#!/bin/bash
#
#   NOT YET UPGRADED
#   docker-deploy - Deploy docker image to an instance
#
#   usage: docker-deploy
#
echo NOT YET UPGRADED
exit 255

IMAGE=${NAME}

UPART=$(echo ${PART} | tr '[:lower:]' '[:upper:]')
eval DEPLOY_VALIDATE=\${DEPLOY_${UPART}_VALIDATE}
eval DEPLOY_GROUP=\${DEPLOY_${UPART}_GROUP}
eval DEPLOY_COMMAND=\${DEPLOY_${UPART}_COMMAND}
eval DEPLOY_TAG=\${DEPLOY_${UPART}_TAG}

export AWS_ACCESS_KEY_ID=${DEPLOY_KEYS_AWS_ACCESS}
export AWS_SECRET_ACCESS_KEY=${DEPLOY_KEYS_AWS_SECRET}
export AWS_DEFAULT_REGION=${DEPLOY_AWS_REGION}

. $(dirname ${BASH_SOURCE[0]})/common

echo -e "\nDeploy container ${IMAGE}:${VERSION}\n"

getTargets() {
    local arn targets tcount tag value
    tag="${DEPLOY_TAG/=*}"
    value="${DEPLOY_TAG/*=}"
    aws ec2 describe-instances --filter "Name=tag:${tag},Values=${value}" \
        --output text --query 'Reservations[].Instances[].InstanceId'
    if [ $? != 0 ] ; then
        echo "Cannot describe instances"
        exit 255
    fi
}

getHost() {
    local target
    target=$1
    aws ec2 describe-instances --instance-ids ${target} --output text --query Reservations[0].Instances[0].PrivateIpAddress
}

pullImage() {
    local i
    i=0
    while [ $i -lt 12 ]
    do
        echo Pull image ${IMAGE}:${VERSION}
        docker pull ${IMAGE}:${VERSION} | \
            egrep -v 'Already exists|Pulling|Waiting|Verifying|Download complete|Pull complete|Digest:'
        if [ $? = 0 ] ; then
            return 0
        fi
        echo "Cannot pull image, retry in 5 seconds. (${i})"
        sleep 5
        i=$((i+1))
    done
    return 1
}

validate() {
    local host i
    host=$1
    echo "Validate application at http://${host}${DEPLOY_VALIDATE}"
    i=0
    while [ $i -lt 5 ]
    do
        code=$(curl -s -o /dev/null --retry 10 --retry-delay 1 --retry-max-time 15 \
            -I -w "%{http_code}" http://${host}${DEPLOY_VALIDATE})
        if [ "${code}" = 200 ] ; then
            echo "PASSED: Health check successful"
            return 0
        fi
        echo "Continue to wait for application, retry in 5 seconds. (${i})"
        sleep 5
        i=$((i+1))
    done
    echo "FAILED: Cannot validate application, status ${code}"
    return 1
}

dockerLogin

count=0
passed=0
for target in $(getTargets)
do
    fail=
    count=$((count+1))

    host=$(getHost ${target})
    export DOCKER_HOST=tcp://${host}:2375
    if ! pullImage ; then
        echo "Cannot pull ${IMAGE}:${VERSION} on ${target}"
        continue
    fi
    echo
    echo "----------------------------------------------------------------------------------"
    echo "Deploy to instance ${target} at ${host}"
    echo "----------------------------------------------------------------------------------"

    current=$(docker ps --filter ancestor=${IMAGE}:${VERSION} --format '{{.ID}}')
    if [ $? != 0 ] ; then
        echo "Cannot talk to docker on ${target}"
        fail=1
        continue
    fi
    if [ "${current}" != "" ] ; then
        echo "Target ${target} already running version ${IMAGE}:${VERSION}"
        if [ "${FORCE}" = "" ] ; then
            passed=$((passed+1))
            continue
        fi
    fi
    #
    #   Gracefully stop containers
    #
    containers=$(docker ps --filter "name=${NAME}" --format '{{.ID}}')
    if [ "${containers}" != "" ] ; then
        echo "Gracefully stop traffic on ${NAME}"

        echo "docker kill -s SIGQUIT ${NAME}"
        docker kill -s SIGQUIT ${NAME}

        echo "Stopping container ${NAME} ${containers}"
        docker stop ${NAME}
        if [ $? != 0 ] ; then
            echo "Cannot stop container ${container} on ${target}, continuing ..."
            # May not be running, continue
        fi
    fi
    #
    #   Remove existing containers
    #
    echo "Remove container ${NAME} ${containers}"
    docker rm ${NAME} >/dev/null 2>&1

    #
    #   Start new container
    #
    COMMAND=`echo ${DEPLOY_COMMAND} | sed "s/-d/-d -e HOST=${host}/"`
    echo "Start ${COMMAND}"
    ${COMMAND}
    if [ $? != 0 ] ; then
        echo "Cannot start container ${IMAGE}:${VERSION} on ${target}"
        echo "WARNING: target ${target} is not registered with load balancer, skip further deployments."
        fail=1
    fi
    #
    #   Validate
    #
    if [ "${fail}" = "" ] ; then
        echo -n "Started: "
        docker ps --filter "ancestor=${IMAGE}:${VERSION}" --format '{{.ID}}, {{.Image}}, {{.Status}}'
        if validate ${host} ; then
            passed=$((passed+1))
        fi
    fi
    dockerLogout
done

if [ "${passed}" != "${count}" ] ; then
    echo "FAILED, upgraded ${passed} instances of ${count} with ${IMAGE}:${VERSION}"
    exit 1
fi

echo -e "\nPASSED, all ${count} instances running ${IMAGE}:${VERSION}"

echo -e "\nRunning docker garbage collection"
docker system prune -f >/dev/null
DOCKER_HOST= docker system prune -f >/dev/null

)

exit 0
