# This make file provides three operations:
#
# - Copy a list of images (hardcoded below) to a main repository (by default,
#   quay.io/skupper)
# - Generate and push images to that same repository, based on Dockerfiles
# - Copy both lists of images above (external and generated) to another,
#   configurable repository
#
# See the README.md for the rationale of each of them.
#
# The basic operation is to copy or generate-and-push a single image into
# the MAIN_REPO:
#
#   make docker.io/svagi/nghttp2
#   make nghttp2
#
# The possible values are those listed on EXTERNAL_IMAGES and GENERATED_IMAGES.
#
# You can also only build an image (and not push it).  Just add _build to the
# image name listed in GENERATED_IMAGES:
#
#   make nghttp2_build
#
# Alternativelly, one can build/push or copy all generated, all external, or
# all of them:
#
#   make external_images
#   make generated_images
#   make everything
#
# Notice that the Makefile itself will not check whether the copy or build/push
# is necessary; the underlying tools (podman and skopeo) may do that, but they
# may still consume Dockerhub pull requests in the process.
#
# As with any Makefile, you can configure the execution by setting variables
# on the make invocation:
#
#   make MAIN_REPO=quay.io/dhashimo docker.io/ssorj/quiver
#
# The command above will copy docker.io/ssorj/quiver into the quay repository
# quay.io/dhashimo, instead of the default MAIN_REPO
#
#   make MAIN_REPO=quay.io/dhashimo everything
#
# Similarly, the command above will copy and build/generate everything, but
# into the specified MAIN_REPO.
#
# The last operation is to copy images from MAIN_REPO to another repository,
# which needs to be specified.
#
#   make COPY_REPO=192.168.0.1:5000/internal copy
#
# The command above will copy all images (external and generated, as listed
# below) from the MAIN_REPO into the 'internal' repository within the
# registry running at 192.168.0.1:5000.
#
# Individual items can also be specified.  For that, just add '_copy' to
# their main target names:
#
#   make COPY_REPO=192.168.0.1:5000/internal nghttp2_copy
#   make COPY_REPO=192.168.0.1:5000/internal docker.io/ssorj/quiver_copy
#
# This Makefile is intended to be executed manually, with the login of
# individual users, and not by a robot account on a CI.
#
# ATTENTION: Remember that images copied for the first time into quay may
#            be created as 'private' images, and need to be changed into
#            'public' before they can be used by CI and other users.

# --- configuration ---

# tools
SHELL = /bin/sh
PODMAN = podman
SKOPEO = skopeo

# tool options

# The options below create or transform the images into the docker format.
# That is required for their use with Openshift 3.11
FORMAT_OPTIONS = --format docker
TRANSFORM_OPTIONS = --format v2s1

# Repositories
MAIN_REPO = quay.io/skupper
COPY_REPO = localhost:5000/local

# This is the list of external images that will be copied to $(MAIN_REPO).  If
# the image specifies a tag, make sure to escape the colon with a backslash
# (such as in docker.io/library/mongo\:5.0).  Otherwise, you'll get an error
# like `multiple target patterns.  Stop.`
EXTERNAL_IMAGES := \
	docker.io/nginxinc/nginx-unprivileged \
	docker.io/ssorj/quiver \
	docker.io/library/postgres \
	docker.io/library/redis \
	docker.io/maistra/examples-bookinfo-productpage-v1\:0.12.0 \
	docker.io/maistra/examples-bookinfo-ratings-v1\:0.12.0 \
	docker.io/maistra/examples-bookinfo-details-v1\:0.12.0 \
	docker.io/maistra/examples-bookinfo-reviews-v3\:0.12.0 \
	docker.io/library/mongo\:5.0 \
	docker.io/nginxinc/nginx-unprivileged\:stable-alpine

# These are the images that are generated by this Makefile (as opposed to
# created elsewhere and just copied here).  To add a new image, simply create
# Dockerfile.IMAGENAME and add the IMAGENAME below.
GENERATED_IMAGES := \
	nghttp2

# --- end of configuration ---


# These are the build target names, such as nghttp2_build, generated
# automatically from GENERATED_IMAGES.  Do not overwrite this
generated_build := $(patsubst %,%_build,$(GENERATED_IMAGES))

# The copy target names, to be used with the copy operation
generated_copy := $(patsubst %,%_copy,$(GENERATED_IMAGES))
external_copy   := $(patsubst %,%_copy,$(EXTERNAL_IMAGES))

# We don't want someone to just run `make` and start copying stuff
# around, so instead the default operation is to just give some
# hint on how to use it.
all:
	@echo "Use 'make everything' for building and copying everything to the MAIN_REPO".
	@echo
	@echo "MAIN_REPO=$(MAIN_REPO)"
	@echo
	@echo Normal use, however, is to select individual targets.
	@echo Check Makefile contents for documentation.

# For a generated image, we simply have a Dockerfile named after it and call
# `podman build` on it, tagging it on the MAIN_REPO
$(generated_build): TARGET = $(patsubst %_build,%,$@)
$(generated_build):
	$(PODMAN) build $(FORMAT_OPTIONS) --file Dockerfile.$(TARGET) --tag $(MAIN_REPO)/$(TARGET)

# This is generic the push target, for images built here (GENERATED_IMAGES)
# Each image depends on its respective _build target
%: %_build
	$(PODMAN) push $(MAIN_REPO)/$@

# Shortcut targets
external_images: $(EXTERNAL_IMAGES)
generated_images: $(GENERATED_IMAGES)
everything: external_images generated_images

# This is the main target for the external images; it copies them from their
# original locations _into_ MAIN_REPO.  Do not confuse this for the `copy` operation
# below, that copies _from_ MAIN_REPO into COPY_REPO.
#
# The first line prepares a target-local TARGET variable, which contains only
# the last part of the URL
$(EXTERNAL_IMAGES): TARGET = $(shell echo "$@" | sed s_.*/__ )
$(EXTERNAL_IMAGES):
	$(SKOPEO) copy $(TRANSFORM_OPTIONS) \
		docker://$@ \
		docker://$(MAIN_REPO)/$(TARGET)

#
# Copy operation
#
copy: $(generated_copy) $(external_copy)

# The targets for external and generated images are basically the same; the
# only difference is the way the original/main target needs to be manipulated
# to generate the image name+tag (saved in the target-local variable TARGET).

$(generated_copy): TARGET = $(patsubst %_copy,%,$@)
$(generated_copy):
	$(SKOPEO) copy $(TRANSFORM_OPTIONS) \
		docker://$(MAIN_REPO)/$(TARGET) \
		docker://$(COPY_REPO)/$(TARGET)

# Remove _copy, but also everything till the last /
$(external_copy): TARGET = $(shell echo "$@" | sed -e "s/_copy$$//" -e 's_.*/__' )
$(external_copy):
	$(SKOPEO) copy $(TRANSFORM_OPTIONS) \
		docker://$(MAIN_REPO)/$(TARGET) \
		docker://$(COPY_REPO)/$(TARGET)
