The problem with such setups is simple: You usually do it manually which in consequence is error-prone. If you are doing that more than once, it becomes cumbersome and you are asking yourself: Isn’t there a simpler solution to make that setup more reproducible?
Fortunately there is a solution for that problem.
The Nexus Repository Manager starting with version 3+ provides a Provisioning REST API which allows to upload scripts to Nexus and execute those scripts which makes it possible to do such kind of setup in a scripted manner.
So now we have taken the first barrier. The next one is in front. How to test such setups?
This can be started by using the following command:
Afterwards you can use the example scripts for provisioning as a starting point.
There is a two step way to get something configured in Nexus. First upload the
script and afterwards run it. This can either been done
curl manually on command line or you can use the
in example scripting setup which is much more convenient.
The above example project contains basic examples for different types of setup tasks to do. So the easiest way to start is by cloning the repository and change it based on your own requirements. I started with creating a separate repository for keeping my scripts and changes. By the way you should use an IDE to write the groovy scripts (IDEA IntelliJ for example). This makes implementing scripts easier, cause you get code completion etc.
So now let’s start with a real example. A script which will create a repository (I have chosen to create a Maven repository) could look like this:
1 2 3 4 5 6 7 8 9 10 11 12
This will create a Maven repository named
test-maven-repository which is
configured as a release repository. That means you are not allowed to upload an
artifact a second time which is the default for release repositories
VersionPolicy.RELEASE) in Maven. That’s valid for repository managers, too.
Furthermore it will use the
true represents the value for the
So now if you have run a script on a running Nexus repository manager instance inside a Docker container, you can check the configuration by looking into the UI of Nexus and see if everything is like you expected it to be. If you find something which is not the way as expected, you simply stop the docker container, fix your script accordingly and start your container and run the script again.
Wait a minute? Running over and over again? Manually checking? Wasn’t that the subject at the beginning of this article? Make it reproducible?
So there is a better way to do. Just simply write tests for those things. This means just pick up a testing framework which supports a kind of web testing. I have decided to use Cypress which was easy to setup (unfortunately I had to register via Github. Why?) and with some kind of searching for JQuery issues I had, it took me about two or three hours to have a very good starting point.
So let’s take a look how such a script looks like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
I have to admit there had been some challenges to get things working, cause it seemed to me that the informations on the result pages of Nexus aren’t intended for testing, cause they contain generated numbers etc. and unfortunately no unique identifiers for particular parts of the output. For example an id for a list of repositories. That made the writing of the testing a bit hard and verbose. For example the following snippet is to extract the information for a single line from the list of repositories:
1 2 3 4 5 6 7 8 9 10
So there is no human readable unique id in the
table, something like
<table id="repository-list"... Only by using the above
data-recordid it was
possible to find the correct entries which means you have to know the name of
the repositories beforehand. This means if you need to check a list of
repositories you have to repeat the above code snippet several times.
So improving the output in a way to add better unique id’s in a more human oriented way would make it much easier to get things done based on the idea of infrastructure as code.
In the end the provisioning API seemed to be not completed yet. So for example a configuration for LDAP is a lot more complex than I thought. But may be I have missed something. The current implementation (as far as it goes) is very simple to use and makes it easy to write such setup scripts which is a great thing.