Skip to content

How to create your own Jenkins Update Center

ikedam edited this page Aug 31, 2013 · 17 revisions

Keywords

Jenkins, Plugin, Update Center, Alternate

Overview

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:

  1. 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.
  2. Create your certificate.
    1. Create your RSA private key.
    2. Create a CSR, and sign it by your RSA private key.
  3. Generate update-center.json.
    1. Retrieve and compile backend-update-center2.
    2. Run backend-update-center2.
    3. Put generated files to your web server.
  4. Let your Jenkins access to your Update Center
    1. Install [UpdateSites Manager plugin] (https://wiki.jenkins-ci.org/display/JENKINS/UpdateSites+Manager+plugin)
    2. Register you update center.
    3. Click "Check now"
    4. Now you can download your plugins!

Create a directory containing plugins

Overview

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.

Prepare the place to deploy

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).

Configure your plugin project deployment

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>

Test your configuration

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

Deploy your plugin with following command:

mvn release:prepare release:perform

Plugin package files are located in the releases directory.

Create your certificate

Overview

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

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

Create self-signed certificate

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 []:

Generate update-center.json

Overview

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.
  • 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.
  • 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.

Checkout backend-update-center2 and compile

  1. Prepare an environment where JDK and Apache Maven is available.
  2. Checkout https://github.com/ikedam/backend-update-center2
  3. run "mvn compile"

Create update-center.json from your maven repository

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...

Upload files

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/.

Let your Jenkins access to your Update Center

Install UpdateSites Manager plugin

Install [UpdateSites Manager plugin] (https://wiki.jenkins-ci.org/display/JENKINS/UpdateSites+Manager+plugin) from "Manage Jenkins" > "Update Center".

Register you 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".

Have Jenkins check your update center

  1. Log in to your Jenkins with an administrative account.
  2. Open "Manage Jenkins" > "Manage Plugins" > "Advanced".
  3. 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!

Another way: Let your Jenkins access to your Update Center

A way without [UpdateSites Manager plugin] (https://wiki.jenkins-ci.org/display/JENKINS/UpdateSites+Manager+plugin).

Put your certificate

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.

Specify your update center URL

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.

  1. Stop your Jenkins.

  2. Open ${JENKINS_HOME}/hudson.model.UpdateCenter.xml with a text editor.

  3. 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>
    
  4. Start your Jenkins.

Have Jenkins check your update center

See the above same section.

Trouble shootings

Jenkins does not read my update-center.json

  • 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 &#039;your-update-center&#039; 
      java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors
          at sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:195)
      ....
    

NPE when install a plugin

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.