-
Notifications
You must be signed in to change notification settings - Fork 24
How to create your own Jenkins Update Center
Jenkins, Plugin, Update Center, Alternate
In this page, I describe how to create an update center alternative to the official update center. This is useful when:
- You want to distribute a plugin, but not open it (as when you developed a plugin usable only in your team).
- You build a update center in an offline environment to allow Jenkins to install plugins.
You can create Jenkins Update Center in following steps:
- Create a directory containing plugins.
- Deploy your plugin to a local directory.
- Alternately, you can simply put hpi files in a directory. This is easy when you want to create subset of official update center.
- Create your certificate.
- Create your RSA private key.
- Create a CSR, and sign it by your RSA private key.
- Generate update-center.json.
- Retrieve and compile backend-update-center2.
- Run backend-update-center2.
- Put generated files to your web server.
- Let your Jenkins access to your Update Center
- Install [UpdateSites Manager plugin] (https://wiki.jenkins-ci.org/display/JENKINS/UpdateSites+Manager+plugin)
- Register you update center.
- Click "Check now"
- Now you can download your plugins!
What you have to do here is to put hpi files in a directory. Backend-update-center picks up all the hpi files in the directory including files in subdirectories. If you develops plugins to put your update center, it is the best way to set up the directory as a maven repository. If not, it is easy to retrieve hpi files and simply put them into the directory.
In this section, I describe how to create as a maven repository.
You will have to put all files to a web server. Though you can use any web server, I describe the way using GitHub Pages in followings.
Create a new repository in your GitHub account. This is also going to be your Jenkins update center. The URI of your update center becomes http://ACCOUNT.github.com/REPOSITORY/... .
Clone your new repository, and create a new branch "gh-pages". This becomes a place to commit files to release as web pages (For details see https://help.github.com/articles/creating-project-pages-manually).
Define a new property indicating the path to deploy in ~/.m2/settings.xml. For example:
<profiles>
<profile>
<id>default</id>
<properties>
<!--maven variable which points to my Jenkins repository -->
<jenkins.repo.path>file:///C:/Users/ikedam/workspace/jenkins-update-center</jenkins.repo.path>
</properties>
</profile>
</profiles>
Then add following lines to your plugins pom.xml:
<scm>
<connection>scm:git:git://github.com/ACCOUNT/REPOSITORY.git</connection>
<developerConnection>scm:git:[email protected]:ACCOUNT/REPOSITORY.git</developerConnection>
<url>https://github.com/ACCOUNT/REPOSITORY</url>
</scm>
<distributionManagement>
<repository>
<id>jenkins.repo.release</id>
<name>Repository for Releases</name>
<url>${jenkins.repo.path}/releases</url>
</repository>
<snapshotRepository>
<id>jenkins.repo.snapshot</id>
<name>Repository for Snapshots</name>
<url>${jenkins.repo.path}/snapshots</url>
</snapshotRepository>
</distributionManagement>
Run following command:
mvn deploy
It's ok if plugin package files (jar and hpi) are correctly located in the snapshots directory.
Deploy your plugin with following command:
mvn release:prepare release:perform
Plugin package files are located in the releases directory.
To create a update center, you need a private key and its certificate. The private key is to sign update-center.json that contains the information of plugins in your update center, and the certificate is to have your Jenkins to accept that signature.
In following, I describe how to create your private key and self-signed certificate with OpenSSL. Java also provides a tool called keytool to manage private keys and certificates, but it does not provide the way to export a private key in the format to be used with backend-update-center2.
If you already have a private key and its certificate pair, it is preferred to use it. In that case, you can skip the later step to install the certificate to Jenkins (for it is signed by known root CA).
Create your private key file your-update-center.key by running the following command. A private key with no pass phrase is created.
openssl genrsa -out your-update-center.key 1024
With your-update-center.key, create your certificate your-update-center.crt with following command.
openssl req -new -x509 -days 1095 -key your-update-center.key -out your-update-center.crt
It will be requested to input information for the certificate. Jenkins seems not to require anything special to those information (as SSL requires Common Name to be the name of the server), you can input anything here. Here is an example session:
Country Name (2 letter code) [AU]:JP
State or Province Name (full name) [Some-State]:Tokyo
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:My own update center
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:
Email Address []:
You need to put update-center.json in your update center, which is a file containing the list of plugins in your update center. In Jenkins official update center, this file seems to be created with backend-update-center2. For this application is programmed to create update-center.json only for the official update center, I forked it and applied following changes to enable to create update-center.json for any update centers.
- Added the option to specify alternate maven repository.
- Original backend-update-center2 always refer to http://repo.jenkins-ci.org/public/.
- Added the option to pick plugins from a local directory.
- Original backend-update-center2 always refer to a remote maven index generated with Nexus Indexer.
- This customize can go without Nexus Indexer, and without structuring directories.
- Added the option to link directory to the HPI files in the maven repository.
- Original backend-update-center2 always link to http://updates.jenkins-ci.org/download/plugins/(artifactId)/(version)/(artifactId).hpi, that is symbolic link to the HPI file in the maven repository.
- Added the option not to refer [Jenkins Wiki] (https://wiki.jenkins-ci.org/).
- Oritinal backend-update-center2 refers Jenkins Wiki to retrieve information of plugins.
- Prepare an environment where JDK and Apache Maven is available.
- Checkout https://github.com/ikedam/backend-update-center2
- run "mvn compile"
Put your private key and self-signed certificate in the backend-update-center2 directory.
Run following command:
mvn exec:java -Dexec.args="-id your-update-center \
-h /dev/null \
-o update-center.json \
-r release-history.json
-repository http://your-web-server/path-to-your-repository/ \
-hpiDirectory /local/path-to-your-repository \
-nowiki \
-key your-update-center.key \
-certificate your-update-center.crt \
-root-certificate your-update-center.crt \
-pretty
"
Each options are:
Option | Explanation |
---|---|
-id your-update-center | Name of your update center. Used by Jenkins to distinguish sites. Official updater center is "default". This must not contain any period letters("."). |
-h /dev/null | Specify not to generate .htaccess. This works also in Windows. |
-o update-center.json | File to create. update-center.json and update-center.json.html will be created. |
-r release-history.json | File created with update-center.json. This file is not used. |
-repository http://your-web-server/path-to-your-repository/ | URL where your maven repository will be placed |
-hpiDirectory /local/path-to-your-repository | Directory you installed plugins in above steps. |
-nowiki | not to refer to Jenkins Wiki to retrieve plugin information. This is not needed when you are building a subset of official update center. |
-key your-update-center.key | Specify your private key file |
-certificate your-update-center.crt | Specify your certificate file |
-root-certificate your-update-center.crt | If your certificate is self-signed, specify your certificate file also here |
-pretty | Pretty print the json file. It enlarges the size of the json file, but easy to see and check the differences |
Following files are created.
File | Explanation |
---|---|
update-center.json | JSONP file indexing plugins in your update center |
update-center.json.html | HTML file that posts index of plugins as a JavaScript. Jenkins seems use this file, not update-center.json |
release-history.json | A file containing all version of plugins. This file seems not to be used anywhere... |
Commit these files.
- plugin filesdeployed files
- (optional)other deployed files (jar, xml, sha1, md5)
- update-center.json
- update-center.json.html
Push it to GitHub. Now you can access these files in http://ACCOUNT.github.com/REPOSITORY/.
Install [UpdateSites Manager plugin] (https://wiki.jenkins-ci.org/display/JENKINS/UpdateSites+Manager+plugin) from "Manage Jenkins" > "Update Center".
Go to "Manage Jenkins" > "Manage Update Center", and register your update center. Fill fields as following:
Field | Value |
---|---|
Disable this site | Do not check |
ID | The value you specified with -id in backend-update-center2. |
URL | The URL to access update-center.json. |
Note | Fill as you like. This does not affect the behavior. |
Need CA Certificate | Check |
CA Certificate | The contents of your certificate file. Your certificate also can be extracted from update-center.json, which is written in "signature/certificate" field. |
If you use a signed certificate, you do not need to check "Need CA Certificate" and do not need to fill "CA Certificate".
- Log in to your Jenkins with an administrative account.
- Open "Manage Jenkins" > "Manage Plugins" > "Advanced".
- Click "Check now"
If Jenkins successfully access to your update center, following log is output.
2013/02/16 21:04:40 hudson.model.UpdateSite doPostBack
INFO: Obtained the latest update center data file for UpdateSource your-update-center
Now plugins in your update center is available in your Jenkins!
A way without [UpdateSites Manager plugin] (https://wiki.jenkins-ci.org/display/JENKINS/UpdateSites+Manager+plugin).
Put your certificate file in ${JENKINS_HOME}/update-center-rootCAs (you have to create a directory). This takes effect immediately even when Jenkins is running.
This step enables your Jenkins to accept your update-center.json.
Your certificate also can be extracted from update-center.json, which is written in "signature/certificate" field.
You cannot specify your update center in the configuration page. It is because Jenkins treats the update center URL specified in the configuration page as the update center whose id is "default". It causes NPE, for the id of your update center is not really "default".
So you have to configure your Jenkins without the configuration page.
-
Stop your Jenkins.
-
Open ${JENKINS_HOME}/hudson.model.UpdateCenter.xml with a text editor.
-
Update its contens as following:
<?xml version='1.0' encoding='UTF-8'?> <sites> <site> <id>default</id> <url>http://updates.jenkins-ci.org/update-center.json</url> </site> <!-- Add following element --> <site> <id>your-update-center</id> <!-- This must be the value you specified with -id in backend-update-center2 --> <url>http://your-web-server/path-to/update-center.json</url> </site> </sites>
-
Start your Jenkins.
See the above same section.
-
Jenkins accesses not update-center.json, but update-center.json.html. So you need to upload update-center.json.html too.
-
Jenkins itself does not access to update-center.json.html, but your browser access it and pass it to Jenkins. So cleaning caches in your browser makes Jenkins read the newest update-center.json.
-
When Jenkins does not accept the signature, following exception will be logged. This indicates that you failed to install your certificate into your Jenkins.
2013/02/16 22:08:32 hudson.model.UpdateSite doPostBack FATAL: Signature verification failed in update site 'your-update-center' java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors at sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:195) ....
Following exception is reported:
javax.servlet.ServletException: java.lang.NullPointerException
at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:615)
at org.kohsuke.stapler.Stapler.invoke(Stapler.java:658)
....
Caused by: java.lang.NullPointerException
at hudson.PluginManager.doInstall(PluginManager.java:664)
This happens in following cases:
- When the value of id in hudson.model.UpdateCenter.xml and the value specified in backend-update-center2 differ.
- When the value of id in hudson.model.UpdateCenter.xml contains a period letter.