Git WebHooks + 스 크 립 트 를 통 해 발표 코드 의 Shell 스 크 립 트 를 자동 으로 업데이트 합 니 다 (2)

이전 'Git WebHooks + 스 크 립 트 를 통 해 게시 코드 를 자동 으로 업데이트 합 니 다' 라 는 솔 루 션 에 따라 작 성 된 셸 스 크 립 트 입 니 다. 이 스 크 립 트 는 패 치 파일 을 업데이트 하 는 데 사 용 됩 니 다. 예 를 들 어 프로젝트 에 있 는 파일 을 추가 (add), 삭제 (remove), 수정 (update) 하고 캐 시 지우 기, 서비스 재 부팅 등 과 관련 된 명령 을 수행 합 니 다.
  이 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--

    좋은 웹페이지 즐겨찾기