blob: 2c8cc201325bfa998fdc016a85e1ad8915dc37d0 [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 Sanchezc0f63792016-08-15 10:30:16 +020065 url="$JENKINS_UC/download/plugins/$plugin/$version/${plugin}.hpi"
apotterebbd13d02016-06-23 12:24:15 -040066
Carlos Sanchezc0f63792016-08-15 10:30:16 +020067 echo "Downloading plugin: $plugin from $url"
68 curl --connect-timeout 5 --retry 5 --retry-delay 0 --retry-max-time 60 -s -f -L "$url" -o "$jpi"
69 return $?
apotterebbd13d02016-06-23 12:24:15 -040070}
71
72function checkIntegrity() {
Carlos Sanchezc0f63792016-08-15 10:30:16 +020073 local plugin jpi
74 plugin="$1"
75 jpi="$(getArchiveFilename "$plugin")"
apotterebbd13d02016-06-23 12:24:15 -040076
Carlos Sanchezc0f63792016-08-15 10:30:16 +020077 zip -T "$jpi" >/dev/null
78 return $?
apotterebbd13d02016-06-23 12:24:15 -040079}
80
Fredrik Kers96ceb542016-08-13 00:02:02 +020081function resolveDependencies() {
Carlos Sanchezc0f63792016-08-15 10:30:16 +020082 local plugin jpi dependencies
83 plugin="$1"
84 jpi="$(getArchiveFilename "$plugin")"
Nicolas De Loof0ef5a622016-05-27 19:14:29 +020085
Carlos Sanchezc0f63792016-08-15 10:30:16 +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
Carlos Sanchezc0f63792016-08-15 10:30:16 +020088 if [[ ! $dependencies ]]; then
89 echo " > $plugin has no dependencies"
90 return
91 fi
Nicolas De Loof0ef5a622016-05-27 19:14:29 +020092
Carlos Sanchezc0f63792016-08-15 10:30:16 +020093 echo " > $plugin depends on $dependencies"
Nicolas De Loof0ef5a622016-05-27 19:14:29 +020094
Carlos Sanchezc0f63792016-08-15 10:30:16 +020095 IFS=',' read -a array <<< "$dependencies"
apotterebbd13d02016-06-23 12:24:15 -040096
Carlos Sanchezc0f63792016-08-15 10:30:16 +020097 for d in "${array[@]}"
98 do
99 plugin="$(cut -d':' -f1 - <<< "$d")"
100 if [[ $d == *"resolution:=optional"* ]]; then
101 echo "Skipping optional dependency $plugin"
102 else
103 local pluginInstalled
104 if pluginInstalled="$(echo "${bundledPlugins}" | grep "^${plugin}:")"; then
105 pluginInstalled="${pluginInstalled//[$'\r']}"
106 local versionInstalled; versionInstalled=$(versionFromPlugin "${pluginInstalled}")
107 local versionToInstall; versionToInstall=$(versionFromPlugin "${d}")
108 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
117 fi
118 done
119 wait
Nicolas De Loof0ef5a622016-05-27 19:14:29 +0200120}
121
Carlos Sancheze1b99f42016-07-06 14:22:39 +0200122function bundledPlugins() {
Carlos Sanchezc0f63792016-08-15 10:30:16 +0200123 local JENKINS_WAR=/usr/share/jenkins/jenkins.war
124 if [ -f $JENKINS_WAR ]
125 then
126 TEMP_PLUGIN_DIR=/tmp/plugintemp.$$
127 for i in $(jar tf $JENKINS_WAR | egrep '[^detached-]plugins.*\..pi' | sort)
128 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
Carlos Sancheze1b99f42016-07-06 14:22:39 +0200142}
143
144function versionFromPlugin() {
Carlos Sanchezc0f63792016-08-15 10:30:16 +0200145 local plugin=$1
146 if [[ $plugin =~ .*:.* ]]; then
147 echo "${plugin##*:}"
148 else
149 echo "latest"
150 fi
Carlos Sancheze1b99f42016-07-06 14:22:39 +0200151
152}
153
apotterebbd13d02016-06-23 12:24:15 -0400154main() {
Carlos Sanchezc0f63792016-08-15 10:30:16 +0200155 local plugin version
Sýlvan Heuserb20f3882016-06-01 15:47:38 +0200156
Carlos Sanchezc0f63792016-08-15 10:30:16 +0200157 mkdir -p "$REF_DIR" || exit 1
Nicolas De Loofa7a34c32016-05-30 09:10:58 +0200158
Carlos Sanchezc0f63792016-08-15 10:30:16 +0200159 # 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
apotterebbd13d02016-06-23 12:24:15 -0400164
Carlos Sanchezc0f63792016-08-15 10:30:16 +0200165 echo -e "\nAnalyzing war..."
166 bundledPlugins="$(bundledPlugins)"
Carlos Sancheze1b99f42016-07-06 14:22:39 +0200167
Carlos Sanchezc0f63792016-08-15 10:30:16 +0200168 echo -e "\nDownloading plugins..."
169 for plugin in "$@"; do
170 version=""
apotterebbd13d02016-06-23 12:24:15 -0400171
Carlos Sanchezc0f63792016-08-15 10:30:16 +0200172 if [[ $plugin =~ .*:.* ]]; then
173 version=$(versionFromPlugin "${plugin}")
174 plugin="${plugin%%:*}"
175 fi
apotterebbd13d02016-06-23 12:24:15 -0400176
Carlos Sanchezc0f63792016-08-15 10:30:16 +0200177 download "$plugin" "$version" "true" &
178 done
179 wait
apotterebbd13d02016-06-23 12:24:15 -0400180
Carlos Sanchezc0f63792016-08-15 10:30:16 +0200181 if [[ -f $FAILED ]]; then
182 echo -e "\nSome plugins failed to download!\n$(<"$FAILED")" >&2
183 exit 1
184 fi
apotterebbd13d02016-06-23 12:24:15 -0400185
Carlos Sanchezc0f63792016-08-15 10:30:16 +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 "$@"