#!/bin/bash
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.
#

set +eux

function install_docker_ce() {
    # installs and configures Docker CE
    [ -z "${DEBUG_INSTALL}" ] || DEBUG beginning of function
    echo "Installing Docker CE ..."
    sudo apt-get -qq update
    sudo apt-get install -y apt-transport-https ca-certificates software-properties-common
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=1 apt-key add -
    sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
    sudo apt-get -qq update
    sudo apt-get install -y docker-ce
#    echo "Reconfiguring Docker to use systemd as cgroup driver"
#    if [ ! -f /etc/docker/daemon.json ]; then
#        sudo bash -c "cat <<EOF > /etc/docker/daemon.json
#{
#  \"exec-opts\": [\"native.cgroupdriver=systemd\"],
#  \"log-driver\": \"json-file\",
#  \"log-opts\": {
#    \"max-size\": \"100m\"
#  },
#  \"storage-driver\": \"overlay2\"
#}
#EOF"
#    else
#        sudo sed -i "s|native.cgroupdriver=cgroupfs|native.cgroupdriver=systemd|" /etc/docker/daemon.json
#    fi
    echo "Adding user to group 'docker'"
    sudo groupadd -f docker
    sudo usermod -aG docker $USER
    sleep 2
    #sudo systemctl enable docker
    #sudo systemctl daemon-reload
    #sudo systemctl restart docker
    sudo service docker restart
    echo "... restarted Docker service"
    if [ -n "${DOCKER_PROXY_URL}" ]; then
        echo "Configuring docker proxy ..."
        if [ -f /etc/docker/daemon.json ]; then
            if grep -q registry-mirrors /etc/docker/daemon.json; then
                sudo sed -i "s|registry-mirrors.*|registry-mirrors\": [\"${DOCKER_PROXY_URL}\"] |" /etc/docker/daemon.json
            else
                sudo sed -i "s|^{|{\n  \"registry-mirrors\": [\"${DOCKER_PROXY_URL}\"],|" /etc/docker/daemon.json
            fi
        else
            sudo bash -c "cat << EOF > /etc/docker/daemon.json
{
  \"registry-mirrors\": [\"${DOCKER_PROXY_URL}\"]
}
EOF"
        fi
    fi
    if [ -n "${OSM_BEHIND_PROXY}" ] ; then
        if ! [ -f /etc/systemd/system/docker.service.d/http-proxy.conf ] ; then
            sudo mkdir -p /etc/systemd/system/docker.service.d
            cat << EOF | sudo tee -a /etc/systemd/system/docker.service.d/http-proxy.conf
[Service]
EOF
        fi
        [ -n "${HTTP_PROXY}" ] && sudo bash -c "cat <<EOF >> /etc/systemd/system/docker.service.d/http-proxy.conf
Environment=\"HTTP_PROXY=${HTTP_PROXY}\"
EOF"
        [ -n "${HTTPS_PROXY}" ] && sudo bash -c "cat <<EOF >> /etc/systemd/system/docker.service.d/http-proxy.conf
Environment=\"HTTPS_PROXY=${HTTPS_PROXY}\"
EOF"
        [ -n "${NO_PROXY}" ] && sudo bash -c "cat <<EOF >> /etc/systemd/system/docker.service.d/http-proxy.conf
Environment=\"NO_PROXY=${NO_PROXY}\"
EOF"
    fi
    if [ -n "${DOCKER_PROXY_URL}" ] || [ -n "${OSM_BEHIND_PROXY}" ] ; then
        #sudo systemctl enable docker
        sudo systemctl daemon-reload
        #sudo systemctl restart docker
        sudo service docker restart
        echo "... restarted Docker service again"
    fi
    [ -z "${DEBUG_INSTALL}" ] || ! echo "File: /etc/docker/daemon.json" || cat /etc/docker/daemon.json
    sg docker -c "docker version" || FATAL "Docker installation failed"
    echo "... Docker CE installation done"
    [ -z "${DEBUG_INSTALL}" ] || DEBUG end of function
    return 0
}

OSM_BEHIND_PROXY=""
DOCKER_PROXY_URL=""

while getopts ":D:p:-: P" o; do
    case "${o}" in
        D)
            OSM_DEVOPS="${OPTARG}"
            ;;
        p)
            DOCKER_PROXY_URL="${OPTARG}"
            ;;
        P)
            OSM_BEHIND_PROXY="y"
            ;;
        -)
            [ "${OPTARG}" == "debug" ] && DEBUG_INSTALL="y" && continue
            echo -e "Invalid option: '--$OPTARG'\n" >&2
            exit 1
            ;;
        :)
            echo "Option -$OPTARG requires an argument" >&2
            exit 1
            ;;
        \?)
            echo -e "Invalid option: '-$OPTARG'\n" >&2
            exit 1
            ;;
        *)
            exit 1
            ;;
    esac
done

source $OSM_DEVOPS/common/logging

echo "DEBUG_INSTALL=$DEBUG_INSTALL"
echo "DOCKER_PROXY_URL=$DOCKER_PROXY_URL"
echo "OSM_BEHIND_PROXY=$OSM_BEHIND_PROXY"
echo "USER=$USER"

install_docker_ce

