Skip to content

Instantly share code, notes, and snippets.

@jack-tjia
Created July 19, 2019 17:48
Show Gist options
  • Save jack-tjia/0c1f27b1c545fb13b02cb50d42ec8510 to your computer and use it in GitHub Desktop.
Save jack-tjia/0c1f27b1c545fb13b02cb50d42ec8510 to your computer and use it in GitHub Desktop.
Script to update jenkins master
#!/bin/sh
################################################################################
# This script will upgrade Jenkins.
#
# It assumes the Jenkins server is started with java -jar jenkins.war command.
# The script will backup existing Jenkins war file and configurations.
# After upgrade is done, Jenkins server will be restarted.
#
# Check upgrade.sh -h to get help.
#
# Jack (Tiefeng) Jia <jiatiefeng@gmail.com>, May 2019
################################################################################
################################################################################
# constants
SCRIPT_NAME=$(basename "$0")
LATEST_JENKINS_WAR=http://mirrors.jenkins-ci.org/war/latest/jenkins.war
LATEST_JENKINS_SHA256=http://mirrors.jenkins-ci.org/war/latest/jenkins.war.sha256
DEFAULT_BACKUP_FOLDER=$(pwd)/backup
DEFAULT_JENKINS_WAR=./jenkins.war
DEFAULT_JENKINS_HOME=/var/lib/jenkins
DEFAULT_JENKINS_URL=http://localhost:8080
DEFAULT_JENKINS_ADMIN=admin
################################################################################
# variables
BACKUP_FOLDER=$DEFAULT_BACKUP_FOLDER
JENKINS_WAR=$DEFAULT_JENKINS_WAR
JENKINS_HOME=$DEFAULT_JENKINS_HOME
JENKINS_URL=$DEFAULT_JENKINS_URL
JENKINS_ADMIN=$DEFAULT_JENKINS_ADMIN
JENKINS_TOKEN=
################################################################################
# Check if Jenkins is running
#
# Returns:
# - 0: not running
# - 1: running
function is_jenkins_running {
IS_RUNNING=$(ps a | grep jenkins.war | grep -v "$SCRIPT_NAME" | grep -v grep)
if [ -z "$IS_RUNNING" ]; then
return 0
else
return 1
fi
}
################################################################################
# parse parameters
function usage {
echo "Upgrade Jenkins server"
echo
echo "Usage: $SCRIPT_NAME [Options] [jenkins-war-file]"
echo
echo "jenkins-war-file: Path to jenkins.war."
echo " Optional, default value is ${DEFAULT_JENKINS_WAR}"
echo
echo "Options:"
echo " -h|--help Display this help message."
echo " -b|--backup Backup folder."
echo " Optional, default value is ${DEFAULT_BACKUP_FOLDER}"
echo " -H|--home Jenkins home folder."
echo " Optional, default value is ${DEFAULT_JENKINS_HOME}"
echo " -r|--url Jenkins URL."
echo " Optional, default value is ${DEFAULT_JENKINS_URL}"
echo " -u|--username Jenkins admin username."
echo " Optional, default value is ${DEFAULT_JENKINS_ADMIN}."
echo " -t|--token Jenkins admin API token."
echo " Required."
echo
}
POSITIONALINDEX=0
POSITIONAL[$POSITIONALINDEX]=
while [ $# -gt 0 ]; do
key="$1"
case $key in
-h|--help)
usage
exit 0
;;
-H|--home)
JENKINS_HOME="$2"
shift # past argument
shift # past value
;;
-r|--url)
JENKINS_URL="$2"
shift # past argument
shift # past value
;;
-u|--username)
JENKINS_ADMIN="$2"
shift # past argument
shift # past value
;;
-t|--token)
JENKINS_TOKEN="$2"
shift # past argument
shift # past value
;;
*) # unknown option
if [ ! "$1" = "${1#-}" ]; then
echo "[${SCRIPT_NAME}][error] invalid option: $1" >&2
exit 1
fi
POSITIONAL[$POSITIONALINDEX]="$1" # save it in an array for later
POSITIONALINDEX=$((POSITIONALINDEX + 1))
shift # past argument
;;
esac
done
set -- "${POSITIONAL[@]}" # restore positional parameters
if [ ! -z "$1" ]; then
JENKINS_WAR=$1
fi
################################################################################
# init variables
is_jenkins_running
JENKINS_IS_RUNNING=$?
CURL_EXISTS=$(which curl)
TS=$(date +%Y%m%d%H%M%S)
CURRENT_DIR=$(pwd)
################################################################################
echo "[${SCRIPT_NAME}] Jenkins upgrade script started ..."
echo "[${SCRIPT_NAME}] - war file : $JENKINS_WAR"
echo "[${SCRIPT_NAME}] - jenkins home : $JENKINS_HOME"
echo "[${SCRIPT_NAME}] - url : $JENKINS_URL"
echo "[${SCRIPT_NAME}] - admin : $JENKINS_ADMIN"
echo "[${SCRIPT_NAME}] - api token : ****"
echo "[${SCRIPT_NAME}] - backup folder : $BACKUP_FOLDER"
echo
################################################################################
# essential validations
if [ "$JENKINS_IS_RUNNING" != "1" ]; then
>&2 echo "[${SCRIPT_NAME}][error] Jenkins is not running."
exit 1
fi
if [ -z "$JENKINS_WAR" ]; then
>&2 echo "[${SCRIPT_NAME}][error] jenkins war file is required."
exit 1
fi
if [ -z "$JENKINS_HOME" ]; then
>&2 echo "[${SCRIPT_NAME}][error] jenkins home folder is required."
exit 1
fi
if [ ! -f "$JENKINS_HOME/config.xml" ]; then
>&2 echo "[${SCRIPT_NAME}][error] ${JENKINS_HOME} doesn't appear to be a Jenkins home folder (config.xml missing)."
exit 1
fi
if [ ! -f "$JENKINS_WAR" ]; then
>&2 echo "[${SCRIPT_NAME}][error] jenkins war file doesn't exist."
exit 1
fi
if [ "$JENKINS_IS_RUNNING" == "1" ]; then
if [ -z "$JENKINS_URL" ]; then
>&2 echo "[${SCRIPT_NAME}][error] jenkins url is required."
exit 1
fi
if [ -z "$JENKINS_ADMIN" ]; then
>&2 echo "[${SCRIPT_NAME}][error] jenkins admin username is required."
exit 1
fi
if [ -z "$JENKINS_TOKEN" ]; then
>&2 echo "[${SCRIPT_NAME}][error] jenkins admin API token is required."
exit 1
fi
fi
if [ -z "$CURL_EXISTS" ]; then
>&2 echo "[${SCRIPT_NAME}][error] curl is required."
exit 1
fi
################################################################################
CURRENT_JENKINS_VERSION=$(cat "${JENKINS_HOME}/config.xml" | grep '<version>' | sed -e 's#<version>##' -e 's#</version>##' -e 's# ##g')
if [ -z "$CURRENT_JENKINS_VERSION" ]; then
>&2 echo "[${SCRIPT_NAME}][error] cannot determine current Jenkins version."
exit 1
fi
echo "[${SCRIPT_NAME}] current Jenkins version is: ${CURRENT_JENKINS_VERSION}"
echo
################################################################################
# backup
mkdir -p "${BACKUP_FOLDER}/${TS}-${CURRENT_JENKINS_VERSION}"
cd "${BACKUP_FOLDER}/${TS}-${CURRENT_JENKINS_VERSION}"
BACKUP_FOLDER_PARSED=$(pwd)
echo "[${SCRIPT_NAME}] backup current Jenkins to ${BACKUP_FOLDER_PARSED} ..."
cd ${CURRENT_DIR}
echo "[${SCRIPT_NAME}] - jenkins.war"
cp "${JENKINS_WAR}" "${BACKUP_FOLDER_PARSED}"
cd "${JENKINS_HOME}"
echo "[${SCRIPT_NAME}] - jenkins home folder"
tar zcf "${BACKUP_FOLDER_PARSED}/home.tar.gz" .
cd ${CURRENT_DIR}
echo "[${SCRIPT_NAME}] backup done"
echo
################################################################################
# download latest version
echo "[${SCRIPT_NAME}] downloading latest version ..."
JENKINS_WAR_FOLDER=$(dirname "${JENKINS_WAR}")
cd $JENKINS_WAR_FOLDER
JENKINS_WAR_FOLDER_PARSED=$(pwd)
echo "[${SCRIPT_NAME}] - jenkins.war"
curl -fL ${LATEST_JENKINS_WAR} -o jenkins.war.latest
SHA256_DOWNLOADED=$(shasum -a 256 jenkins.war.latest | awk '{print $1}')
echo "[${SCRIPT_NAME}] > ${SHA256_DOWNLOADED}"
echo "[${SCRIPT_NAME}] - jenkins.war.sha256"
SHA256_LATEST=$(curl -fsL ${LATEST_JENKINS_SHA256} | awk '{print $1}')
echo "[${SCRIPT_NAME}] > ${SHA256_LATEST}"
if [ "${SHA256_DOWNLOADED}" != "${SHA256_LATEST}" ]; then
>&2 echo "[${SCRIPT_NAME}][error] jenkins.war hash doesn't match."
exit 3
fi
# successful, overwrite
mv jenkins.war.latest jenkins.war
echo "[${SCRIPT_NAME}] download successfully, jenkins.war is updated."
cd ${CURRENT_DIR}
echo
################################################################################
# Restart Jenkins
echo "[${SCRIPT_NAME}] Jenkins will be restarted after all builds are finished ..."
curl -s -X POST -u "${JENKINS_ADMIN}:${JENKINS_TOKEN}" "${JENKINS_URL}/safeRestart"
echo
################################################################################
echo "[${SCRIPT_NAME}] upgrade done."
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment