docker脚本

#!/bin/bash

PROC="$0"
RUN_PATH=$(cd "$(dirname "$PROC")"; pwd)
PROJECT_NAME="gtms"
DATA_IMAGE_NAME="gtms-data"
DBSCALE_CHECKER="dbscale-checker"

# docker run parameters
LOCAL_IP="20.196.87.68"
PRIVILEGED="--privileged"
SSL="0"
PORT="19101"
REPO_DIR="/repo"
CONTAINER_NAME="portal"
ENV_FILE="env.conf"
DATADIR="/home/gtms/mysql"
MIGRATION_DIR="/home/gtms/migrations"
IMAGE_NAME="gtms"
MAX_OPEN_FILES=204800

function usage()
{
    cat << EOF
Manage services with docker.

Usage: $PROC [OPTIONS] COMMAND

Options:
  -s, --server ADDR    Local IP address
  -p, --port           published port; Default is 80
  -f, --nofile         ulimit max open files
  -v, --privileged     disable privileged
  -t, --datadir        data directory to store mysql data
      --ssl            use https or not; Default is http

Commands:
    up                 Create and start services
    down               Stop and remove services
    start              Start services
    stop               Stop services
    upgrade            Upgrade service with new image
    build              Build images
    export             Export tar.xz file of image
    import             Import tar.xz file of image in current directory
EOF
    exit 1
}

function _valid_ip_format()
{
    local ip_addr=$1
    if [[ $ip_addr =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
        return 0
    fi
    return 1
}

function _valid_local_ip()
{
    local ip_addr=$1
    which ifconfig >/dev/null 2>&1
    if [ $? -eq 0 ]; then
        ifconfig -a | grep inet | grep -v 127.0.0.1 | grep -v inet6 \
            | awk '{print $2}' | tr -d "addr:" | grep $ip_addr >/dev/null 2>&1
        return $?
    fi
    return 0
}

function _env_check()
{
    sysctl -w net.ipv4.ip_forward=1 >/dev/null 2>&1
    which getenforce >/dev/null 2>&1
    if [ $? -eq 0 ]; then
        getenforce | grep -iw "disabled" >/dev/null
        if [ $? -ne 0 ]; then
            echo "Please disable SELinux and then try again."
            exit 1
        fi
    fi

    ls $ENV_FILE >/dev/null 2>&1
    if [ $? -ne 0 ]; then
        echo "Cannot find env file"
        exit 1
    fi

    ls /repo >/dev/null 2>&1
    if [ $? -ne 0 ]; then
        echo "Cannot find /repo path"
        exit 1
    fi
}

function _prepare()
{
    container=$1
    running_count=$(docker ps -a --filter status=running | awk '{print $NF}' \
        | grep -w $container | wc -l)
    if [ $running_count -gt 0 ]; then
        return 0
    fi

    stopped_count=$(docker ps -a --filter status=exited | awk '{print $NF}' \
        | grep -w $container | wc -l)
    if [ $stopped_count -gt 0 ]; then
        docker start $container >/dev/null 2>&1
        return 0
    fi
    return 1
}

function _save_parameters()
{
    sed -i "/^LOCAL_IP/s/=.*/=\"$LOCAL_IP\"/" $RUN_PATH/run.sh
    sed -i "/^PRIVILEGED/s/=.*/=\"$PRIVILEGED\"/" $RUN_PATH/run.sh
    sed -i "/^SSL/s/=.*/=\"$SSL\"/" $RUN_PATH/run.sh
    sed -i "/^PORT/s/=.*/=\"$PORT\"/" $RUN_PATH/run.sh
}

function add_group()
{
    gid=$1
    gname=$2
    groupadd -g $gid $gname
}

function add_user()
{
    uid=$1
    gid=$2
    dir=$3
    shl=$4
    uname=$5
    comment=$6
    grep "^${uname}:" /etc/group >/dev/null 2>&1
    if [ $? -ne 0 ]; then
        add_group $gid $uname
        if [ $? -ne 0 ]; then
            return 1
        fi
    fi
    useradd -u $uid -g $gid -c "$comment" -d "$dir" -s "$shl" $uname >/dev/null 2>&1
    if [ $? -ne 0 ]; then
        return 1
    fi
}

function _mysql_up_check()
{
    uname="mysql"
    homedir="/var/lib/mysql"
    uid=27
    shell="/sbin/nologin"

    grep "^${uname}:" /etc/passwd >/dev/null 2>&1
    if [ $? -eq 0 ]; then
        grep "^${uname}:" /etc/passwd | grep -w 27 >/dev/null 2>&1
        if [ $? -ne 0 ]; then
            return 1
        fi
    else
        add_user $uid $uid $homedir $shell $uname "MySQL"
        if [ $? -ne 0 ]; then
            return 1
        fi
    fi
    if [ ! -d $DATADIR ]; then
        mkdir -p $DATADIR
    fi
    chown -R ${uname}:${uname} $DATADIR
    return 0
}

function _mysql_upgrade_check()
{
    if [ ! -d $DATADIR ]; then
        echo "MySQL datadir dose not exist, cannot upgrade."
        return 1
    fi

    ls $DATADIR/backend >/dev/null 2>&1
    if [ $? -ne 0 ]; then
        echo "MySQL datadir is empty, cannot upgrade."
        return 1
    fi

    uname="mysql"
    chown -R ${uname}:${uname} $DATADIR
    return 0
}

function _data_confirm()
{
    count=`ls $DATADIR | wc -w`
    if [ $count -gt 0 ]; then
        echo "MySQL data directory [$DATADIR] is not empty, please clear it and then try again."
        exit 0
    fi
}

function _wait_done()
{
    timeout=300
    begin_time=$(date +%s)
    while true; do
        docker exec -it portal systemctl -l status rc-local | grep "Started /etc/rc.d/rc.local Compatibility" >/dev/null 2>&1
        if [ $? -eq 0 ]; then
            echo " done"
            return
        fi
        sleep 2
        echo -n "."
        current_time=$(date +%s)
        if (($current_time - $begin_time > $timeout)); then
            echo " timeout!"
            return
        fi
    done
}

function up()
{

    image_count=$(docker images "$IMAGE_NAME" | wc -l)
    if [ $image_count -lt 2 ]; then
        echo "Docker images are not found."
        exit 1
    fi

    _mysql_up_check
    if [ $? -ne 0 ]; then
        echo "User \"mysql\" cannot be created correctly."
        exit 2
    fi

    if [ ! "X$1" = "Xstart" ]; then
        _data_confirm
    fi

    echo -n "Starting (This will take a few minutes, please wait) ..."
    _prepare $CONTAINER_NAME
    if [ $? -eq 0 ]; then
        echo "done"
        return
    fi

    _save_parameters

    ret=$(docker run --detach $PRIVILEGED -e SERVER=$LOCAL_IP \
        -e SSL=$SSL -p $PORT:80 -v /repo:$REPO_DIR \
        -e SERVICE_PORT=$PORT \
        --name $CONTAINER_NAME --env-file $ENV_FILE \
        --volume $DATADIR:/var/lib/mysql \
        --volume $MIGRATION_DIR:/migrations \
        $IMAGE_NAME 2>&1)
    if [ $? -ne 0 ]; then
        echo " fail"
        echo $ret
    else
        _wait_done
    fi
}

function down()
{
    while true; do
        echo -n "Remove the container? [yes/No] "
        read answer
        case $answer in
            [yY][eE][sS]|[yY])
                break
                ;;
            [nN][oO]|[nN])
                return
                ;;
            "")
                return
                ;;
            *)
                continue
                ;;
        esac
    done
    stop
    [ $? -ne 0 ] && return

    echo -n "Removing $CONTAINER_NAME ... "
    ret=$(docker rm $CONTAINER_NAME 2>&1)
    if [ $? -ne 0 ]; then
        echo "fail"
        echo $ret
    else
        echo "done"
    fi
}

