blob: a04dfb28f1a0812ac18d03eda6c640b8675f6edc [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() {
16 echo -n "$REF_DIR/${1}.lock"
17}
18
Carlos Sanchez16ae24e2016-06-27 13:47:09 +020019function getArchiveFilename() {
20 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() {
apotterebbd13d02016-06-23 12:24:15 -040024 local plugin originalPlugin version lock ignoreLockFile
25 plugin="$1"
26 version="${2:-latest}"
Carlos Sanchez7d165ac2016-08-14 11:13:12 +020027 ignoreLockFile="${3:-}"
apotterebbd13d02016-06-23 12:24:15 -040028 lock="$(getLockFile "$plugin")"
Nicolas De Loof0ef5a622016-05-27 19:14:29 +020029
apotterebbd13d02016-06-23 12:24:15 -040030 if [[ $ignoreLockFile ]] || mkdir "$lock" &>/dev/null; then
31 if ! doDownload "$plugin" "$version"; then
Nicolas De Loof4675f042016-06-01 14:07:33 +020032 # some plugin don't follow the rules about artifact ID
33 # typically: docker-plugin
apotterebbd13d02016-06-23 12:24:15 -040034 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
Nicolas De Loof4675f042016-06-01 14:07:33 +020040 fi
Nicolas De Loof0ef5a622016-05-27 19:14:29 +020041 fi
Nicolas De Loofa7a34c32016-05-30 09:10:58 +020042
apotterebbd13d02016-06-23 12:24:15 -040043 if ! checkIntegrity "$plugin"; then
Carlos Sanchez16ae24e2016-06-27 13:47:09 +020044 echo "Downloaded file is not a valid ZIP: $(getArchiveFilename "$plugin")" >&2
apotterebbd13d02016-06-23 12:24:15 -040045 echo "Download integrity: ${plugin}" >> "$FAILED"
46 return 1
47 fi
48
Sýlvan Heuser62421ca2016-06-01 15:52:33 +020049 resolveDependencies "$plugin"
Nicolas De Loofa7a34c32016-05-30 09:10:58 +020050 fi
Nicolas De Loof0ef5a622016-05-27 19:14:29 +020051}
52
apotterebbd13d02016-06-23 12:24:15 -040053function doDownload() {
Carlos Sanchez16ae24e2016-06-27 13:47:09 +020054 local plugin version url jpi
apotterebbd13d02016-06-23 12:24:15 -040055 plugin="$1"
56 version="$2"
Carlos Sanchez16ae24e2016-06-27 13:47:09 +020057 jpi="$(getArchiveFilename "$plugin")"
apotterebbd13d02016-06-23 12:24:15 -040058
Carlos Sanchez3a83b9d2016-08-08 09:36:28 +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
apotterebbd13d02016-06-23 12:24:15 -040061 echo "Using provided plugin: $plugin"
62 return 0
63 fi
64
65 url="$JENKINS_UC/download/plugins/$plugin/$version/${plugin}.hpi"
66
67 echo "Downloading plugin: $plugin from $url"
Carlos Sanchezd76ab2e2016-06-27 23:40:22 +020068 curl --connect-timeout 5 --retry 5 --retry-delay 0 --retry-max-time 60 -s -f -L "$url" -o "$jpi"
apotterebbd13d02016-06-23 12:24:15 -040069 return $?
70}
71
72function checkIntegrity() {
Carlos Sanchez16ae24e2016-06-27 13:47:09 +020073 local plugin jpi
apotterebbd13d02016-06-23 12:24:15 -040074 plugin="$1"
Carlos Sanchez16ae24e2016-06-27 13:47:09 +020075 jpi="$(getArchiveFilename "$plugin")"
apotterebbd13d02016-06-23 12:24:15 -040076
Carlos Sanchez16ae24e2016-06-27 13:47:09 +020077 zip -T "$jpi" >/dev/null
apotterebbd13d02016-06-23 12:24:15 -040078 return $?
79}
80
Fredrik Kers96ceb542016-08-13 00:02:02 +020081function resolveDependencies() {
Carlos Sanchez16ae24e2016-06-27 13:47:09 +020082 local plugin jpi dependencies
apotterebbd13d02016-06-23 12:24:15 -040083 plugin="$1"
Carlos Sanchez16ae24e2016-06-27 13:47:09 +020084 jpi="$(getArchiveFilename "$plugin")"
Nicolas De Loof0ef5a622016-05-27 19:14:29 +020085
Fredrik Kers96ceb542016-08-13 00:02:02 +020086 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 +020087
apotterebbd13d02016-06-23 12:24:15 -040088 if [[ ! $dependencies ]]; then
89 echo " > $plugin has no dependencies"
Nicolas De Loof0ef5a622016-05-27 19:14:29 +020090 return
91 fi
92
apotterebbd13d02016-06-23 12:24:15 -040093 echo " > $plugin depends on $dependencies"
Nicolas De Loof0ef5a622016-05-27 19:14:29 +020094
apotterebbd13d02016-06-23 12:24:15 -040095 IFS=',' read -a array <<< "$dependencies"
96
97 for d in "${array[@]}"
Nicolas De Loof0ef5a622016-05-27 19:14:29 +020098 do
apotterebbd13d02016-06-23 12:24:15 -040099 plugin="$(cut -d':' -f1 - <<< "$d")"
Fredrik Kers96ceb542016-08-13 00:02:02 +0200100 if [[ $d == *"resolution:=optional"* ]]; then
apotterebbd13d02016-06-23 12:24:15 -0400101 echo "Skipping optional dependency $plugin"
Nicolas De Loof0ef5a622016-05-27 19:14:29 +0200102 else
Carlos Sanchez7d165ac2016-08-14 11:13:12 +0200103 local pluginInstalled
104 if pluginInstalled="$(echo "${bundledPlugins}" | grep "^${plugin}:")"; then
105 pluginInstalled="${pluginInstalled//[$'\r']}"
106 local versionInstalled=$(versionFromPlugin "${pluginInstalled}")
107 local versionToInstall=$(versionFromPlugin "${d}")
Carlos Sancheze1b99f42016-07-06 14:22:39 +0200108 if versionLT "${versionInstalled}" "${versionToInstall}"; then
109 echo "Upgrading bundled dependency $d ($versionToInstall > $versionInstalled)"
110 download "$plugin" "$versionToInstall" &
111 else
112 echo "Skipping already bundled dependency $d ($versionToInstall <= $versionInstalled)"
113 fi
114 else
115 download "$plugin" "$(versionFromPlugin "${d}")" &
116 fi
Nicolas De Loof0ef5a622016-05-27 19:14:29 +0200117 fi
118 done
apotterebbd13d02016-06-23 12:24:15 -0400119 wait
Nicolas De Loof0ef5a622016-05-27 19:14:29 +0200120}
121
Carlos Sancheze1b99f42016-07-06 14:22:39 +0200122function bundledPlugins() {
123 local JENKINS_WAR=/usr/share/jenkins/jenkins.war
124 if [ -f $JENKINS_WAR ]
125 then
126 TEMP_PLUGIN_DIR=/tmp/plugintemp.$$
Carlos Sanchez0ab40702016-08-05 10:44:58 +0200127 for i in `jar tf $JENKINS_WAR | egrep '[^detached-]plugins.*\..pi' | sort`
Carlos Sancheze1b99f42016-07-06 14:22:39 +0200128 do
129 rm -fr $TEMP_PLUGIN_DIR
130 mkdir -p $TEMP_PLUGIN_DIR
131 PLUGIN=`basename $i|cut -f1 -d'.'`
132 (cd $TEMP_PLUGIN_DIR;jar xf $JENKINS_WAR "$i";jar xvf $TEMP_PLUGIN_DIR/$i META-INF/MANIFEST.MF >/dev/null 2>&1)
133 VER=`egrep -i Plugin-Version "$TEMP_PLUGIN_DIR/META-INF/MANIFEST.MF"|cut -d\: -f2|sed 's/ //'`
134 echo "$PLUGIN:$VER"
135 done
136 rm -fr $TEMP_PLUGIN_DIR
137 else
138 rm -f $TEMP_ALREADY_INSTALLED
139 echo "ERROR file not found: $JENKINS_WAR"
140 exit 1
141 fi
142}
143
144function versionFromPlugin() {
145 local plugin=$1
146 if [[ $plugin =~ .*:.* ]]; then
147 echo "${plugin##*:}"
148 else
149 echo "latest"
150 fi
151
152}
153
apotterebbd13d02016-06-23 12:24:15 -0400154main() {
155 local plugin version
Sýlvan Heuserb20f3882016-06-01 15:47:38 +0200156
apotterebbd13d02016-06-23 12:24:15 -0400157 mkdir -p "$REF_DIR" || exit 1
Nicolas De Loofa7a34c32016-05-30 09:10:58 +0200158
apotterebbd13d02016-06-23 12:24:15 -0400159 # Create lockfile manually before first run to make sure any explicit version set is used.
160 echo "Creating initial locks..."
161 for plugin in "$@"; do
162 mkdir "$(getLockFile "${plugin%%:*}")"
163 done
164
Carlos Sancheze1b99f42016-07-06 14:22:39 +0200165 echo -e "\nAnalyzing war..."
166 bundledPlugins="$(bundledPlugins)"
167
apotterebbd13d02016-06-23 12:24:15 -0400168 echo -e "\nDownloading plugins..."
169 for plugin in "$@"; do
170 version=""
171
172 if [[ $plugin =~ .*:.* ]]; then
Carlos Sancheze1b99f42016-07-06 14:22:39 +0200173 version=$(versionFromPlugin "${plugin}")
apotterebbd13d02016-06-23 12:24:15 -0400174 plugin="${plugin%%:*}"
175 fi
176
177 download "$plugin" "$version" "true" &
Fredrik Kers96ceb542016-08-13 00:02:02 +0200178 done
apotterebbd13d02016-06-23 12:24:15 -0400179 wait
180
181 if [[ -f $FAILED ]]; then
182 echo -e "\nSome plugins failed to download!\n$(<"$FAILED")" >&2
183 exit 1
184 fi
185
Carlos Sancheze1b99f42016-07-06 14:22:39 +0200186 echo -e "\nCleaning up locks"
187 rm -r "$REF_DIR"/*.lock
apotterebbd13d02016-06-23 12:24:15 -0400188}
189
Brian Antonelli6706b262016-06-24 06:31:54 -0400190main "$@"