#!/bin/bash
#exec 3>&1 4>&2
#trap 'exec 2>&4 1>&3' 0 1 2 3
#exec 1>log.out 2>&1
set -o errexit
set -o pipefail
set -u
function log() {
COLOR='\033[01;32m' # bold yellow
RESET='\033[00;00m' # normal white
MESSAGE=${@:-"${RESET}Error: No message passed"}
echo -e "${COLOR}${MESSAGE}${RESET}" >> manage-jenkins-log.txt
}
function warning() {
COLOR='\033[01;34m' # bold yellow
RESET='\033[00;00m' # normal white
MESSAGE=${@:-"${RESET}Error: No message passed"}
echo -e "${COLOR}${MESSAGE}${RESET}" >> manage-jenkins-log.txt
}
function error() {
COLOR='\033[01;31m' # bold red
RESET='\033[00;00m' # normal white
MESSAGE=${@:-"${RESET}Error: No message passed"}
echo -e "${COLOR}${MESSAGE}${RESET}" >> manage-jenkins-log.txt
}
# Names to identify images and containers of this app
IMAGE_NAME='lhjenkins_jenkins'
CONTAINER_NAME='lhjenkins_jenkins_1'
# Usefull to run commands as non-root user inside containers
USER=$USER
HOME_DIR=$HOME
EXECUTE_AS="sudo -u $USER HOME=$HOME_DIR"
IMAGE_PATH="$HOME_DIR/lh-jenkins"
IMAGE_PATH_OLD="$HOME_DIR/lh-jenkins_old"
GIT_URL=""
CERTS_PATH="$IMAGE_PATH/nginx/ssl/jenkins"
LOGDIR="$HOME_DIR/log"
BACKUP_PATH="$HOME_DIR/backup"
MASTER_CONFIG_PATH="$IMAGE_PATH/conf"
MASTER_CONFIG_FILE="jenkins-master-config.yml"
DOCKER_COMPOSE_FILE="docker-compose.yml"
DATA_PATH_HOST="/data/jenkins_home"
DATA_PATH_HOST_OLD="/data/jenkins_home_old"
DATA_PATH_HOST_BACKUP="/data/jenkins_home_$(date '+%d-%b-%Y')"
UPGRADE_JENKINS_PATH="$HOME_DIR/lh-jenkins-$(date '+%d-%b-%Y')"
HOST_DOCKER_GID=`grep "^docker:" /etc/group | grep -o [0-9]* |awk '{print $1}'`
echo $HOST_DOCKER_GID
DOCKER_GID=$HOST_DOCKER_GID
CURRENT_JENKINS_INSTANCE_RUNNING=false
log_file="$HOME_DIR/log/manageJenkins_$(date '+%d-%b-%Y').log"
mkdir -p $LOGDIR
ENV_VAR_FILE="envVars.sh"
# define usage function
usage(){
echo "usage $0 -h or -i <GIT URL> or -u or -v $0 --help --install <GIT URL> --upgrade --verbose "
exit 1
}
#function exportEnvVars() {
# cd $IMAGE_PATH
# echo "current path is $(pwd)"
# source ./$ENV_VAR_FILE
# echo "After env vars setting:"
#}
function backupFiles() {
echo "Backup existing files"
now=$(date '+%d-%b-%Y')
BACKUP_PATH="$BACKUP_PATH/$now/"
echo "Backup path is : $BACKUP_PATH"
mkdir -p $BACKUP_PATH
mv $MASTER_CONFIG_PATH/$MASTER_CONFIG_FILE $BACKUP_PATH
mv $IMAGE_PATH/$DOCKER_COMPOSE_FILE $BACKUP_PATH
mv $CERTS_PATH/*.* $BACKUP_PATH
}
function buildContainer() {
cd $1
docker-compose build
}
function installContainer() {
echo "Installing full application at once"
if [ -d "$IMAGE_PATH" ]; then
printf '%s\n' "Removing existing ($IMAGE_PATH)"
rm -rf "$IMAGE_PATH"
fi
git clone $GIT_URL $IMAGE_PATH
echo "Build Container"
buildContainer $IMAGE_PATH
echo "start Container"
startContainer $IMAGE_PATH
exit 0
}
function bash() {
log "BASH"
docker exec -it $IMAGE_NAME /bin/bash
}
function upgradeContainer() {
log "UPGRADE"
echo "Upgrding the container"
#backupFiles
echo -n "Upgrade certificates / config File / Total Application (c /f /a)?"
read choice
if echo "$choice" | grep -iq "^c" ;then
echo -n "Please enter certificates path "
read srcCertsPath
echo -n "is the path $certsPath is correct or not, please proceed with (y/n)?"
read answer
if echo "$answer" | grep -iq "^y" ;then
cp "${srcCertsPath}/*.pem *.cer" "${CERTS_PATH}/"
fi
elif echo "$choice" | grep -iq "^f" ;then
echo -n "Please enter config file path "
read configFilePath
echo -n "is the path $configFilePath is correct or not, please proceed with (y/n)?"
read answer
if echo "$answer" | grep -iq "^y" ;then
find "$configFilePath/$MASTER_CONFIG_FILE" -name "$MASTER_CONFIG_FILE" -exec mv -i {} -t $MASTER_CONFIG_PATH \;
find "$configFilePath/$DOCKER_COMPOSE_FILE" -name "$DOCKER_COMPOSE_FILE" -exec mv -i {} -t $IMAGE_PATH \;
fi
elif echo "$choice" | grep -iq "^a" ;then
echo "Application will be upgraded from SCM"
GIT_URL=`git remote show origin | grep 'Fetch URL' -n |awk '{print $4}'`
echo -n "The SCM URL for update is $GIT_URL -> \nPress 'y' to proceed or 'u' to enter new SCM URL : "
read answer
if echo "$answer" | grep -iq "^y" ;then
upgradeFull $GIT_URL
elif echo "$answer" | grep -iq "^u" ;then
echo -n "Enter SCM URL for update (ex. $GIT_URL ) : "
read UPDATED_GIT_URL
upgradeFull $UPDATED_GIT_URL
fi
fi
#buildContainer $IMAGE_PATH
#startContainer $IMAGE_PATH
exit 0
}
function removeVolume() {
docker volume rm $1
}
function upgradeFull() {
URL=$1
echo "Exported docker group ID : $DOCKER_GID"
sudo mkdir -p $DATA_PATH_HOST_BACKUP
echo "Change mod of $DATA_PATH_HOST_BACKUP"
sudo chmod 775 -R $DATA_PATH_HOST_BACKUP
sudo chown -R $USER:$DOCKER_GID $DATA_PATH_HOST_BACKUP
echo "Copy fils from jenkins_home"
sudo cp -r $DATA_PATH_HOST/* $DATA_PATH_HOST_BACKUP/
echo "Created all required directories and copied files"
DIR=$UPGRADE_JENKINS_PATH
if [ -d "$DIR" ]; then
printf '%s\n' "Removing existing ($DIR)"
rm -rf "$DIR"
fi
mkdir -p $UPGRADE_JENKINS_PATH
sudo chmod 775 -R $UPGRADE_JENKINS_PATH
sudo chown -R $USER:$DOCKER_GID $UPGRADE_JENKINS_PATH
CURRENT_JENKINS_INSTANCE_RUNNING=`docker ps | grep $CONTAINER_NAME | awk '{print $14}'`
echo "Current running instance is : $CURRENT_JENKINS_INSTANCE_RUNNING"
if [ $CURRENT_JENKINS_INSTANCE_RUNNING != false ]; then
git clone $URL $UPGRADE_JENKINS_PATH
sudo rm -f $DATA_PATH_HOST_BACKUP/init.groovy.d/*
sudo rm -rf $DATA_PATH_HOST_BACKUP/jobs/bitbucketServer-cd-enabler/
echo -n "Enter temporary port for updating Jenkins : (Don't input port no.8081, which already in use): "
read tmpJenkinsPort
echo -n "Enter temporary port for updating nginx : (Don't input port no.8443, which already in use): "
read tmpNginxPort
cd $UPGRADE_JENKINS_PATH
docker_id_string='${HOST_DOCKER_GID}'
log "The docker string is $docker_id_string"
log "Upgraded Jenkins path is : $UPGRADE_JENKINS_PATH "
sed -i -e "s/8081/$tmpJenkinsPort/" $DOCKER_COMPOSE_FILE
sed -i -e "s/8443/$tmpNginxPort/" $DOCKER_COMPOSE_FILE
sed -i -e "s/$docker_id_string/$DOCKER_GID/" $DOCKER_COMPOSE_FILE
buildContainer $UPGRADE_JENKINS_PATH
log "Container build was done, now starting Container "
startContainer $UPGRADE_JENKINS_PATH
log "Started Container "
updated_instance_url="http://$(hostname):$tmpJenkinsPort"
log "Please check the following URL in web browser: $updated_instance_url "
echo -n "Press 'y' to if you can see the updated Jenkins Login Page"
read answer
if echo "$answer" | grep -iq "^y" ;then
log "Moving forward"
else
log "Error while starting the updated instance , please check logs. Now exiting from updating."
exit 0
fi
#updated_instance_url="http://$(hostname):$tmpJenkinsPort"
#res=`curl -I $updated_instance_url | grep HTTP/1.1 | awk {'print $2'}`
#if [ $res -ne 200 ]
#then
# echo "Not started updated imahge $res on $updated_instance_url"
#fi
log "Now stopping both containers (updated one and existing one) and start updated container"
echo -n "Press 'y' to stop both containers "
read answer
if echo "$answer" | grep -iq "^y" ;then
log "Copying current docker.yml and jenkins-master-config.yml to UPGRADE_JENKINS_PATH"
cp $MASTER_CONFIG_PATH/$MASTER_CONFIG_FILE $UPGRADE_JENKINS_PATH/conf/
cp $IMAGE_PATH/$DOCKER_COMPOSE_FILE $UPGRADE_JENKINS_PATH
log "Stopping $UPGRADE_JENKINS_PATH"
downContainer $UPGRADE_JENKINS_PATH
log "Stopping $IMAGE_PATH"
downContainer $IMAGE_PATH
fi
volumeToRemove="lhjenkins_myorg_extensions"
log "Removing volume :$volumeToRemove"
echo -n "Press 'y' to remove volume "
read answer
if echo "$answer" | grep -iq "^y" ;then
log "Removing"
removeVolume $volumeToRemove
fi
log "Restoring backup data from /data/$DATA_PATH_HOST_BACKUP :step 1-> moving existind jenkins_home to jenkins_home_old"
sudo mv $DATA_PATH_HOST/ $DATA_PATH_HOST_OLD
log "Restoring backup data from /data/$DATA_PATH_HOST_BACKUP :step 2-> moving updated $DATA_PATH_HOST_BACKUP to $DATA_PATH_HOST "
sudo mv $DATA_PATH_HOST_BACKUP/ $DATA_PATH_HOST
log "Backup current image from $IMAGE_PATH --> $IMAGE_PATH_OLD"
sudo mv $IMAGE_PATH $IMAGE_PATH_OLD
log "Storing image from $UPGRADE_JENKINS_PATH --> $IMAGE_PATH"
sudo mv $UPGRADE_JENKINS_PATH $IMAGE_PATH
#################################################
#echo -n "Enter Permenent port for updating Jenkins : (Default port no.8081, which can be used): "
# read permJenkinsPort
#echo -n "Enter Permenent port for updating nginx : (Default port no.443, which can be used): "
# read permNginxPort
#########################################################
cd $IMAGE_PATH
###############################################
#log "Upgraded Jenkins port to original is : $IMAGE_PATH "
#sed -i -e "s/$tmpJenkinsPort/$permJenkinsPort/" $DOCKER_COMPOSE_FILE
#sed -i -e "s/$tmpNginxPort/$permNginxPort/" $DOCKER_COMPOSE_FILE
###############################################
#sed -i -e "s/$docker_id_string/$DOCKER_GID/" $DOCKER_COMPOSE_FILE
log "Building image from $UPGRADE_JENKINS_PATH --> $IMAGE_PATH"
buildContainer $IMAGE_PATH
log "Starting image from $UPGRADE_JENKINS_PATH --> $IMAGE_PATH"
startContainer $IMAGE_PATH
log "Started $IMAGE_PATH"
chmod 777 manage-jenkins.sh
else
log "No container is running with name $CONTAINER_NAME : Starting new installation"
installContainer $URL
fi
exit 0
}
function stopContainer() {
echo "Stop container"
cd $1
docker stop $CONTAINER_NAME
}
function startContainer() {
echo "Start Container in $1"
cd $1
docker-compose up -d
}
function downContainer() {
cd $1
log "Removing container $CONTAINER_NAME" && \
docker-compose down &> /dev/null || true
}
function removeContainer() {
log "Removing previous container $CONTAINER_NAME" && \
docker rm -f $CONTAINER_NAME &> /dev/null || true
}
function help() {
echo "-----------------------------------------------------------------------"
echo " Available commands -"
echo "-----------------------------------------------------------------------"
echo -e -n "$BLUE"
echo " > install - To execute full install at once"
echo " > upgrade - To upgrade the certificates and master config files"
echo " > help - Display this help"
echo -e -n "$NORMAL"
echo "-----------------------------------------------------------------------"
}
[[ $# -eq 0 ]] && usage
# Execute getopt on the arguments passed to this program, identified by the special character $@
PARSED_OPTIONS=$(getopt -n "$0" -o hi:u:v --long "help,install:,upgrade:,verbose" -- "$@")
#Bad arguments, something has gone wrong with the getopt command.
if [ $? -ne 0 ];
then
exit 1
fi
# Necessary when using getopt.
eval set -- "$PARSED_OPTIONS"
# Now goes through all the options with a case and using shift to analyse 1 argument at a time.
#$1 identifies the first argument, and when we use shift we discard the first argument, so $2 becomes $1 and goes again through the case.
while true;
do
case "$1" in
-h|--help)
echo "usage $0 -h -i -u -v or $0 --help --install --upgrade --verbose"
help
shift;;
-i|--install)
echo "install"
GIT_URL=$2
echo "GITURL IS $GIT_URL"
installContainer
shift;;
-v|--verbose)
VERBOSE=true
shift;;
-u|--upgrade)
echo "upgrade"
GIT_URL=$2
upgradeContainer
# We need to take the option of the argument "three"
if [ -n "$2" ];
then
echo "Argument: $2"
fi
shift 2;;
--)
shift
break;;
esac
done
$*
This script will install Jenkins / update existing Jenkins from any repo. Say for example some one want to install Jenkins inside a docker, this script will pickup the docker-compose.yml and install docker from that.
This scripts can also be used to partial update like SSL certificates or any configuration files.
This script is customized for GIT, but this can be modified for any thing like SVN, GITLAB, CVS.
For example you have docker-compose.yml like below,
######################################################################
version: '2'
services:
nginx:
image: nginx:1.10
volumes:
- "./nginx:/etc/nginx/:ro" #Let it mount from install directory
ports:
- "443:443"
links:
- jenkins
jenkins:
build:
context: .
dockerfile: jenkins.df
args:
HOST_DOCKER_GID: ${HOST_DOCKER_GID}
restart: unless-stopped
ports:
- 8081:8080
env_file:
- jenkins-master.env
extra_hosts:
- "localbitbucket:10.0.2.2"
- "repo.staging.com:192.104.61.54"
- "sonar.myorg.com:10.128.136.94"
- "nexusrepo.myorg.com:10.128.136.94"
- "scm.myorg.com:10.128.136.175"
volumes:
#This is where all m2 artifacts are stored
- maven_repo:/var/.m2
#Using this as a named volume so it can be tracked, no need to mount it on host
- mycompany_extensions:/var/mycompany/:ro
#The configuration directory which customizes the installation, let it mount from install directory
- "./conf:/var/lhconf"
#This is the Jenkins Home location, defined by the base image
- home:/var/jenkins_home
- /var/run/docker.sock:/var/run/docker.sock
volumes:
mycompany_extensions:
home:
maven_repo:
#####################################################################
The log is self descriptive. Hope this helps UNIX admins to maintain their jenkins installation up to date.
Note: This script is fully customized for my pu
This scripts can also be used to partial update like SSL certificates or any configuration files.
This script is customized for GIT, but this can be modified for any thing like SVN, GITLAB, CVS.
For example you have docker-compose.yml like below,
######################################################################
version: '2'
services:
nginx:
image: nginx:1.10
volumes:
- "./nginx:/etc/nginx/:ro" #Let it mount from install directory
ports:
- "443:443"
links:
- jenkins
jenkins:
build:
context: .
dockerfile: jenkins.df
args:
HOST_DOCKER_GID: ${HOST_DOCKER_GID}
restart: unless-stopped
ports:
- 8081:8080
env_file:
- jenkins-master.env
extra_hosts:
- "localbitbucket:10.0.2.2"
- "repo.staging.com:192.104.61.54"
- "sonar.myorg.com:10.128.136.94"
- "nexusrepo.myorg.com:10.128.136.94"
- "scm.myorg.com:10.128.136.175"
volumes:
#This is where all m2 artifacts are stored
- maven_repo:/var/.m2
#Using this as a named volume so it can be tracked, no need to mount it on host
- mycompany_extensions:/var/mycompany/:ro
#The configuration directory which customizes the installation, let it mount from install directory
- "./conf:/var/lhconf"
#This is the Jenkins Home location, defined by the base image
- home:/var/jenkins_home
- /var/run/docker.sock:/var/run/docker.sock
volumes:
mycompany_extensions:
home:
maven_repo:
#####################################################################
The log is self descriptive. Hope this helps UNIX admins to maintain their jenkins installation up to date.
Note: This script is fully customized for my pu
Be the first to comment
You can use [html][/html], [css][/css], [php][/php] and more to embed the code. Urls are automatically hyperlinked. Line breaks and paragraphs are automatically generated.