diff --git a/modules/kind/kind-image-preload.mk b/modules/kind/kind-image-preload.mk index e95c9ee..d41aadc 100644 --- a/modules/kind/kind-image-preload.mk +++ b/modules/kind/kind-image-preload.mk @@ -32,18 +32,30 @@ images_files := $(foreach image,$(images),$(subst :,+,$(image))) images_tar_dir := $(bin_dir)/downloaded/containers/$(HOST_ARCH) images_tars := $(images_files:%=$(images_tar_dir)/%.tar) -# Download the images as tarballs. We must use the tag because the digest -# will change after we docker import the image. The tag is the only way to -# reference the image after it has been imported. Before downloading the -# image, we check that the provided digest matches the digest of the image -# that we are about to pull. -$(images_tars): $(images_tar_dir)/%.tar: | $(NEEDS_CRANE) - @$(eval image=$(subst +,:,$*)) - @$(eval image_without_digest=$(shell cut -d@ -f1 <<<"$(image)")) - @$(eval digest=$(subst $(image_without_digest)@,,$(image))) - @mkdir -p $(dir $@) - diff <(echo "$(digest) -" | cut -d: -f2) <($(CRANE) manifest --platform=linux/$(HOST_ARCH) $(image_without_digest) | sha256sum) - $(CRANE) pull $(image_without_digest) $@ --platform=linux/$(HOST_ARCH) +# Download the images as tarballs. After downloading the image using +# its digest, we untar the image and modify the .[0].RepoTags[0] value in +# the manifest.json file to have the correct tag (instead of "i-was-a-digest" +# which is set when the image is pulled using its digest). This tag is the +# only way to reference the image after it has been imported. This is a hack +# and we hope that crane adds an option in the future that allows setting the +# tag on images that are pulled by digest. +# NOTE: the tag is fully determined based on the input, we fully allow the remote +# tag to point to a different digest. This prevents CI from breaking due to upstream +# changes. However, it also means that we can incorrectly combine digests with tags, +# hence caution is advised. +$(images_tars): $(images_tar_dir)/%.tar: | $(NEEDS_CRANE) $(NEEDS_GOJQ) + @$(eval full_image=$(subst +,:,$*)) + @$(eval bare_image=$(word 1,$(subst :, ,$(full_image)))) + @$(eval digest=$(word 2,$(subst @, ,$(full_image)))) + @$(eval tag=$(word 2,$(subst :, ,$(word 1,$(subst @, ,$(full_image)))))) + @mkdir -p $@.tmp.unpacked + $(CRANE) pull "$(bare_image)@$(digest)" $@.tmp --platform=linux/$(HOST_ARCH) + @tar xf $@.tmp -C $@.tmp.unpacked + @rm -rf $@.tmp + @$(GOJQ) '.[0].RepoTags[0] |= rtrimstr("i-was-a-digest") + "$(tag)"' $@.tmp.unpacked/manifest.json > $@.tmp.unpacked/manifest.json.new + @mv $@.tmp.unpacked/manifest.json.new $@.tmp.unpacked/manifest.json + @find $@.tmp.unpacked \( -type f -o -type d \) -printf "%P\n" | tar -czf $@ --no-recursion -C $@.tmp.unpacked -T - + @rm -rf $@.tmp.unpacked images_tar_envs := $(images_files:%=env-%)