#!/bin/sh
set -eu

fail() {
    printf 'offbox: %s\n  Fix: Check the privileged container settings and dockerd log.\n' "$1" >&2
    if [ -f /var/log/dockerd.log ]; then
        tail -n 40 /var/log/dockerd.log >&2
    fi
    exit 1
}

# Invoked by TERM/INT traps while waiting for dockerd.
# shellcheck disable=SC2317,SC2329
stop_daemon() {
    trap '' TERM INT
    rm -f /run/offbox/ready
    if [ -n "$daemon_pid" ]; then
        kill -TERM "$daemon_pid" 2>/dev/null || :
        wait "$daemon_pid" || :
    fi
    exit 0
}

daemon_pid=
trap 'stop_daemon' TERM INT

install -d -m 0755 /etc/docker /run/offbox
install -d -m 0700 -o dev -g dev /run/offbox/exec
rm -f /run/offbox/ready /var/run/docker.pid /var/run/docker.sock
rm -rf /var/run/docker
cat > /etc/docker/daemon.json <<'JSON'
{"data-root":"/var/lib/docker","storage-driver":"overlay2","bip":"172.31.0.1/24","default-address-pools":[{"base":"172.30.0.0/16","size":24}],"log-driver":"local"}
JSON

if [ -f /sys/fs/cgroup/cgroup.controllers ]; then
    mkdir -p /sys/fs/cgroup/init || fail 'Cannot create the nested cgroup.'
    processes=$(cat /sys/fs/cgroup/cgroup.procs)
    for pid in $processes; do
        if ! printf '%s\n' "$pid" > /sys/fs/cgroup/init/cgroup.procs; then
            [ ! -e "/proc/$pid" ] || fail 'Cannot move processes into the nested cgroup.'
        fi
    done
    controllers=$(cat /sys/fs/cgroup/cgroup.controllers)
    for controller in $controllers; do
        case "$controller" in
            cpu|memory|pids|io)
                printf '+%s\n' "$controller" > /sys/fs/cgroup/cgroup.subtree_control || fail 'Cannot enable nested cgroup controllers.'
                ;;
        esac
    done
fi

log_fifo=/run/offbox/dockerd.log.fifo
rm -f "$log_fifo"
mkfifo -m 0600 "$log_fifo"
awk -v log_file=/var/log/dockerd.log -v limit=10485760 '
    { print > log_file; fflush(log_file); size += length($0) + 1 }
    size >= limit { close(log_file); system("mv -f " log_file " " log_file ".1"); size = 0 }
' < "$log_fifo" &
dockerd --host=unix:///var/run/docker.sock > "$log_fifo" 2>&1 &
daemon_pid=$!
deadline=$(($(date +%s) + 60))
while [ "$(date +%s)" -lt "$deadline" ]; do
    kill -0 "$daemon_pid" 2>/dev/null || fail 'The nested Docker daemon exited during startup.'
    if [ -S /var/run/docker.sock ] && timeout 1 docker --host=unix:///var/run/docker.sock info >/dev/null 2>&1; then
        touch /run/offbox/ready
        set +e
        wait "$daemon_pid"
        status=$?
        rm -f /run/offbox/ready
        exit "$status"
    fi
    sleep 1
done
fail 'The nested Docker daemon was not ready within 60 seconds.'
