Upgrade plugins if needed (#306)
Each plugin installed through the docker image is now tracked using a marker file containing the version that was installed through the image. If later, the container is started from a docker image containing newer plugins, existing plugins will be upgraded if they haven't been upgraded in the mean time and if the new docker image provides a new version of them. Add tests to check that plugins are upgrade properly
This commit is contained in:
parent
195787dca5
commit
bb8f8c9ad0
|
@ -223,6 +223,12 @@ All the data needed is in the /var/jenkins_home directory - so depending on how
|
|||
|
||||
As always - please ensure that you know how to drive docker - especially volume handling!
|
||||
|
||||
## Upgrading plugins
|
||||
|
||||
By default, plugins will be upgraded if they haven't been upgraded manually and if the version from the docker image is newer than the version in the container. Versions installed by the docker image are tracked through a marker file.
|
||||
|
||||
The default behaviour when upgrading from a docker image that didn't write marker files is to leave existing plugins in place. If you want to upgrade existing plugins without marker you may run the docker image with `-e TRY_UPGRADE_IF_NO_MARKER=true`. Then plugins will be upgraded if the version provided by the docker image is newer.
|
||||
|
||||
# Building
|
||||
|
||||
Build with the usual
|
||||
|
|
107
jenkins.sh
107
jenkins.sh
|
@ -2,6 +2,19 @@
|
|||
|
||||
set -e
|
||||
|
||||
# compare if version1 < version2
|
||||
versionLT() {
|
||||
[ "$1" = "$2" ] && return 1 || [ "$1" = "`echo -e "$1\n$2" | sort -V | head -n1`" ]
|
||||
}
|
||||
|
||||
# returns a plugin version from a plugin archive
|
||||
get_plugin_version() {
|
||||
local archive; archive=$1
|
||||
local version; version=$(unzip -p $archive META-INF/MANIFEST.MF | grep "^Plugin-Version: " | sed -e 's#^Plugin-Version: ##')
|
||||
version=${version%%[[:space:]]}
|
||||
echo $version
|
||||
}
|
||||
|
||||
# Copy files from /usr/share/jenkins/ref into $JENKINS_HOME
|
||||
# So the initial JENKINS-HOME is set with expected content.
|
||||
# Don't override, as this is just a reference setup, and use from UI
|
||||
|
@ -9,20 +22,94 @@ set -e
|
|||
copy_reference_file() {
|
||||
f="${1%/}"
|
||||
b="${f%.override}"
|
||||
echo "$f" >> "$COPY_REFERENCE_FILE_LOG"
|
||||
rel="${b:23}"
|
||||
version_marker="${rel}.version_from_image"
|
||||
dir=$(dirname "${b}")
|
||||
echo " $f -> $rel" >> "$COPY_REFERENCE_FILE_LOG"
|
||||
if [[ ! -e $JENKINS_HOME/${rel} || $f = *.override ]]
|
||||
then
|
||||
echo "copy $rel to JENKINS_HOME" >> "$COPY_REFERENCE_FILE_LOG"
|
||||
mkdir -p "$JENKINS_HOME/${dir:23}"
|
||||
cp -r "${f}" "$JENKINS_HOME/${rel}";
|
||||
# pin plugins on initial copy
|
||||
[[ ${rel} == plugins/*.jpi ]] && touch "$JENKINS_HOME/${rel}.pinned"
|
||||
fi;
|
||||
local action;
|
||||
local reason;
|
||||
local container_version;
|
||||
local image_version;
|
||||
local marker_version;
|
||||
local log; log=false
|
||||
if [[ ${rel} == plugins/*.jpi ]]; then
|
||||
container_version=$(get_plugin_version $JENKINS_HOME/${rel})
|
||||
image_version=$(get_plugin_version ${f})
|
||||
if [[ -e $JENKINS_HOME/${version_marker} ]]; then
|
||||
marker_version=$(cat $JENKINS_HOME/${version_marker})
|
||||
if versionLT $marker_version $container_version; then
|
||||
action="SKIPPED"
|
||||
reason="Installed version ($container_version) has been manually upgraded from initial version ($marker_version)"
|
||||
log=true
|
||||
else
|
||||
if [[ "$image_version" == "$container_version" ]]; then
|
||||
action="SKIPPED"
|
||||
reason="Version from image is the same as the installed version $image_version"
|
||||
else
|
||||
if versionLT $image_version $container_version; then
|
||||
action="SKIPPED"
|
||||
log=true
|
||||
reason="Image version ($image_version) is older than installed version ($container_version)"
|
||||
else
|
||||
action="UPGRADED"
|
||||
log=true
|
||||
reason="Image version ($image_version) is newer than installed version ($container_version)"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
else
|
||||
if [[ -n "$TRY_UPGRADE_IF_NO_MARKER" ]]; then
|
||||
if [[ "$image_version" == "$container_version" ]]; then
|
||||
action="SKIPPED"
|
||||
reason="Version from image is the same as the installed version $image_version (no marker found)"
|
||||
# Add marker for next time
|
||||
echo $image_version > $JENKINS_HOME/${version_marker}
|
||||
else
|
||||
if versionLT $image_version $container_version; then
|
||||
action="SKIPPED"
|
||||
log=true
|
||||
reason="Image version ($image_version) is older than installed version ($container_version) (no marker found)"
|
||||
else
|
||||
action="UPGRADED"
|
||||
log=true
|
||||
reason="Image version ($image_version) is newer than installed version ($container_version) (no marker found)"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if [[ ! -e $JENKINS_HOME/${rel} || "$action" == "UPGRADED" || $f = *.override ]]; then
|
||||
action=${action:-"INSTALLED"}
|
||||
log=true
|
||||
mkdir -p "$JENKINS_HOME/${dir:23}"
|
||||
cp -r "${f}" "$JENKINS_HOME/${rel}";
|
||||
# pin plugins on initial copy
|
||||
touch "$JENKINS_HOME/${rel}.pinned"
|
||||
echo $image_version > $JENKINS_HOME/${version_marker}
|
||||
reason=${reason:-$image_version}
|
||||
else
|
||||
action=${action:-"SKIPPED"}
|
||||
fi
|
||||
else
|
||||
if [[ ! -e $JENKINS_HOME/${rel} || $f = *.override ]]
|
||||
then
|
||||
action="INSTALLED"
|
||||
log=true
|
||||
mkdir -p "$JENKINS_HOME/${dir:23}"
|
||||
cp -r "${f}" "$JENKINS_HOME/${rel}";
|
||||
else
|
||||
action="SKIPPED"
|
||||
fi
|
||||
fi
|
||||
if [[ -n "$VERBOSE" || "$log" == "true" ]]; then
|
||||
if [ -z "$reason" ]; then
|
||||
echo "$action $rel" >> "$COPY_REFERENCE_FILE_LOG"
|
||||
else
|
||||
echo "$action $rel : $reason" >> "$COPY_REFERENCE_FILE_LOG"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
: ${JENKINS_HOME:="/var/jenkins_home"}
|
||||
export -f versionLT
|
||||
export -f get_plugin_version
|
||||
export -f copy_reference_file
|
||||
touch "${COPY_REFERENCE_FILE_LOG}" || (echo "Can not write to ${COPY_REFERENCE_FILE_LOG}. Wrong volume permissions?" && exit 1)
|
||||
echo "--- Copying files at $(date)" >> "$COPY_REFERENCE_FILE_LOG"
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
# check dependencies
|
||||
(
|
||||
type docker &>/dev/null || ( echo "docker is not available"; exit 1 )
|
||||
type unzip &>/dev/null || ( echo "unzip is not available"; exit 1 )
|
||||
type curl &>/dev/null || ( echo "curl is not available"; exit 1 )
|
||||
)>&2
|
||||
|
||||
|
|
|
@ -78,3 +78,56 @@ load test_helpers
|
|||
@test "clean test containers" {
|
||||
cleanup $SUT_CONTAINER
|
||||
}
|
||||
|
||||
@test "plugins are getting upgraded but not downgraded" {
|
||||
run docker build -t $SUT_IMAGE-install-plugins $BATS_TEST_DIRNAME/install-plugins
|
||||
assert_success
|
||||
local work; work="$BATS_TEST_DIRNAME/upgrade-plugins/work"
|
||||
# Image contains maven-plugin 2.7.1 and ant-plugin 1.3
|
||||
run bash -c "docker run -ti -v $work:/var/jenkins_home --rm $SUT_IMAGE-install-plugins true"
|
||||
assert_success
|
||||
run bash -c "unzip -p $work/plugins/maven-plugin.jpi META-INF/MANIFEST.MF | tr -d '\r'"
|
||||
assert_line 'Plugin-Version: 2.7.1'
|
||||
run bash -c "unzip -p $work/plugins/ant.jpi META-INF/MANIFEST.MF | tr -d '\r'"
|
||||
assert_line 'Plugin-Version: 1.3'
|
||||
run docker build -t $SUT_IMAGE-upgrade-plugins $BATS_TEST_DIRNAME/upgrade-plugins
|
||||
assert_success
|
||||
# Images contains maven-plugin 2.13 and ant-plugin 1.2
|
||||
run bash -c "docker run -ti -v $work:/var/jenkins_home --rm $SUT_IMAGE-upgrade-plugins true"
|
||||
assert_success
|
||||
run bash -c "unzip -p $work/plugins/maven-plugin.jpi META-INF/MANIFEST.MF | tr -d '\r'"
|
||||
assert_success
|
||||
# Should be updated
|
||||
assert_line 'Plugin-Version: 2.13'
|
||||
run bash -c "unzip -p $work/plugins/ant.jpi META-INF/MANIFEST.MF | tr -d '\r'"
|
||||
# 1.2 is older than the existing 1.3, so keep 1.3
|
||||
assert_line 'Plugin-Version: 1.3'
|
||||
}
|
||||
|
||||
@test "clean work directory" {
|
||||
run bash -c "rm -rf $BATS_TEST_DIRNAME/upgrade-plugins/work"
|
||||
}
|
||||
|
||||
@test "do not upgrade if plugin has been manually updated" {
|
||||
run docker build -t $SUT_IMAGE-install-plugins $BATS_TEST_DIRNAME/install-plugins
|
||||
assert_success
|
||||
local work; work="$BATS_TEST_DIRNAME/upgrade-plugins/work"
|
||||
# Image contains maven-plugin 2.7.1 and ant-plugin 1.3
|
||||
run bash -c "docker run -ti -v $work:/var/jenkins_home --rm $SUT_IMAGE-install-plugins curl --connect-timeout 5 --retry 5 --retry-delay 0 --retry-max-time 60 -s -f -L https://updates.jenkins.io/download/plugins/maven-plugin/2.12.1/maven-plugin.hpi -o /var/jenkins_home/plugins/maven-plugin.jpi"
|
||||
assert_success
|
||||
run bash -c "unzip -p $work/plugins/maven-plugin.jpi META-INF/MANIFEST.MF | tr -d '\r'"
|
||||
assert_line 'Plugin-Version: 2.12.1'
|
||||
run docker build -t $SUT_IMAGE-upgrade-plugins $BATS_TEST_DIRNAME/upgrade-plugins
|
||||
assert_success
|
||||
# Images contains maven-plugin 2.13 and ant-plugin 1.2
|
||||
run bash -c "docker run -ti -v $work:/var/jenkins_home --rm $SUT_IMAGE-upgrade-plugins true"
|
||||
assert_success
|
||||
run bash -c "unzip -p $work/plugins/maven-plugin.jpi META-INF/MANIFEST.MF | tr -d '\r'"
|
||||
assert_success
|
||||
# Shouldn't be updated
|
||||
refute_line 'Plugin-Version: 2.13'
|
||||
}
|
||||
|
||||
@test "clean work directory" {
|
||||
run bash -c "rm -rf $BATS_TEST_DIRNAME/upgrade-plugins/work"
|
||||
}
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
FROM bats-jenkins
|
||||
|
||||
RUN /usr/local/bin/install-plugins.sh maven-plugin:2.13 ant:1.2
|
Loading…
Reference in New Issue