blob: 8b8daeef87fec68a50a39e6b2ba0779ea316defe [file] [log] [blame]
Carlos Sanchez7d165ac2016-08-14 11:13:12 +02001#!/bin/bash -eu
Nicolas De Loof0ef5a622016-05-27 19:14:29 +02002
Sýlvan Heuserb20f3882016-06-01 15:47:38 +02003# Resolve dependencies and download plugins given on the command line
4#
5# FROM jenkins
6# RUN install-plugins.sh docker-slaves github-branch-source
7
Carlos Sanchez3a83b9d2016-08-08 09:36:28 +02008set -o pipefail
9
apotterebbd13d02016-06-23 12:24:15 -040010REF_DIR=${REF:-/usr/share/jenkins/ref/plugins}
11FAILED="$REF_DIR/failed-plugins.txt"
Sýlvan Heuserb20f3882016-06-01 15:47:38 +020012
Vincent Latombec14af952016-07-18 10:20:12 +020013. /usr/local/bin/jenkins-support
14
apotterebbd13d02016-06-23 12:24:15 -040015function getLockFile() {
Carlos Sanchezc0f63792016-08-15 10:30:16 +020016 echo -n "$REF_DIR/${1}.lock"
apotterebbd13d02016-06-23 12:24:15 -040017}
18
Carlos Sanchez16ae24e2016-06-27 13:47:09 +020019function getArchiveFilename() {
Carlos Sanchezc0f63792016-08-15 10:30:16 +020020 echo -n "$REF_DIR/${1}.jpi"
apotterebbd13d02016-06-23 12:24:15 -040021}
Sýlvan Heuserb20f3882016-06-01 15:47:38 +020022
Nicolas De Loof0ef5a622016-05-27 19:14:29 +020023function download() {
Carlos Sanchezc0f63792016-08-15 10:30:16 +020024 local plugin originalPlugin version lock ignoreLockFile
25 plugin="$1"
26 version="${2:-latest}"
27 ignoreLockFile="${3:-}"
28 lock="$(getLockFile "$plugin")"
Nicolas De Loof0ef5a622016-05-27 19:14:29 +020029
Carlos Sanchezc0f63792016-08-15 10:30:16 +020030 if [[ $ignoreLockFile ]] || mkdir "$lock" &>/dev/null; then
31 if ! doDownload "$plugin" "$version"; then
32 # some plugin don't follow the rules about artifact ID
33 # typically: docker-plugin
34 originalPlugin="$plugin"
35 plugin="${plugin}-plugin"
36 if ! doDownload "$plugin" "$version"; then
37 echo "Failed to download plugin: $originalPlugin or $plugin" >&2
38 echo "Not downloaded: ${originalPlugin}" >> "$FAILED"
39 return 1
40 fi
41 fi
Nicolas De Loofa7a34c32016-05-30 09:10:58 +020042
Carlos Sanchezc0f63792016-08-15 10:30:16 +020043 if ! checkIntegrity "$plugin"; then
44 echo "Downloaded file is not a valid ZIP: $(getArchiveFilename "$plugin")" >&2
45 echo "Download integrity: ${plugin}" >> "$FAILED"
46 return 1
47 fi
apotterebbd13d02016-06-23 12:24:15 -040048
Carlos Sanchezc0f63792016-08-15 10:30:16 +020049 resolveDependencies "$plugin"
50 fi
Nicolas De Loof0ef5a622016-05-27 19:14:29 +020051}
52
apotterebbd13d02016-06-23 12:24:15 -040053function doDownload() {
Carlos Sanchezc0f63792016-08-15 10:30:16 +020054 local plugin version url jpi
55 plugin="$1"
56 version="$2"
57 jpi="$(getArchiveFilename "$plugin")"
apotterebbd13d02016-06-23 12:24:15 -040058
Carlos Sanchezc0f63792016-08-15 10:30:16 +020059 # If plugin already exists and is the same version do not download
60 if test -f "$jpi" && unzip -p "$jpi" META-INF/MANIFEST.MF | tr -d '\r' | grep "^Plugin-Version: ${version}$" > /dev/null; then
61 echo "Using provided plugin: $plugin"
62 return 0
63 fi
apotterebbd13d02016-06-23 12:24:15 -040064
Carlos Sanchez0d167af2016-08-29 11:02:57 +020065 JENKINS_UC_DOWNLOAD=${JENKINS_UC_DOWNLOAD:-"$JENKINS_UC/download"}
Jean-Louis Boudartad0ff9c2016-08-22 09:00:30 +020066
67 url="$JENKINS_UC_DOWNLOAD/plugins/$plugin/$version/${plugin}.hpi"
apotterebbd13d02016-06-23 12:24:15 -040068
Carlos Sanchezc0f63792016-08-15 10:30:16 +020069 echo "Downloading plugin: $plugin from $url"
70 curl --connect-timeout 5 --retry 5 --retry-delay 0 --retry-max-time 60 -s -f -L "$url" -o "$jpi"
71 return $?
apotterebbd13d02016-06-23 12:24:15 -040072}
73
74function checkIntegrity() {
Carlos Sanchezc0f63792016-08-15 10:30:16 +020075 local plugin jpi
76 plugin="$1"
77 jpi="$(getArchiveFilename "$plugin")"
apotterebbd13d02016-06-23 12:24:15 -040078
Carlos Sanchezc0f63792016-08-15 10:30:16 +020079 zip -T "$jpi" >/dev/null
80 return $?
apotterebbd13d02016-06-23 12:24:15 -040081}
82
Fredrik Kers96ceb542016-08-13 00:02:02 +020083function resolveDependencies() {
Carlos Sanchezc0f63792016-08-15 10:30:16 +020084 local plugin jpi dependencies
85 plugin="$1"
86 jpi="$(getArchiveFilename "$plugin")"
Nicolas De Loof0ef5a622016-05-27 19:14:29 +020087
Carlos Sanchezc0f63792016-08-15 10:30:16 +020088 dependencies="$(unzip -p "$jpi" META-INF/MANIFEST.MF | tr -d '\r' | tr '\n' '|' | sed -e 's#| ##g' | tr '|' '\n' | grep "^Plugin-Dependencies: " | sed -e 's#^Plugin-Dependencies: ##')"
Nicolas De Loof0ef5a622016-05-27 19:14:29 +020089
Carlos Sanchezc0f63792016-08-15 10:30:16 +020090 if [[ ! $dependencies ]]; then
91 echo " > $plugin has no dependencies"
92 return
93 fi
Nicolas De Loof0ef5a622016-05-27 19:14:29 +020094
Carlos Sanchezc0f63792016-08-15 10:30:16 +020095 echo " > $plugin depends on $dependencies"
Nicolas De Loof0ef5a622016-05-27 19:14:29 +020096
Carlos Sanchezc0f63792016-08-15 10:30:16 +020097 IFS=',' read -a array <<< "$dependencies"
apotterebbd13d02016-06-23 12:24:15 -040098
Carlos Sanchezc0f63792016-08-15 10:30:16 +020099 for d in "${array[@]}"
100 do
101 plugin="$(cut -d':' -f1 - <<< "$d")"
102 if [[ $d == *"resolution:=optional"* ]]; then
103 echo "Skipping optional dependency $plugin"
104 else
105 local pluginInstalled
106 if pluginInstalled="$(echo "${bundledPlugins}" | grep "^${plugin}:")"; then
107 pluginInstalled="${pluginInstalled//[$'\r']}"
108 local versionInstalled; versionInstalled=$(versionFromPlugin "${pluginInstalled}")
Carlos Sanchez119703c2016-08-15 10:59:54 +0200109 local minVersion; minVersion=$(versionFromPlugin "${d}")
110 if versionLT "${versionInstalled}" "${minVersion}"; then
111 echo "Upgrading bundled dependency $d ($minVersion > $versionInstalled)"
112 download "$plugin" &
Carlos Sanchezc0f63792016-08-15 10:30:16 +0200113 else
Carlos Sanchez119703c2016-08-15 10:59:54 +0200114 echo "Skipping already bundled dependency $d ($minVersion <= $versionInstalled)"
Carlos Sanchezc0f63792016-08-15 10:30:16 +0200115 fi
116 else
Carlos Sanchez119703c2016-08-15 10:59:54 +0200117 download "$plugin" &
Carlos Sanchezc0f63792016-08-15 10:30:16 +0200118 fi
119 fi
120 done
121 wait
Nicolas De Loof0ef5a622016-05-27 19:14:29 +0200122}
123
Carlos Sancheze1b99f42016-07-06 14:22:39 +0200124function bundledPlugins() {
Carlos Sanchezc0f63792016-08-15 10:30:16 +0200125 local JENKINS_WAR=/usr/share/jenkins/jenkins.war
126 if [ -f $JENKINS_WAR ]
127 then
128 TEMP_PLUGIN_DIR=/tmp/plugintemp.$$
129 for i in $(jar tf $JENKINS_WAR | egrep '[^detached-]plugins.*\..pi' | sort)
130 do
131 rm -fr $TEMP_PLUGIN_DIR
132 mkdir -p $TEMP_PLUGIN_DIR
133 PLUGIN=$(basename "$i"|cut -f1 -d'.')
134 (cd $TEMP_PLUGIN_DIR;jar xf "$JENKINS_WAR" "$i";jar xvf "$TEMP_PLUGIN_DIR/$i" META-INF/MANIFEST.MF >/dev/null 2>&1)
135 VER=$(egrep -i Plugin-Version "$TEMP_PLUGIN_DIR/META-INF/MANIFEST.MF"|cut -d: -f2|sed 's/ //')
136 echo "$PLUGIN:$VER"
137 done
138 rm -fr $TEMP_PLUGIN_DIR
139 else
140 rm -f "$TEMP_ALREADY_INSTALLED"
141 echo "ERROR file not found: $JENKINS_WAR"
142 exit 1
143 fi
Carlos Sancheze1b99f42016-07-06 14:22:39 +0200144}
145
146function versionFromPlugin() {
Carlos Sanchezc0f63792016-08-15 10:30:16 +0200147 local plugin=$1
148 if [[ $plugin =~ .*:.* ]]; then
149 echo "${plugin##*:}"
150 else
151 echo "latest"
152 fi
Carlos Sancheze1b99f42016-07-06 14:22:39 +0200153
154}
155
Carlos Sanchezb5ae0c52016-08-15 11:38:24 +0200156function installedPlugins() {
157 for f in "$REF_DIR"/*.jpi; do
158 echo "$(basename "$f" | sed -e 's/\.jpi//'):$(get_plugin_version "$f")"
159 done
160}
161
apotterebbd13d02016-06-23 12:24:15 -0400162main() {
Carlos Sanchezc0f63792016-08-15 10:30:16 +0200163 local plugin version
Sýlvan Heuserb20f3882016-06-01 15:47:38 +0200164
Carlos Sanchezc0f63792016-08-15 10:30:16 +0200165 mkdir -p "$REF_DIR" || exit 1
Nicolas De Loofa7a34c32016-05-30 09:10:58 +0200166
Carlos Sanchezc0f63792016-08-15 10:30:16 +0200167 # Create lockfile manually before first run to make sure any explicit version set is used.
168 echo "Creating initial locks..."
169 for plugin in "$@"; do
170 mkdir "$(getLockFile "${plugin%%:*}")"
171 done
apotterebbd13d02016-06-23 12:24:15 -0400172
Carlos Sanchezc0f63792016-08-15 10:30:16 +0200173 echo -e "\nAnalyzing war..."
174 bundledPlugins="$(bundledPlugins)"
Carlos Sancheze1b99f42016-07-06 14:22:39 +0200175
Carlos Sanchezc0f63792016-08-15 10:30:16 +0200176 echo -e "\nDownloading plugins..."
177 for plugin in "$@"; do
178 version=""
apotterebbd13d02016-06-23 12:24:15 -0400179
Carlos Sanchezc0f63792016-08-15 10:30:16 +0200180 if [[ $plugin =~ .*:.* ]]; then
181 version=$(versionFromPlugin "${plugin}")
182 plugin="${plugin%%:*}"
183 fi
apotterebbd13d02016-06-23 12:24:15 -0400184
Carlos Sanchezc0f63792016-08-15 10:30:16 +0200185 download "$plugin" "$version" "true" &
186 done
187 wait
apotterebbd13d02016-06-23 12:24:15 -0400188
Carlos Sanchezb5ae0c52016-08-15 11:38:24 +0200189 echo
190 echo "WAR bundled plugins:"
191 echo "${bundledPlugins}"
192 echo
193 echo "Installed plugins:"
194 installedPlugins
195
Carlos Sanchezc0f63792016-08-15 10:30:16 +0200196 if [[ -f $FAILED ]]; then
197 echo -e "\nSome plugins failed to download!\n$(<"$FAILED")" >&2
198 exit 1
199 fi
apotterebbd13d02016-06-23 12:24:15 -0400200
Carlos Sanchezc0f63792016-08-15 10:30:16 +0200201 echo -e "\nCleaning up locks"
202 rm -r "$REF_DIR"/*.lock
apotterebbd13d02016-06-23 12:24:15 -0400203}
204
Brian Antonelli6706b262016-06-24 06:31:54 -0400205main "$@"