#!/bin/bash

# this scripts outputs the actual installer script to stdout, after performing some simplistic templating
# when utilised as described below, an all-in-one script named like
#       install_netops_modules_$( TZ=UTC date "+%Y_%m_%d-%H_%M_%S" ).sh
# will be generated in the user's current working directory, with instructions on how to use it written to stdout
#
# there are two ways end users may utilise this script:
#
#   docker pull docker.io/opengear/deployment:latest \
#       && docker run --rm --entrypoint offline-installer docker.io/opengear/deployment:latest | sh
#
# or
#
#   docker pull docker.io/opengear/deployment:TAG \
#       && docker tag docker.io/opengear/deployment:TAG docker.io/opengear/deployment:latest \
#       && docker run --rm --entrypoint offline-installer docker.io/opengear/deployment:latest | sh

set -o pipefail
set -e || exit 1

# shellcheck disable=SC2016
if [ -z "$INSTALLER" ]; then INSTALLER="install_netops_modules_$( TZ=UTC date "+%Y_%m_%d-%H_%M_%S" ).sh"; fi
if [ -z "$REPOSITORY" ]; then REPOSITORY="docker.io/opengear"; fi
IMAGES="$( jq -r -M '.modules[] | select(.active == true) | .versions[] | select(.bundle == true) | .images[] | ( .image + ":" + .version )' /modules | sort | uniq | xargs printf '\ %s' )"

cat << OUTPUT
#!/bin/sh

# This script creates a self-contained installer which packages the latest
# available NetOps Modules from Docker Hub. The generated installer is intended
# to be run directly on a Lighthouse instance that can not reach Docker Hub.

INSTALLER=$INSTALLER
REPOSITORY=$REPOSITORY
IMAGES=$IMAGES

OUTPUT
cat << 'OUTPUT'
# pull accepts a list of images (sans repository) as arguments, and will pull
# them from $REPOSITORY
#
# USAGE
# pull ...IMAGES
pull() {
    for image in "$@"; do
        image="$REPOSITORY/$image" \
            && echo docker pull "$image" \
            && docker pull "$image" \
            || return 1
    done
}

# retag accepts a list of images as arguments and will tag each one from the
# $REPOSITORY to localhost:5005 (local Lighthouse repository)
# Note each (retagged) image will be printed to stdout (space separated)
#
# USAGE
# retag ...IMAGES
retag() {
    for image in "$@"; do
        source="$REPOSITORY/$image" \
            && target="localhost:5005/$image" \
            && echo docker tag "$source" "$target" >&2 \
            && docker tag "$source" "$target" >&2 \
            && ( printf '%s ' "$target" || echo -n "$target " ) \
            || return 1
    done
}

echo "Pulling images from $REPOSITORY" \
    && pull $IMAGES \
    && echo "Re-tagging images from $REPOSITORY" \
    && IMAGES="$( retag deployment:latest $IMAGES )" 2>&1 \
    && echo "Pulling docker registry image" \
    && echo docker pull registry:2 \
    && docker pull registry:2 \
    && echo "Creating $INSTALLER" \
    && { cat > "$INSTALLER" << 'EOF'
#!/bin/bash

set -o pipefail
set -e || exit 1

SKIP="$(awk '/^__TAR_FOLLOWS__/ { print NR + 1; exit 0; }' "$0")"
tail -n+$SKIP "$0" | gzip -d | docker load

/etc/scripts/start_netops_deployment

docker stop registry || true
docker container rm registry || true
docker run -d -p 5005:5000 --network netops --restart=always -v registry-vol:/var/lib/registry --name registry registry:2
count=1
while ! curl -v --connect-timeout 10 -k http://localhost:5005/v2/_catalog &> /dev/null; do
    if [ $count -ge 30 ]; then
        echo "Registry failed to respond"
        exit 1
    fi

    sleep 1
    ((count++))
done

EOF
    } \
    && echo "for image in $IMAGES; do" >> "$INSTALLER" \
    && { cat >> "$INSTALLER" << 'EOF'
    docker push "$image"
done

echo 'Done!'
exit 0

__TAR_FOLLOWS__
EOF
    } \
    && docker save registry:2 $IMAGES | gzip -9 >> "$INSTALLER" \
    && chmod +x "$INSTALLER" \
    && { cat << EOF
Done!

Install modules on Lighthouse with these commands:

  LH_ADDRESS=address.of.lighthouse
  scp -p $INSTALLER root@\$LH_ADDRESS:/mnt/data/
  ssh root@\$LH_ADDRESS "/mnt/data/$INSTALLER && rm /mnt/data/$INSTALLER"

.. where address.of.lighthouse is your Lighthouse address
EOF
    }
OUTPUT
