Skip to content

Commit bbd13d0

Browse files
apotterecarlossg
authored andcommitted
Update download script to add parallelism, correct locking, and specific version support. (jenkinsci#291)
Update download script to add parallelism, correct locking, and specific version support. Add support for provided plugins.
1 parent dd5373a commit bbd13d0

File tree

1 file changed

+107
-53
lines changed

1 file changed

+107
-53
lines changed

install-plugins.sh

Lines changed: 107 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,138 @@
1-
#! /bin/bash
1+
#!/bin/bash
22

33
# Resolve dependencies and download plugins given on the command line
44
#
55
# FROM jenkins
66
# RUN install-plugins.sh docker-slaves github-branch-source
77

8-
set -e
8+
REF_DIR=${REF:-/usr/share/jenkins/ref/plugins}
9+
FAILED="$REF_DIR/failed-plugins.txt"
910

10-
REF=${REF:-/usr/share/jenkins/ref/plugins}
11-
mkdir -p "$REF"
12-
13-
function download() {
14-
local plugin="$1"; shift
15-
16-
if [[ ! -f "${plugin}.hpi" ]]; then
11+
function getLockFile() {
12+
echo -n "$REF_DIR/${1}.lock"
13+
}
1714

18-
local url="${JENKINS_UC}/latest/${plugin}.hpi"
19-
echo "download plugin : $plugin from $url"
15+
function getHpiFilename() {
16+
echo -n "$REF_DIR/${1}.hpi"
17+
}
2018

21-
if ! curl -s -f -L "$url" -o "${plugin}.hpi"
22-
then
19+
function download() {
20+
local plugin originalPlugin version lock ignoreLockFile
21+
plugin="$1"
22+
version="${2:-latest}"
23+
ignoreLockFile="$3"
24+
lock="$(getLockFile "$plugin")"
25+
26+
if [[ $ignoreLockFile ]] || mkdir "$lock" &>/dev/null; then
27+
if ! doDownload "$plugin" "$version"; then
2328
# some plugin don't follow the rules about artifact ID
2429
# typically: docker-plugin
25-
plugin=${plugin}-plugin
26-
27-
local url="${JENKINS_UC}/latest/${plugin}.hpi"
28-
echo "download plugin : $plugin from $url"
29-
if ! curl -s -f -L "${url}" -o "${plugin}.hpi"
30-
then
31-
>&2 echo "failed to download plugin ${plugin}"
32-
exit -1
30+
originalPlugin="$plugin"
31+
plugin="${plugin}-plugin"
32+
if ! doDownload "$plugin" "$version"; then
33+
echo "Failed to download plugin: $originalPlugin or $plugin" >&2
34+
echo "Not downloaded: ${originalPlugin}" >> "$FAILED"
35+
return 1
3336
fi
3437
fi
35-
else
36-
echo "$plugin is already downloaded."
37-
fi
3838

39-
if [[ ! -f ${plugin}.resolved ]]; then
39+
if ! checkIntegrity "$plugin"; then
40+
echo "Downloaded file is not a valid ZIP: $(getHpiFilename "$plugin")" >&2
41+
echo "Download integrity: ${plugin}" >> "$FAILED"
42+
return 1
43+
fi
44+
4045
resolveDependencies "$plugin"
4146
fi
4247
}
4348

49+
function doDownload() {
50+
local plugin version url hpi
51+
plugin="$1"
52+
version="$2"
53+
hpi="$(getHpiFilename "$plugin")"
54+
55+
if [[ -f $hpi ]]; then
56+
echo "Using provided plugin: $plugin"
57+
return 0
58+
fi
59+
60+
url="$JENKINS_UC/download/plugins/$plugin/$version/${plugin}.hpi"
61+
62+
echo "Downloading plugin: $plugin from $url"
63+
curl -s -f -L "$url" -o "$hpi"
64+
return $?
65+
}
66+
67+
function checkIntegrity() {
68+
local plugin hpi
69+
plugin="$1"
70+
hpi="$(getHpiFilename "$plugin")"
71+
72+
zip -T "$hpi" >/dev/null
73+
return $?
74+
}
75+
4476
function resolveDependencies() {
45-
local plugin="$1"; shift
46-
47-
local dependencies=`jrunscript -e '\
48-
java.lang.System.out.println(\
49-
new java.util.jar.JarFile("'${plugin}.hpi'")\
50-
.getManifest()\
51-
.getMainAttributes()\
52-
.getValue("Plugin-Dependencies")\
53-
);'`
54-
55-
if [[ "$dependencies" == "null" ]]; then
56-
echo " > plugin has no dependencies"
77+
local plugin hpi dependencies
78+
plugin="$1"
79+
hpi="$(getHpiFilename "$plugin")"
80+
81+
# ^M below is a control character, inserted by typing ctrl+v ctrl+m
82+
dependencies="$(unzip -p "$hpi" META-INF/MANIFEST.MF | sed -e 's###g' | tr '\n' '|' | sed -e 's#| ##g' | tr '|' '\n' | grep "^Plugin-Dependencies: " | sed -e 's#^Plugin-Dependencies: ##')"
83+
84+
if [[ ! $dependencies ]]; then
85+
echo " > $plugin has no dependencies"
5786
return
5887
fi
5988

60-
echo " > depends on ${dependencies}"
89+
echo " > $plugin depends on $dependencies"
6190

62-
IFS=',' read -a array <<< "${dependencies}"
63-
for d in "${array[@]}"
91+
IFS=',' read -a array <<< "$dependencies"
92+
93+
for d in "${array[@]}"
6494
do
65-
local p=$(echo $d | cut -d':' -f1 -)
66-
if [[ $d == *"resolution:=optional"* ]]
67-
then
68-
echo "skipping optional dependency $p"
95+
plugin="$(cut -d':' -f1 - <<< "$d")"
96+
if [[ $d == *"resolution:=optional"* ]]; then
97+
echo "Skipping optional dependency $plugin"
6998
else
70-
download "$p"
99+
download "$plugin" &
71100
fi
72101
done
73-
touch "${plugin}.resolved"
102+
wait
74103
}
75104

76-
cd "$REF"
105+
main() {
106+
local plugin version
107+
108+
mkdir -p "$REF_DIR" || exit 1
109+
110+
# Create lockfile manually before first run to make sure any explicit version set is used.
111+
echo "Creating initial locks..."
112+
for plugin in "$@"; do
113+
mkdir "$(getLockFile "${plugin%%:*}")"
114+
done
77115

78-
for plugin in "$@"
79-
do
80-
download "$plugin"
81-
done
116+
echo -e "\nDownloading plugins..."
117+
for plugin in "$@"; do
118+
version=""
119+
120+
if [[ $plugin =~ .*:.* ]]; then
121+
version="${plugin##*:}"
122+
plugin="${plugin%%:*}"
123+
fi
124+
125+
download "$plugin" "$version" "true" &
126+
done
127+
wait
128+
129+
if [[ -f $FAILED ]]; then
130+
echo -e "\nSome plugins failed to download!\n$(<"$FAILED")" >&2
131+
exit 1
132+
fi
133+
134+
echo -e "\nCleaning up locks..."
135+
rm -rv "$REF_DIR"/*.lock
136+
}
82137

83-
# cleanup 'resolved' flag files
84-
rm -f *.resolved
138+
main "$@"

0 commit comments

Comments
 (0)