Skip to content

Instantly share code, notes, and snippets.

@perfecto25
Last active April 23, 2021 03:45
Embed
What would you like to do?
Bash examples - shows use of key=val parameter passing, error checking, functions, etc
#!/bin/bash
#set -x
# source common function and variables
source "$(readlink -f $0 | xargs dirname)/shared"
REPO_DIR="${HOME}/NewDeploy/Repositories/Config_$(date +%Y%m%d%H%M%S)"
# check if another instance of this deployment is in progress
check_another_instance $(basename -- "$0")
start_release() {
confirm_start
[ ! -d "${REPO_DIR}" ] && { echo -e "${b_red}No repository present, exiting...${clear}"; exit 1; }
git -C "${REPO_DIR}" checkout -q "${BRANCH}"
[ ! $? -eq 0 ] && { echo -e "${b_red}Error checking out branch ${BRANCH}, exiting${clear}"; exit 1; }
br=$(git -C "${REPO_DIR}" branch -v | grep '\*' | cut -d ' ' -f2)
[ "${br}" != "${BRANCH}" ] && { echo -e "${b_red}Branch mis-match exiting...${clear}"; exit 1; }
IFS=,
for TARGET in $MACHINES
do
TARGET=$(echo "${TARGET}" | xargs echo -n)
[ ! -d "${REPO_DIR}/host_configs/${TARGET}" ] && { echo -e "${b_red}[$(date)] no config path $REPO_DIR}/host_configs/${TARGET} exists, skipping...${clear}"; continue ; }
# get Env of host if DEPLOY_ENV is not provided
if [ -z "${DEPLOY_ENV}" ]
then
get_target_env "${TARGET}"
else
CFG_ENV="${DEPLOY_ENV}"
fi
# go through common files and copy to the right place
find ${REPO_DIR}/common/${CFG_ENV}/* -prune -type d | while IFS= read -r d; do
folder=${d##*/}
rsync -avz --delete $d/* ${TARGET}:./deploy/config_versions/config_${COMMIT}/$folder/
[ ! $? -eq 0 ] && { echo -e "${b_red}Error Rsync commit folder to ${TARGET}, continuing to next host ${clear}"; continue ;}
done
ssh $TARGET "rm -f config; ln -sfn deploy/config_versions/config_${COMMIT} config;"
[ ! $? -eq 0 ] && { echo -e "${b_red}Error removing config on ${TARGET}, continuing to next host ${clear}"; continue ;}
echo -e "${green}Deployment on host $TARGET is complete${clear}"
done
}
get_params "${@}"
# check # of given params
[ "$#" -lt 2 ] && { print_usage; exit 1; }
start_message "Config"
echo -e "${green}\nRemoving current Config Dir and git cloning Config repo..${clear}\n\n"
rm -rf "${REPO_DIR:?}"
COMMIT=$(git -C "${REPO_DIR}" rev-parse --short=7 origin/"${BRANCH}")
[ ! $? -eq 0 ] && { echo -e "${b_red}Error getting the Commit number from repository, exiting${clear}"; exit 1; }
# get list of targets from passed parameters
[ -n "${HOSTS}" ] && { MACHINES="${HOSTS}"; }
[ -n "${DEPLOY_ENV}" ] && { MACHINES="${hostlist[$DEPLOY_ENV]}"; }
if [ -n "${MACHINES}" ]; then start_release; else echo -e "${b_red}No machines provided${clear}"; fi
exit 0;
#!/bin/bash
# terminal colors
red="\e[0;91m"
green="\e[0;92m"
white="\e[0;97m"
bold="\e[1m"
clear="\e[0m"
b_red="${red}${bold}"
b_green="${green}${bold}"
b_white="${white}${bold}"
# Host list per Environment
declare -A hostlist
hostlist[PROD]="prod@web1, prod@web2"
hostlist[SIM]="sim@web4, sim@web6"
hostlist[QA]="qa@web9"
get_params(){
PARAMS=""
while (( "$#" )); do
case "$1" in
## --silent NO PROMPT
-s|--silent)
SILENT=true
shift
;;
## BRANCH
-b|--branch)
if [ -n "${2}" ] && [ ${2:0:1} != "-" ]; then
BRANCH=$2
shift 2
else
echo -e "${b_red}Error: Argument for $1 is missing${clear}" >&2
exit 1
fi
;;
## Deploy ENV
-e|--environment)
if [ -n "${2}" ] && [ ${2:0:1} != "-" ]; then
DEPLOY_ENV=${2}
# set environment to uppercase
DEPLOY_ENV="${DEPLOY_ENV^^}"
shift 2
else
echo -e "${b_red}Error: Argument for $1 is missing${clear}" >&2
exit 1
fi
;;
## specific Hostnames
-h|--hosts)
if [ -n "${2}" ] && [ ${2:0:1} != "-" ]; then
HOSTS=$2
shift 2
else
echo -e "${b_red}Error: Argument for $1 is missing${clear}" >&2
exit 1
fi
;;
-*|--*=) # unsupported flags
echo -e "${b_red}Error: Unsupported flag $1 ${clear}" >&2
print_usage
exit 1
;;
*) # preserve positional arguments
PARAMS="$PARAMS $1"
shift
;;
esac
done
# set positional arguments in their proper place
eval set -- "${PARAMS}"
# sanity checks
[[ -n "${HOSTS}" && -n "${DEPLOY_ENV}" ]] && { echo -e "${b_red}Cannot have both Environment and Hosts, provide one or the other. exiting..${clear}"; exit 1; }
[[ -z "${HOSTS}" && -z "${DEPLOY_ENV}" ]] && { echo -e "${b_red}You must provide either an Environment or a Host list '--environment PROD or --hosts prod@qweb1,prod@qweb2'. exiting..${clear}"; exit 1; }
[ -z "${BRANCH}" ] && { echo -e "${b_red}You must provide a Branch to pull for this repository '--branch QA'. exiting..${clear}"; exit 1; }
}
print_usage() {
printf '%.s-' {1..100}
echo -e "\nusage: $0 --branch [QA|master] --environment [PROD|SIM|QA|prod@web1 ...] <optional: --silent (no confirmation prompt)> "
echo -e "\nparameter options: \n -b | --branch\n -e | --environment\n -h | --hosts [comma separted hostlist, cannot be used along with Environment]\n -s | --silent (boolean)"
echo -e "\n${b_white}Example: $0 --branch QA --environment SIM --silent${clear}"
echo -e "${b_white}Example: $0 --branch QA --hosts prod@web1,sim@web5${clear}\n"
}
get_target_env() {
for ENV in "${!hostlist[@]}"
do
hosts=${hostlist[$ENV]}
IFS=,
for host in ${hosts}
do
host=$(echo $host | xargs echo -n)
if [ "${host}" == "${1}" ]
then
CFG_ENV=$ENV
break
fi
done
done
}
confirm_start() {
if [[ $SILENT = true ]]
then
echo -e "\n${green}--silent provided. skipping confirmation${clear}\n"
else
echo -e "\n\nAre you ready to release ${b_green}${BRANCH}${clear} branch, commit number ${b_green}${COMMIT}${clear} to the following machine(s) ${b_green}${MACHINES}${clear}\n\nType ${b_white}y${clear} to proceed\n"
read -r resp
[ "${resp}" != "y" ] && { echo -e "${b_red}Not confirmed, exiting..${clear}"; exit 1; }
fi
}
start_message() {
if [[ $SILENT = true ]]
then
echo -e "\n${green}--silent provided. skipping confirmation${clear}\n"
else
echo -e "\n\n[$(date)]\n\nThis will deploy ${b_white}$1${clear} to hosts\nType ${b_white}y${clear} to proceed\n"
read -r resp
[ "${resp}" != "y" ] && { echo -e "${b_red}Not confirmed, exiting..${clear}"; exit 1; }
fi
}
check_another_instance() {
if pidof -x "${1}" -o $$ >/dev/null;then
echo -e "${b_red}An another instance of this script is already running, please clear all the sessions of this script before starting a new session${clear}"
exit 1
fi
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment