Goal: Create a new library and tools to unify plugin management across the Jenkins ecosystem
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.
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.
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.
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.
I also presented my Phase 3 work at a Jenkins Online Meetup (slides).
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 comptability (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.