Plugin Installation Manager CLI Tool / Library

Goal: Create a new library and tools to unify plugin management across the Jenkins ecosystem

Status: Completed

Team

Details

There are currently many reincarnations of plugin management across Jenkins, including:

The goal of this project is to create a new Plugin Manager CLI tool and a library which would unify the plugin management across different Jenkins implementations and improve plugin tooling. Although we looked at extracting plugin management from Jenkins Core into its own module, this proved to be a challenging first step (see JENKINS-57672).

The input to the the tool is a list of plugins, either specified via the --plugins CLI option, or using the --plugin-file option with a .txt or yaml file. The library finds all recursive dependencies for each requested plugin, replacing every duplicate plugin with the highest required version of that plugin. The direct plugin dependencies first try to be resolved using the update center metadata. If that fails, they are determined by downloading the plugin to a temporary file and parsing the MANIFEST.MF file. The final set of the plugins to be downloaded is found, taking into account any currently installed or bundled plugins, which are ignored. The plugins are then downloaded and can be used when Jenkins starts.

Below is an example of how the tool can be used with Docker.

Plugin Tool Input
Dockerfile
Plugin Download Details
Plugin Installed in Jenkins

Phase 1

Phase 1 focused on extracting the docker install-plugins bash script to Java. The first alpha version of the library and CLI tool was released. It implemented basic functionality of the install-plugins.sh script to take in plugins and download them to a user-specified directory.

The alpha release was announced in the following blog post and a live demo can be seen in the Phase 1 evaluation recording (slides).

Phase 2

Phase 2 focused on improving upon what was written in Phase 1, with particular focus on making parsing more robust, adding better Docker compatibility, and creating new CLI options that will make the plugin installation process more transparent. Parsing was improved to filter out comments and blank lines, and accept a yaml file listing plugins to install as input. Instead of hard coding the update centers, options were added to allow update centers to be set via environment variables or CLI options. Windows compatible defaults for locations to find an existing Jenkins war file and setting the plugin directory were also added. To make the plugin installation process more transparent, options were added to view the list of plugins that would be installed prior to installation, and view if any of these plugins had available updates or security warnings. This last step involved re-writing some of the plugin download and dependency resolution logic so that all plugins and their recursive dependencies are resolved before the time of download.

The blog post announcing the new features can be found here and the demo for this coding phase can be found here (slides)

Phase 3

Most of this phase was dedicated to cleaning up and testing the work done in Phase 1 and 2. Some fixes and optimizations included in this coding phase include throwing an exception sooner if there are problems downloading a plugin or resolving its dependencies, throwing an exception if the required Jenkins version listed for any of the plugins to be installed is lower than the version of the Jenkins war file, and improving plugin download times through a custom IO thread pool and using http HEAD instead of http GET where appropriate.

I was also able to attend DevOps World and present the work I’ve done on this project both during the Continuous Delivery Contributor Summit and for the Jenkins Community Demos.

DevOps World Demo

Here are the slides from my presentation. I detailed my time at DevOps World here.

I also presented my Phase 3 work at a Jenkins Online Meetup (slides).

Future Directions

The project is very close to its first official release. After the first release, the goal is to incorporate it into the official Jenkins Docker Image, the Custom War Packager, and to inject the library into Jenkins to install plugins before the Configuration as Code plugin runs. Other requested features include maven compatibility (JENKINS-58217: supporting maven as an installation source and JENKINS-59066: sharing a plugin cache with ~/.m2/repository). See Jira to see and create additional requests. To get the most up-to-date changes outside of the release cycle, you can also download the incrementals binaries.

Links