Git WebHooks + 스 크 립 트 를 통 해 발표 코드 의 Shell 스 크 립 트 를 자동 으로 업데이트 합 니 다 (2)
이 Shell 스 크 립 트 는 현재 로 컬 에서 실행 되도록 설계 되 어 있 으 며 분포 식 으로 실행 하기에 적합 하지 않 습 니 다.즉, 이 스 크 립 트 는 프로젝트 와 같은 기계 에 있 는 것 이 좋 습 니 다. 이 결함 은 스 크 립 트 에 표시 되 어 있 습 니 다. 스 크 립 트 의 여러 TODO 를 참조 하 십시오.
스 크 립 트 가 완 료 된 작업:
이 스 크 립 트 는 앞에서 언급 한 배치 스 크 립 트 와 함께 수정 할 수 있 습 니 다.후기 개선 은 github 에 주목 하 세 요.
스 크 립 트 는 다음 과 같 습 니 다:
#!/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 <<eof
file filename1 add
file filename2 remove
file filename3 update
file filename4 add
config cleancachea enable
config cleancacheb disable
config restartservicea enable
config restartserviceb disable
target 192.168.1.241 ssh
target 192.168.1.242 ssh
eof
files=`awk -F '[ ]+' '/^file/ { print $2 }' $config_config_file`
echo_b "Making an example files(patches) refer to $config_config_file. "
for names in $files; do
[ ! -f $config_resources_dir/$names ] && touch $config_resources_dir/$names
done
fi
# TODO
# test network and ssh for remote call
# make an example backup directory
if [ -z $config_backup_dir -o ! -d $config_backup_dir ]; then
echo_b "Making an example backup directory"
mkdir $WORKDIR/example_backup_dir
config_backup_dir=$WORKDIR/example_backup_dir
fi
echo_g "Test purpose is finished and successfully! "
}
#function parse_config_file(){
# # unbanned action
# files=`awk -F '[ ]+' '/^file/ { print $2 }' $config_config_file`
# configs=`awk -F '[ ]+' '/^config/ { print $2 }' $config_config_file`
#}
function do_cp(){
SOURCE=$1
# echo "var: $SOURCE"
# echo "result: $(dirname $SOURCE | grep ^\/ | awk '{print substr($1,1,1)}' )"
# exit 0
if test "$(dirname $SOURCE | grep ^\/ | awk '{print substr($1,1,1)}')" == ""; then
echo_b "Execute copy action. "
DEST=$config_project_dir/$SOURCE
\cp $SOURCE $DEST
else
echo_y "Self test purpose found! But we can do this action! "
[ ! -d $config_project_dir/$(dirname $SOURCE) ] && mkdir -p $config_project_dir/$(dirname $SOURCE)
\cp $SOURCE $config_project_dir/$(dirname $SOURCE)
fi
}
function do_remove(){
FILE=$1
if test "$(dirname $SOURCE | awk -F '/' '{print $1}')" == ""; then
rm -rf $config_project_dir/$FILE
else
echo_y "Self test purpose found! This can NOT do remove action on self test purpose, skipping..."
return
fi
}
# TODO
# for remote call
#function do_remote_cp(){}
#function fo_remote_remove(){}
function file_operation(){
echo_b "Begin files operations"
files=`awk -F '[ ]+' '/^file/ { print $2 }' $config_config_file`
for names in $files; do
if grep $names $config_config_file | grep add >/dev/null 2>&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
:
tag: 셸 스 크 립 트 자동 업데이트, 자동화 배치 스 크 립 트, 셸 배치 스 크 립 트, 스 크 립 트 자동 업데이트 및 스크롤 백, 자동화 배치 셸 스 크 립 트 인 스 턴 스
--end--
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Git WebHooks + 스 크 립 트 를 통 해 발표 코드 의 셸 스 크 립 트 를 자동 으로 업데이트 합 니 다.이 글 은 'Git WebHooks + 스 크 립 트 를 통 해 게시 코드 를 자동 으로 업데이트 합 니 다' 라 는 내용 으로 게시 코드 를 자동 으로 업데이트 하 는 스 크 립 트 작성 방향 을 제공 합 니 다....
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.