blob: 4ea9cf52b68401f41dff349de2b9486ec3a99af8 [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
Jean-Louis Boudartad0ff9c2016-08-22 09:00:30 +020065 if [ -z "$JENKINS_UC_DOWNLOAD" ]; then
66 JENKINS_UC_DOWNLOAD=$JENKINS_UC/download
67 fi
68
69 url="$JENKINS_UC_DOWNLOAD/plugins/$plugin/$version/${plugin}.hpi"
apotterebbd13d02016-06-23 12:24:15 -040070
Carlos Sanchezc0f63792016-08-15 10:30:16 +020071 echo "Downloading plugin: $plugin from $url"
72 curl --connect-timeout 5 --retry 5 --retry-delay 0 --retry-max-time 60 -s -f -L "$url" -o "$jpi"
73 return $?
apotterebbd13d02016-06-23 12:24:15 -040074}
75
76function checkIntegrity() {
Carlos Sanchezc0f63792016-08-15 10:30:16 +020077 local plugin jpi
78 plugin="$1"
79 jpi="$(getArchiveFilename "$plugin")"
apotterebbd13d02016-06-23 12:24:15 -040080
Carlos Sanchezc0f63792016-08-15 10:30:16 +020081 zip -T "$jpi" >/dev/null
82 return $?
apotterebbd13d02016-06-23 12:24:15 -040083}
84
Fredrik Kers96ceb542016-08-13 00:02:02 +020085function resolveDependencies() {
Carlos Sanchezc0f63792016-08-15 10:30:16 +020086 local plugin jpi dependencies
87 plugin="$1"
88 jpi="$(getArchiveFilename "$plugin")"
Nicolas De Loof0ef5a622016-05-27 19:14:29 +020089
Carlos Sanchezc0f63792016-08-15 10:30:16 +020090 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 +020091
Carlos Sanchezc0f63792016-08-15 10:30:16 +020092 if [[ ! $dependencies ]]; then
93 echo " > $plugin has no dependencies"
94 return
95 fi
Nicolas De Loof0ef5a622016-05-27 19:14:29 +020096
Carlos Sanchezc0f63792016-08-15 10:30:16 +020097 echo " > $plugin depends on $dependencies"
Nicolas De Loof0ef5a622016-05-27 19:14:29 +020098
Carlos Sanchezc0f63792016-08-15 10:30:16 +020099 IFS=',' read -a array <<< "$dependencies"
apotterebbd13d02016-06-23 12:24:15 -0400100
Carlos Sanchezc0f63792016-08-15 10:30:16 +0200101 for d in "${array[@]}"
102 do
103 plugin="$(cut -d':' -f1 - <<< "$d")"
104 if [[ $d == *"resolution:=optional"* ]]; then
105 echo "Skipping optional dependency $plugin"
106 else
107 local pluginInstalled
108 if pluginInstalled="$(echo "${bundledPlugins}" | grep "^${plugin}:")"; then
109 pluginInstalled="${pluginInstalled//[$'\r']}"
110 local versionInstalled; versionInstalled=$(versionFromPlugin "${pluginInstalled}")
Carlos Sanchez119703c2016-08-15 10:59:54 +0200111 local minVersion; minVersion=$(versionFromPlugin "${d}")
112 if versionLT "${versionInstalled}" "${minVersion}"; then
113 echo "Upgrading bundled dependency $d ($minVersion > $versionInstalled)"
114 download "$plugin" &
Carlos Sanchezc0f63792016-08-15 10:30:16 +0200115 else
Carlos Sanchez119703c2016-08-15 10:59:54 +0200116 echo "Skipping already bundled dependency $d ($minVersion <= $versionInstalled)"
Carlos Sanchezc0f63792016-08-15 10:30:16 +0200117 fi
118 else
Carlos Sanchez119703c2016-08-15 10:59:54 +0200119 download "$plugin" &
Carlos Sanchezc0f63792016-08-15 10:30:16 +0200120 fi
121 fi
122 done
123 wait
Nicolas De Loof0ef5a622016-05-27 19:14:29 +0200124}
125
Carlos Sancheze1b99f42016-07-06 14:22:39 +0200126function bundledPlugins() {
Carlos Sanchezc0f63792016-08-15 10:30:16 +0200127 local JENKINS_WAR=/usr/share/jenkins/jenkins.war
128 if [ -f $JENKINS_WAR ]
129 then
130 TEMP_PLUGIN_DIR=/tmp/plugintemp.$$
131 for i in $(jar tf $JENKINS_WAR | egrep '[^detached-]plugins.*\..pi' | sort)
132 do
133 rm -fr $TEMP_PLUGIN_DIR
134 mkdir -p $TEMP_PLUGIN_DIR
135 PLUGIN=$(basename "$i"|cut -f1 -d'.')
136 (cd $TEMP_PLUGIN_DIR;jar xf "$JENKINS_WAR" "$i";jar xvf "$TEMP_PLUGIN_DIR/$i" META-INF/MANIFEST.MF >/dev/null 2>&1)
137 VER=$(egrep -i Plugin-Version "$TEMP_PLUGIN_DIR/META-INF/MANIFEST.MF"|cut -d: -f2|sed 's/ //')
138 echo "$PLUGIN:$VER"
139 done
140 rm -fr $TEMP_PLUGIN_DIR
141 else
142 rm -f "$TEMP_ALREADY_INSTALLED"
143 echo "ERROR file not found: $JENKINS_WAR"
144 exit 1
145 fi
Carlos Sancheze1b99f42016-07-06 14:22:39 +0200146}
147
148function versionFromPlugin() {
Carlos Sanchezc0f63792016-08-15 10:30:16 +0200149 local plugin=$1
150 if [[ $plugin =~ .*:.* ]]; then
151 echo "${plugin##*:}"
152 else
153 echo "latest"
154 fi
Carlos Sancheze1b99f42016-07-06 14:22:39 +0200155
156}
157
Carlos Sanchezb5ae0c52016-08-15 11:38:24 +0200158function installedPlugins() {
159 for f in "$REF_DIR"/*.jpi; do
160 echo "$(basename "$f" | sed -e 's/\.jpi//'):$(get_plugin_version "$f")"
161 done
162}
163
apotterebbd13d02016-06-23 12:24:15 -0400164main() {
Carlos Sanchezc0f63792016-08-15 10:30:16 +0200165 local plugin version
Sýlvan Heuserb20f3882016-06-01 15:47:38 +0200166
Carlos Sanchezc0f63792016-08-15 10:30:16 +0200167 mkdir -p "$REF_DIR" || exit 1
Nicolas De Loofa7a34c32016-05-30 09:10:58 +0200168
Carlos Sanchezc0f63792016-08-15 10:30:16 +0200169 # Create lockfile manually before first run to make sure any explicit version set is used.
170 echo "Creating initial locks..."
171 for plugin in "$@"; do
172 mkdir "$(getLockFile "${plugin%%:*}")"
173 done
apotterebbd13d02016-06-23 12:24:15 -0400174
Carlos Sanchezc0f63792016-08-15 10:30:16 +0200175 echo -e "\nAnalyzing war..."
176 bundledPlugins="$(bundledPlugins)"
Carlos Sancheze1b99f42016-07-06 14:22:39 +0200177
Carlos Sanchezc0f63792016-08-15 10:30:16 +0200178 echo -e "\nDownloading plugins..."
179 for plugin in "$@"; do
180 version=""
apotterebbd13d02016-06-23 12:24:15 -0400181
Carlos Sanchezc0f63792016-08-15 10:30:16 +0200182 if [[ $plugin =~ .*:.* ]]; then
183 version=$(versionFromPlugin "${plugin}")
184 plugin="${plugin%%:*}"
185 fi
apotterebbd13d02016-06-23 12:24:15 -0400186
Carlos Sanchezc0f63792016-08-15 10:30:16 +0200187 download "$plugin" "$version" "true" &
188 done
189 wait
apotterebbd13d02016-06-23 12:24:15 -0400190
Carlos Sanchezb5ae0c52016-08-15 11:38:24 +0200191 echo
192 echo "WAR bundled plugins:"
193 echo "${bundledPlugins}"
194 echo
195 echo "Installed plugins:"
196 installedPlugins
197
Carlos Sanchezc0f63792016-08-15 10:30:16 +0200198 if [[ -f $FAILED ]]; then
199 echo -e "\nSome plugins failed to download!\n$(<"$FAILED")" >&2
200 exit 1
201 fi
apotterebbd13d02016-06-23 12:24:15 -0400202
Carlos Sanchezc0f63792016-08-15 10:30:16 +0200203 echo -e "\nCleaning up locks"
204 rm -r "$REF_DIR"/*.lock
apotterebbd13d02016-06-23 12:24:15 -0400205}
206
Brian Antonelli6706b262016-06-24 06:31:54 -0400207main "$@"