function start()
{
    count=$(docker ps -a | awk '{print $NF}' | grep -w $CONTAINER_NAME | wc -l)
    if [ $count -lt 1 ]; then
        echo "GTMS portal has not been created, exit."
        return 1
    fi
    up start
}

function stop()
{
    count=$(docker ps -a --filter status=running | awk '{print $NF}' \
        | grep -w $CONTAINER_NAME | wc -l)
    if [ $count -gt 0 ]; then
        echo -n "Stoping $CONTAINER_NAME ... "
        ret=$(docker stop $CONTAINER_NAME 2>&1)
        if [ $? -ne 0 ]; then
            echo "fail"
            echo $ret
        else
            echo "done"
        fi
    fi
}

function upgrade()
{
    while true; do
        echo -n "Stop the old service and upgrade to the new one? [yes/No] "
        read answer
        case $answer in
            [yY][eE][sS]|[yY])
                break
                ;;
            [nN][oO]|[nN])
                return
                ;;
            "")
                return
                ;;
            *)
                continue
                ;;
        esac
    done
    stop
    [ $? -ne 0 ] && return

    echo -n "Removing the old service ... "
    ret=$(docker rm $CONTAINER_NAME 2>&1)
    if [ $? -ne 0 ]; then
        echo "fail"
        echo $ret
        return
    fi

    _mysql_upgrade_check
    if [ $? -ne 0 ]; then
        exit 2
    fi

    echo -n "Upgrading (This will take a few minutes, please wait) ..."
    ret=$(docker run --detach $PRIVILEGED -e SERVER=$LOCAL_IP \
        -e UPGRADE=1 -e SSL=$SSL -p $PORT:80 -v /repo:$REPO_DIR \
        -e SERVICE_PORT=$PORT \
        --name $CONTAINER_NAME --env-file $ENV_FILE \
        --volume $DATADIR:/var/lib/mysql \
        --volume $MIGRATION_DIR:/migrations \
        $IMAGE_NAME 2>&1)
    if [ $? -ne 0 ]; then
        echo " fail"
        echo $ret
    else
        _wait_done
    fi
}

