通过Git WebHooks+脚本实现自动更新发布代码之Shell脚本(二)
#!/usr/bin/env bash# Public header
# =============================================================================================================================
# Check that we are root ... so non-root users stop here
[`id -u` -eq"0" ] ||exit 4
# resolve links - $0 may be a symbolic link
PRG="$0"
while [ -h "$PRG" ]; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`/"$link"
fi
done
# Get standard environment variables
PRGDIR=`dirname "$PRG"`
# echo color function
function cecho {
# Usage:
# cecho -red sometext #Error, Failed
# cecho -green sometext # Success
# cecho -yellow sometext# Warning
# cecho -blue sometext # Debug
# cecho -white sometext # info
# cecho -n # new line
# end
while [ "$1" ]; do
case "$1" in
-normal) color="\033[00m" ;;
# -black) color="\033[30;01m" ;;
-red) color="\033[31;01m" ;;
-green) color="\033[32;01m" ;;
-yellow) color="\033[33;01m" ;;
-blue) color="\033[34;01m" ;;
# -magenta) color="\033[35;01m" ;;
# -cyan) color="\033[36;01m" ;;
-white) color="\033[37;01m" ;;
-n) one_line=1; shift ; continue ;;
*) echo -n "$1"; shift ; continue ;;
esac
shift
echo -en "$color"
echo -en "$1"
echo -en "\033[00m"
shift
done
if [ ! $one_line ]; then
echo
fi
}
# end echo color function
# echo color function, smarter
function echo_r () {
#Error, Failed
[ $# -ne 1 ] && return 0
echo -e "\033[31m$1\033[0m"
}
function echo_g () {
# Success
[ $# -ne 1 ] && return 0
echo -e "\033[32m$1\033[0m"
}
function echo_y () {
# Warning
[ $# -ne 1 ] && return 0
echo -e "\033[33m$1\033[0m"
}
function echo_b () {\
# Debug
[ $# -ne 1 ] && return 0
echo -e "\033[34m$1\033[0m"
}
# end echo color function, smarter
WORKDIR=$PRGDIR
# end public header
# =============================================================================================================================
# begin customization for special case
# project directory to waiting for update
config_project_dir=example_projects
# resources directory which contain config file and update files
config_resources_dir=example_resources
config_config_file=$config_resources_dir/config_update.conf
config_backup_dir=example_backup_dir
# log options
config_this_logfile=$WORKDIR/.update_backup.log
# end
function check_dependencies(){
echo_b "Checking dependencies for update procedure. "
if [ -z $config_project_dir ]; then
echo_r "Error: config_project_dir is undefined! "
exit 1
fi
if [ ! -d $config_resources_dir ]; then
echo_r "Error: config_resources_dir is undefined! "
fi
if [ -z $config_config_file ]; then
echo_r "Error: config_config_file is undefined! "
exit 1
fi
left_disk_space=`df $config_backup_dir | tail -n1 | awk '{print $(NF -2)}'`
# set 2097152 to project directory size
if [ -z $config_project_dir -o ! -d $config_project_dir ]; then
project_file_space_usage=$(du -s /root | awk '{print $1}')
required_size=$(expr $project_file_space_usage \* 2)
fi
if [[ $left_disk_space -lt $required_size ]]; then
echo_r "Disk space of $config_backup_dir is smaller than $required_size. "
exit 1
fi
echo_g "All required dependencies check pass! "
}
function test_self(){
# How to use this function:
# First execute "$0 test_self", then execute "$0 update"
echo_b "Test purpose begin. "
# clean old test example
echo_b "Clean old test example. "
[ -d $WORKDIR/example_projects ] && rm -rf $WORKDIR/example_projects
[ -d $WORKDIR/example_resources ] && rm -rf $WORKDIR/example_resources
[ -d $WORKDIR/example_backup_dir ] && rm -rf $WORKDIR/example_backup_dir
# make an example project directory
if [ -z $config_project_dir -o ! -d $config_project_dir ]; then
echo_b "Making an example project directory. "
mkdir $WORKDIR/example_projects
config_project_dir=example_projects
# Padding example_projects directory
touch $config_project_dir/example_filename
mkdir $config_project_dir/example_directory
fi
# make an example resources directory
if [ -z $config_resources_dir -o ! -d $config_resources_dir ]; then
echo_b "Making an example resources directory. "
mkdir$WORKDIR/example_resources
config_resources_dir=$WORKDIR/example_resources
fi
# make an example config_update.conf
if [ -z $config_config_file -o ! -f $config_config_file ]; then
echo_b "Making an example config_update.conf file. "
touch $config_resources_dir/config_update.conf
config_config_file=$config_resources_dir/config_update.conf
# Padding config_update.conf file
cat >$config_config_file &1 ; then
# do_cp
do_cp $names
elif grep $names $config_config_file | grep update >/dev/null 2>&1 ;then
# do_cp
do_cp $names
elif grep $names $config_config_file | grep remove >/dev/null 2>&1 ;then
# do_remove
do_remove $names
else
exit 1
fi
done
echo_g "Files operations finished successfully! "
}
# TODO
# no example here, please refer to your real production environment
#function do_clean_cache(){}
#function do_restart_service(){}
function service_operation(){
echo_b "Begin services operations"
configs=`awk -F '[ ]+' '/^config/ { print $2 }' $config_config_file`
for names in $configs; do
if grep $names $config_config_file | grep cleancache | grep enable >/dev/null 2>&1 ; then
# do_clean_cache
echo do_clean_cache $names
elif grep $names $config_config_file | grep cleancache | grep disable >/dev/null 2>&1 ; then
# echo a warning
echo_y "Warning: disable action is NOT recommended, $names skipped."
elif grep $names $config_config_file | grep restartservice | grep enable >/dev/null 2>&1 ; then
# do_restart_service
echo do_restart_service $names
elif grep $names $config_config_file | grep restartservice | grep disable >/dev/null 2>&1 ; then
# echo a warning
echo_y "Warning: disable action is NOT recommended, $names skipped."
else
echo $names
echo_r "Error: Wrong config file $config_config_file, please check it. "
exit 1
fi
done
echo_g "Services operations finished successfully! "
}
function check_remote_server_status(){
# TODO
# for remote call
echo
}
function backup(){
echo_b "Backup files before update"
# backup_filename=backup_$(date +%F_%H_%M_%S).tgz
backup_filename=backup_$(date +%Y_%m_%d_%H_%M_%S).tgz
tar --create --gzip --absolute-names --file=$config_backup_dir/$backup_filename $config_project_dir
if [ $? -eq 0 ]; then
echo_g "Backup files before update finished and successfully! "
echo "restore_least_file=$config_backup_dir/$backup_filename" > $config_this_logfile
else
echo_r "Error: Backup files before update failed! Please alter to administrator. "
exit 1
fi
}
function restore(){
echo_b "Restore files for rollback"
if [ -f $config_this_logfile ]; then
. $config_this_logfile
fi
restore_least_file=${restore_least_file:-1}
if [ -s $restore_least_file ]; then
tar -C $config_project_dir/.. -zxf $restore_least_file
if [ $? -eq 0 ]; then
echo_g "Restore files finished and successfully! "
else
echo_r "Restore files failed! Please alter to administrator. "
exit 1
fi
else
echo_r "Can NOT find backup files in $config_backup_dir, backup once indeed? "
exit 1
fi
}
# TODO
# for remote call
# function remote_backup(){}
# function remote_restore(){}
function rollback(){
echo_b "rollback after update failed"
$0 restore
echo_g "rollback finished and successfully! "
}
function update_status(){
# TODO
# no example here, please refer to your real production environment
# check if update success or failure
echo update_status
# if failure, do rollback action
# service_operation
}
function update(){
# TODO
# thinking carefully with all exit status, which is not good for automatic update
check_dependencies
backup
file_operation
service_operation
update_status
}
function destroy() {
# echo a warning message
echo_y "Warning: This action will destroy all this project, and this is unrecoverable! "
answer="n"
echo_y "Do you want to destroy this project? "
read -p "(Default no,if you want please input: y ,if not please press the enter button):" answer
case "$answer" in
y|Y|Yes|YES|yes|yES|yEs|YeS|yeS )
# delete all file expect for this script self
# find: warning: Unix filenames usually don't contain slashes (though pathnames do).That means that '-name `./deploy.sh'' will probably evaluate to false all the time on this system.You might find the '-wholename' test more useful, or perhaps '-samefile'.Alternatively, if you are using GNU grep, you could use 'find ... -print0 | grep -FzZ `./deploy.sh''.
# echo $WORKDIR/
#find -L $WORKDIR -type f ! -name "$(basename $0)" -exec ls --color=auto -al {} \;
# find -L . -type f ! -name "deploy.sh" -exec ls --color=auto -al {} \;
# find -L . -type d -exec ls --color=auto -al {} \;
# find -L ./ -maxdepth 1 ! -name "deploy.sh" ! -wholename "./"
# ls | grep -v "fielname" |xargs rm -rf
find -L $WORKDIR -maxdepth 1 ! -name "$(basename $0)" ! -wholename "$WORKDIR"-exec rm -rf {} \;
if [ $? -eq 0 ];then
echo_g "Destory this project successfully! Now will exit with status 0. "
exit 0
else
echo_r "Error: something go wrong! Please check or alter to Admin user! "
exit 1
fi
;;
n|N|No|NO|no|nO)
echo_g "destroy action is cancel"
exit 0
;;
*)
echo_r "Are you kidding me? You are a bad kid! "
exit 1
;;
esac
}
case $1 in
update)
update
;;
backup)
backup
;;
restore)
restore
;;
rollback)
rollback
;;
destroy)
destroy
;;
help|*)
echo "Usage: $0 {update|backup|restore|rollback|destroy} with $0 itself"
exit 1
;;
esac
# This is not essential with 'case .. esac' handled no args excutions
# replace "exit 0" with ":"
#exit 0
:
页:
[1]