#!/bin/sh

handle_part() {
    case "$MOUNT" in
        "/overlay")
            return 1
        ;;
    esac
    return 0
}

check_dir() {
    local data_root=$(uci -q get dockerd.globals.data_root)
    [ -n "$data_root" ] || return 0
    local block_dev=$(findmnt -T "$data_root" -v -o SOURCE | sed -n 2p)
    [ -n "$block_dev" ] || return 0
    [ "overlayfs:/overlay" = "$block_dev" ] && return 1
    local line=$(block info "$block_dev" 2>/dev/null)
    [ -n "$line" ] || return 0
    eval "${line##*: } handle_part ${line%%: *}"
}

migrate_check(){
    local dest="$1"
    [ -n "$dest" ] || {
        echo "dest dir not specified!" >&2
        return 1
    }
    local data_root="$2"
    [ -n "$data_root" ] || data_root=$(uci -q get dockerd.globals.data_root)
    [ -n "$data_root" ] || {
        echo "get docker data_root failed!" >&2
        return 1
    }

    [ "$data_root" = "/" ] || data_root="${data_root%%/}"
    [ "$dest" = "/" ] || dest="${dest%%/}"

    [ "$data_root" = "$dest" ] && {
        echo "dest dir is the same as data_root!" >&2
        return 1
    }

    [ 1 = "$FORCE" ] && return 0
    [ -e "$dest" ] || return 0
    [ -d "$dest" ] || {
        echo "$dest is existed and it's not a dir, use FORCE=1 to overwrite it" >&2
        return 2
    }
    [ 0 = "$(ls -A "$dest" | head -1 | wc -l)" ] || {
        echo "$dest is existed and it's not empty, use FORCE=1 to overwrite it" >&2
        return 2
    }
    return 0
}

migrate() {
    local dest="$1"
    local data_root=$(uci -q get dockerd.globals.data_root)
    [ -n "$data_root" ] || {
        echo "get docker data_root failed!" >&2
        return 1
    }
    [ "$data_root" = "/" ] || data_root="${data_root%%/}"
    [ "$dest" = "/" ] || dest="${dest%%/}"

    FORCE=1 migrate_check "$dest" "$data_root"
    local check_result=$?
    [ 0 = $check_result ] || return $check_result

    if [ "$UCI_ONLY" != 1 ]; then
        rm -rf "$dest"
        mkdir -p "$dest"
        echo "Copy $data_root to $dest ..."
        cp -a "$data_root/." "$dest/" || return 1
    fi

    echo "Change dockerd data_root to $dest and restart"
    uci set dockerd.globals.data_root="$dest"
    uci commit dockerd
    /etc/init.d/dockerd restart

    echo "Done"
}

action=${1}
shift

usage() {
    echo "usage: $1 sub-command [arguments...]"
    echo "where sub-command is one of:"
    echo "      check_dir                    Check docker data_root is on extrnal disk"
    echo "      migrate_check {target_dir}   Check target_dir is valid for migration, return 2 if target_dir existed and not empty"
    echo "      migrate {target_dir}         Migrate docker data_root to target_dir"
    echo "      change_dir {target_dir}      Migrate docker data_root to target_dir but change dir only (no data copy)"
}

case $action in
    "check_dir")
        check_dir
    ;;
    "migrate")
        migrate "$@"
    ;;
    "migrate_check")
        migrate_check "$@"
    ;;
    "change_dir")
        UCI_ONLY=1 migrate "$@"
    ;;
    *)
        usage "$0"
    ;;
esac
