#!/bin/sh

# Usage:
#
#   ./images-build BRANCH DOCKERFILE1 [DOCKERFILE2 ...]
#
# Build specified Dockerfiles for the host architecture and push them to the
# project registry. These are used by CI jobs, not a Charliecloud test suite
# image.
#
#   WARNING: This does not tag the images in a usable way. See “images-tag”
#   for that. Two separate scripts seemed the only way to do it without a race
#   condition.
#
# Because of this bootstrap context, we need to run *this* job using an image
# available somewhere else. It also needs to have some image builder
# installed. GitLab recommends images provided by Docker that are very bare
# bones (Alpine with no programming language other than Busybox) [1], which is
# why this is a POSIX shell script.
#
# An alternative would be Podman images, which are Fedora based and do have a
# recent Python 3 [2].
#
# CONFUSION OPPORTUNITY: The local image builder does not know if the correct
# image is already in the registry, and it doesn’t even know the layer digests
# without building the layers, which we want to avoid. Therefore, we *tag* the
# images with the MD5 of the Dockerfile plus the base image digest, and build
# a new image if either is not in the registry. That is, we use tags that are
# digests, which is weird and confusing.
#
# PREREQUISITES:
#
#   1. Log in to the gitlab.com container registry. For testing, do a manual
#      “docker login” with your username and a personal access token
#      (PAT) [3]. While your username/password will work, don’t do that
#      because Docker stores it in a plaintext file.
#
#   2. Set $CI_REGISTRY_IMAGE [4] if the default below isn’t appropriate.
#
# [1]: https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#use-docker-in-docker
# [2]: https://quay.io/repository/podman/stable
# [3]: https://docs.gitlab.com/ee/user/packages/container_registry/authenticate_with_container_registry.html
# [4]: https://docs.gitlab.com/ee/ci/variables/predefined_variables.html

set -e  # needs to be POSIX so can’t use our fancy traps

# Add directory containing script to PATH so it doesn’t yell about arch.sh and
# friends during manual testing.
PATH=$(cd "$(dirname "$0")" && pwd):$PATH
export PATH

. images.sh

branch=$1
shift
echo "branch:        $branch" 1>&2

arch=$(arch.sh)
echo "architecture:  $arch" 1>&2
#echo "nv distro:     $nv_distro"

for df in "$@"; do

    echo
    echo "file:          $df" 1>&2
    name=$(tag_from_filename "$df")
    echo "image name:    $name" 1>&2
    digest=$(fulldigest "$arch" "$df")
    echo "digest:        $digest" 1>&2

    # Check if image exists in our registry; if not, build and push it, tagged
    # with the digest we computed.
    ref_digest=$regy/$name:$digest
    printf 'in registry:   ' 1>&2
    if registry_exists "$ref_digest"; then
        echo 'yes, skipping build' 1>&2
    else
        echo 'no, building and pushing ...' 1>&2
        context=$(dirname "$df")
        echo "context:       $context" 1>&2
        docker image list
        # We only want to pull the base image if it’s not in the local Docker
        # images, because in that case the repository might contain an old
        # version. This is the default behavior without --pull.
        build -t "$ref_digest" -f "$df" \
              --build-arg=regy="$regy/" \
              --build-arg=branch="$branch" \
              "$context"
        echo 1>&2
        docker push "$ref_digest"
        # Tag so descendant images can use it even before we tag it up with
        # the right manifest in images-manifest.
        docker tag "$ref_digest" "$name:$branch" 1>&2
        docker tag "$ref_digest" "$regy/$name:$branch" 1>&2
    fi

done