function build()
{
    ls $DBSCALE_CHECKER >/dev/null 2>&1
    if [ $? -ne 0 ]; then
        echo
        echo "\"$DBSCALE_CHECKER\" tool does not exist, please put it in this directory."
        echo
        echo "================= How to build $DBSCALE_CHECKER ==================="
        echo "# git clone git@gitlab.greatopensource.com:dbscale/dbscale-checker.git"
        echo "# cd dbscale-checker"
        echo "# go build"
        echo "=================================================================="
        echo
        echo "To make this build successfu, we create a fake dbscale-checker."
        touch dbscale-checker
        chmod +x dbscale-checker
    fi

    rm -rf $RUN_PATH/$PROJECT_NAME
    mkdir -p $RUN_PATH/$PROJECT_NAME
    cp -r ../manage.py $RUN_PATH/$PROJECT_NAME/
    cp -r ../backend $RUN_PATH/$PROJECT_NAME/
    cp -r ../frontend $RUN_PATH/$PROJECT_NAME/
    cp ../requirements.txt $RUN_PATH/$PROJECT_NAME/
    /bin/cp -f ../tools/celery/celery $RUN_PATH/files/
    /bin/cp -f ../tools/celery/celery.service $RUN_PATH/files/
    /bin/cp -f ../tools/httpd/backend.conf $RUN_PATH/files/
    /bin/cp -f ../tools/httpd/backend-ssl.conf $RUN_PATH/files/
    echo -n "Compiling ... "
    npm --prefix $RUN_PATH/$PROJECT_NAME/frontend install
    npm run --prefix $RUN_PATH/$PROJECT_NAME/frontend build
    echo "done"
    rm -rf $RUN_PATH/$PROJECT_NAME/frontend/node_modules
    docker build -t $IMAGE_NAME $RUN_PATH
    if [ $? -ne 0 ]; then
        echo "Failed to build image."
    else
        echo "done"
    fi

    rm -rf $RUN_PATH/$PROJECT_NAME
    rm -f $RUN_PATH/files/celery $RUN_PATH/files/celery.service \
        $RUN_PATH/files/backend.conf $RUN_PATH/files/backend-ssl.conf
}

function export()
{
    echo -n "Saving $IMAGE_NAME ... "
    ret=$(docker save $IMAGE_NAME | xz > $RUN_PATH/$IMAGE_NAME.tar.xz 2>&1)
    if [ $? -ne 0 ]; then
        echo "fail"
        echo $ret
    else
        echo "done"
    fi
}

function import()
{
    echo -n "Loading $IMAGE_NAME ... "
    ret=$(docker load -i ./$IMAGE_NAME.tar.xz 2>&1)
    if [ $? -ne 0 ]; then
        echo "fail"
        echo $ret
    fi
    echo "done"
}

ARGS=$(getopt -a -o p:vs:f:t: -l privileged,port:,server:,nofile:,ssl:,datadir:,help -- "$@" 2>/dev/null)
if [ $? -ne 0 ]; then
    usage
fi
eval set -- "${ARGS}"

while true; do
    case "$1" in
        -s|--server)
            LOCAL_IP=$2
            shift
            ;;
        -f|--nofile)
            MAX_OPEN_FILES=$2
            shift
            ;;
        -p|--port)
            PORT=$2
            shift
            ;;
        -v|--privileged)
            PRIVILEGED=""
            ;;
        --ssl)
            SSL=1
            ;;
        -t|--datadir)
            DATADIR="$2"
            shift
            ;;
        -h|--help)
            usage
            ;;
        --)
            shift
            break
            ;;
        *)
            usage
            ;;
    esac
    shift
done

if [ "X$1" = "X" ]; then
    usage
fi

_env_check

case "$1" in
    up)
        if [ "X$LOCAL_IP" = "X" ]; then
            usage
        fi
        _valid_ip_format $LOCAL_IP
        if [ $? -ne 0 ]; then
            echo "Not valid IP address format: $LOCAL_IP"
            exit 1
        fi
        _valid_local_ip $LOCAL_IP
        if [ $? -ne 0 ]; then
            echo "Not valid local IP address: $LOCAL_IP"
            exit 1
        fi
        up
        ;;
    down)
        down
        ;;
    start)
        start
        ;;
    stop)
        stop
        ;;
    upgrade)
        upgrade
        ;;
    build)
        build
        ;;
    export)
        export
        ;;
    import)
        import
        ;;
    *)
        usage
        ;;
esac

exit

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凤舞飘伶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值