Deploy specific versions of Jenkins-plugins via Artifactory-caching

Jenkins can be configured in many ways. When trying to find a suitable solution for deployment of plugins, we’ve been facing to the problem of using not (!) the latest and greatest plugin versions. This can be necessary when using the jobdsl plugin without having the resources to update our own dsl library when there comes up a non-downstream-compatible version of the jobdsl plugin. But this is only one example, there are more 🙂

So that’s why we decided to stick to specific versions. There is a nice option with building up your own Jenkins Update site. Juseppe might by a promising project. In our case we already run an Artifactory instance and don’t want to maintain the jenkins-plugins in a system like Juseppe and Artifactory at the same time.

Environment:

  • Jenkins: 2.46.1, running at http://localhost:8080/jenkins
  • Artifactory: 5.2.0-OSS, running at http://localhost:8081/artifactory

Note: Jenkins is getting started in this scenario via :


java -DJENKINS_HOME=/data/jenkins/ -jar jenkins.war --prefix=/jenkins

First of all I added a remote repo in Artifactory where the Jenkins plugins will be cached and mirrored automatically from the official Jenkins repository. That makes it much faster instead of downloading it every time from remote:

Next part: The script that simply fetches the desired Jenkins-plugins via Artifactory, pushes them directly to Jenkins and finally restarts Jenkins:


#!/bin/bash

ARTIFACTORY_BASE_URL="http://localhost:8081/artifactory"
ARTIFACTORY_PLUGIN_REPO="jenkins-plugins"
LOCAL_PLUGIN_DIR="./plugin-cache"

JENKINS_BASE_URL="http://localhost:8080/jenkins"
JENKINS_UPLOAD_PATH="pluginManager/uploadPlugin"
JENKINS_USERNAME="admin"
JENKINS_APIKEY="691d453b8201a56f455b23bfd7c8d912"
JENKINS_CRUMBPATH="crumbIssuer/api/xml"
JENKINS_RESTART_PATH="safeRestart"

rm -rf $LOCAL_PLUGIN_DIR
mkdir $LOCAL_PLUGIN_DIR

# getting the crumb for curl-post-communication
JENKINS_CRUMB=$(curl --user ${JENKINS_USERNAME}:${JENKINS_APIKEY} ${JENKINS_BASE_URL}/${JENKINS_CRUMBPATH}?xpath=concat\(//crumbRequestField,%22:%22,//crumb\))

while read PLUGIN_LINK; do
PLUGIN_FILE=$(echo $PLUGIN_LINK | rev | cut -d "/" -f1 | rev)
PLUGIN_FULL_LINK="${ARTIFACTORY_BASE_URL}/${ARTIFACTORY_PLUGIN_REPO}/${PLUGIN_LINK}"

printf "fetching ${LOCAL_PLUGIN_DIR}/${PLUGIN_FILE} from Artifactory (${PLUGIN_FULL_LINK}) \n"
printf "================================================================================================== \n"
wget -O $LOCAL_PLUGIN_DIR/$PLUGIN_FILE $PLUGIN_FULL_LINK

printf "pushing ${LOCAL_PLUGIN_DIR}/${PLUGIN_FILE} to Jenkins (${JENKINS_BASE_URL}/${JENKINS_UPLOAD_PATH}) \n"
printf "================================================================================================== \n"
curl --header "$JENKINS_CRUMB" -kv $JENKINS_BASE_URL/$JENKINS_UPLOAD_PATH -u $JENKINS_USERNAME:$JENKINS_APIKEY -F file=@$LOCAL_PLUGIN_DIR/$PLUGIN_FILE
done <pluginlist.txt

# finally restart the jenkins to load all plugins
printf "restarting Jenkins via ${JENKINS_BASE_URL}/${JENKINS_RESTART_PATH} \n"
curl --header "$JENKINS_CRUMB" -X POST $JENKINS_BASE_URL/$JENKINS_RESTART_PATH -u $JENKINS_USERNAME:$JENKINS_APIKEY

As you can see this script relies on a „pluginlist.txt“. This is the only part where we have to make (revision-safe) changes about what will be installed on Jenkins 🙂


org/jvnet/hudson/plugins/chucknorris/0.5/chucknorris-0.5.hpi
org/jenkins-ci/plugins/cmakebuilder/2.3.3/cmakebuilder-2.3.3.hpi

And that’s the result:

The Jenkins-Plugin-Manager shows the two outdated plugins that have been successfully installed and cached in Artifactory: