Skip to content

Instantly share code, notes, and snippets.

@dduportal
Last active March 4, 2021 17:39
Show Gist options
  • Save dduportal/52c9005499a1d7fd00bba2ab742c029b to your computer and use it in GitHub Desktop.
Save dduportal/52c9005499a1d7fd00bba2ab742c029b to your computer and use it in GitHub Desktop.
#!/bin/bash
# This script updates all the installed plugins of a Jenkins docker container,
# restart the instance and outputs the resulting list of updated plugins (aka. "plugins.txt")
#
set -eu -o pipefail
JENKINS_URL=https://"${JENKINS_HOST}"
JENKINS_TEST_CREDZ="admin:${ADMIN_TOKEN}"
JENKINS_CONTAINER_NAME="${PROJECT_ID:-default}_jenkins_1"
CURL_OPTS=("--insecure" "--fail" "--location" "--silent" "--show-error" "--user" "${JENKINS_TEST_CREDZ}")
PLUGINS_TXT_FILE="${PLUGINS_TXT_FILE:-"plugins.txt"}"
## Check for CLI requirements
for CLI in perl sed curl sort uniq docker
do
command -v "${CLI}" >/dev/null 2>&1 || {
echo "ERROR: Command Line ${CLI} not found but is required. Exiting."
exit 1
}
done
###### get_jenkins_plugins_list()
# Prints on the stdout the alphabetically order list of plugins installed on the provided Jenkins instance.
# The format of the stdout is one line per plugin, with the name and version on each line, separated by a colon (':')
#
# Arguments: none
function get_jenkins_plugins_list() {
curl "${CURL_OPTS[@]}" "${1}/pluginManager/api/xml?depth=1&xpath=/*/*/shortName|/*/*/version&wrapper=plugins" \
| perl -pe 's/.*?<shortName>([\w-]+).*?<version>([^<]+)()(<\/\w+>)+/\1 \2\n/g' \
| sed 's/ /:/' | sort | uniq
}
function retry() {
counter=0
max_retries="$1"
shift
waiting_time="$1"
shift
until [ "${counter}" -ge "${max_retries}" ]
do
if "$@"
then
break
fi
sleep "${waiting_time}"
counter=$((counter+1))
done
if [ "${counter}" -ge "${max_retries}" ]
then
return 1
fi
return 0
}
echo "== Checking if Jenkins container is up and healty..."
retry 30 10 bash -c "docker inspect -f '{{json .State.Health.Status}}' ${JENKINS_CONTAINER_NAME} | grep -q '\"healthy\"'" || {
echo "== ERROR: the Jenkins container ${JENKINS_CONTAINER_NAME} is not healthy after 1 minute. Exiting."
exit 1
}
echo "== Jenkins container ${JENKINS_CONTAINER_NAME} is up and healthy."
echo "== Retrieving list of plugins from Jenkins instance at ${JENKINS_URL}..."
curl "${CURL_OPTS[@]}" -o /dev/null "${JENKINS_URL}/manage" 2>/dev/null
echo "== The Jenkins instance management page at ${JENKINS_URL}/manage can be accessed."
### Get the list of CURRENTLY installed packages
CURRENT_PLUGINS_LIST="$(get_jenkins_plugins_list "${JENKINS_URL}")"
echo "== List of plugins retrieved successfully."
echo "== Upgrading the list of plugins in a new Docker image..."
DOCKER_IMAGE_NAME=jenkins-plugins-upgrade
DOCKER_CONTAINER_NAME=jenkins-plugins-upgrade
cat <<EOF | docker build --pull --no-cache --tag="${DOCKER_IMAGE_NAME}" -
# Always use the latest LTS
FROM jenkins/jenkins:lts
# Install Plugins (latest version)
RUN /usr/local/bin/install-plugins.sh $(echo "${CURRENT_PLUGINS_LIST}" | cut -d: -f1 | tr "\n" " ")
ENV JAVA_OPTS="-Djenkins.install.runSetupWizard=false"
EOF
echo "== Docker image built successfully."
echo "== Starting a temp Jenkins instance in a Docker container from this new image..."
docker kill "${DOCKER_CONTAINER_NAME}" || true
docker rm -f -v "${DOCKER_CONTAINER_NAME}" || true
docker run --rm -d -P --name="${DOCKER_CONTAINER_NAME}" "${DOCKER_IMAGE_NAME}"
TEMP_JENKINS_ADDRESS="$(docker port "${DOCKER_CONTAINER_NAME}" 8080/tcp)"
retry 30 2 curl "${CURL_OPTS[@]}" "${TEMP_JENKINS_ADDRESS}" || {
echo "== ERROR: could not access the temp Jenkins instance in the docker container ${DOCKER_CONTAINER_NAME}. Check its logs. Exiting."
exit 1
}
echo "== The temp Jenkins instance is available."
echo "== Exporting the new plugins list..."
get_jenkins_plugins_list "${TEMP_JENKINS_ADDRESS}" | tee "${PLUGINS_TXT_FILE}"
echo "== Updated plugin list is available at ${PLUGINS_TXT_FILE}. End of Script"
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment