From a7c48e970767b1f0c1f7474253f6c8314ea30b04 Mon Sep 17 00:00:00 2001 From: Claudiu Belu Date: Thu, 24 Jun 2021 13:39:44 +0000 Subject: [PATCH] images: Removes OS Version workaround for manifest list images For manifest lists containing Windows images, it is important to also have the "os.version" annotation set, as it is needed by the Windows nodes, so they can pull the appropriate image from the list. Previously, the docker manifest CLI did not have the capability to set it, so, we had to set it outselves in the manifest list's image JSON file. This is no longer necessary since docker 20.10.0, which includes docker manifest annotate --os-version. The docker installed in the image gcr.io/k8s-testimages/gcb-docker-gcloud:v20210622-762366a satisfies this version requirement. --- build/pause/Makefile | 14 +++----------- build/pause/cloudbuild.yaml | 2 +- test/images/cloudbuild.yaml | 2 +- test/images/image-util.sh | 29 +++++++++-------------------- 4 files changed, 14 insertions(+), 33 deletions(-) diff --git a/build/pause/Makefile b/build/pause/Makefile index 422c5e23949..ecc545e04d2 100644 --- a/build/pause/Makefile +++ b/build/pause/Makefile @@ -81,21 +81,13 @@ push-manifest: docker manifest create --amend $(IMAGE):$(TAG) $(shell echo $(ALL_OS_ARCH) | sed -e "s~[^ ]*~$(IMAGE):$(TAG)\-&~g") set -x; for arch in $(ALL_ARCH.linux); do docker manifest annotate --os linux --arch $${arch} ${IMAGE}:${TAG} ${IMAGE}:${TAG}-linux-$${arch}; done # For Windows images, we also need to include the "os.version" in the manifest list, so the Windows node can pull the proper image it needs. - # At the moment, docker manifest annotate doesn't allow us to set the os.version, so we'll have to it ourselves. The manifest list can be found locally as JSONs. - # See: https://github.com/moby/moby/issues/41417 - # If the ${REGISTRY} is on dockerhub, the prefix "docker.io/" is optional. However, we need the full - # registry name for setting the os.version for Windows images below. - # If the registry name does not contain any slashes, we prepend "docker.io/" - # TODO(claudiub): Clean this up once the above issue has been fixed. + # we use awk to also trim the quotes around the OS version string. set -x; \ - registry_prefix=$(shell (echo ${REGISTRY} | grep -Eq ".*\/.*") && echo "" || echo "docker.io/"); \ - manifest_image_folder=`echo "$${registry_prefix}${IMAGE}" | sed "s|/|_|g" | sed "s/:/-/"`; \ for arch in $(ALL_ARCH.windows); do \ for osversion in ${ALL_OSVERSIONS.windows}; do \ - docker manifest annotate --os windows --arch $${arch} ${IMAGE}:${TAG} ${IMAGE}:${TAG}-windows-$${arch}-$${osversion}; \ BASEIMAGE=${BASE.windows}:$${osversion}; \ - full_version=`docker manifest inspect ${BASE.windows}:$${osversion} | grep "os.version" | head -n 1 | awk '{print $$2}'` || true; \ - sed -i -r "s/(\"os\"\:\"windows\")/\0,\"os.version\":$${full_version}/" "${HOME}/.docker/manifests/$${manifest_image_folder}-${TAG}/$${manifest_image_folder}-${TAG}-windows-$${arch}-$${osversion}"; \ + full_version=`docker manifest inspect ${BASE.windows}:$${osversion} | grep "os.version" | head -n 1 | awk -F\" '{print $$4}'` || true; \ + docker manifest annotate --os windows --arch $${arch} --os-version $${full_version} ${IMAGE}:${TAG} ${IMAGE}:${TAG}-windows-$${arch}-$${osversion}; \ done; \ done docker manifest push --purge ${IMAGE}:${TAG} diff --git a/build/pause/cloudbuild.yaml b/build/pause/cloudbuild.yaml index 2b354129886..79da36ab41b 100644 --- a/build/pause/cloudbuild.yaml +++ b/build/pause/cloudbuild.yaml @@ -4,7 +4,7 @@ options: substitution_option: ALLOW_LOOSE machineType: 'N1_HIGHCPU_8' steps: - - name: 'gcr.io/k8s-testimages/gcb-docker-gcloud:v20200422-b25d964' + - name: 'gcr.io/k8s-testimages/gcb-docker-gcloud:v20210622-762366a' entrypoint: 'bash' dir: ./build/pause env: diff --git a/test/images/cloudbuild.yaml b/test/images/cloudbuild.yaml index 7e55571b644..c575622e52f 100644 --- a/test/images/cloudbuild.yaml +++ b/test/images/cloudbuild.yaml @@ -9,7 +9,7 @@ options: substitution_option: ALLOW_LOOSE machineType: 'N1_HIGHCPU_8' steps: - - name: 'gcr.io/k8s-testimages/gcb-docker-gcloud:v20201130-750d12f' + - name: 'gcr.io/k8s-testimages/gcb-docker-gcloud:v20210622-762366a' entrypoint: 'bash' dir: ./test/images/ env: diff --git a/test/images/image-util.sh b/test/images/image-util.sh index 3d4cf5311b7..b034a304669 100755 --- a/test/images/image-util.sh +++ b/test/images/image-util.sh @@ -42,7 +42,8 @@ declare -A WINDOWS_OS_VERSIONS_MAP initWindowsOsVersions() { for os_version in "${windows_os_versions[@]}"; do img_base="mcr.microsoft.com/windows/nanoserver:${os_version}" - full_version=$(docker manifest inspect "${img_base}" | grep "os.version" | head -n 1 | awk '{print $2}') || true + # we use awk to also trim the quotes around the OS version string. + full_version=$(docker manifest inspect "${img_base}" | grep "os.version" | head -n 1 | awk -F\" '{print $4}') || true WINDOWS_OS_VERSIONS_MAP["${os_version}"]="${full_version}" done } @@ -189,10 +190,11 @@ build() { } docker_version_check() { - # docker buildx has been introduced in 19.03, so we need to make sure we have it. + # docker manifest annotate --os-version has been introduced in 20.10.0, + # so we need to make sure we have it. docker_version=$(docker version --format '{{.Client.Version}}' | cut -d"-" -f1) - if [[ ${docker_version} != 19.03.0 && ${docker_version} < 19.03.0 ]]; then - echo "Minimum docker version 19.03.0 is required for using docker buildx: ${docker_version}]" + if [[ ${docker_version} != 20.10.0 && ${docker_version} < 20.10.0 ]]; then + echo "Minimum docker version 20.10.0 is required for annotating the OS Version in the manifest list images: ${docker_version}]" exit 1 fi } @@ -225,29 +227,16 @@ push() { while IFS='' read -r line; do manifest+=("$line"); done < <(echo "$os_archs" | "${SED}" "s~\/~-~g" | "${SED}" -e "s~[^ ]*~$REGISTRY\/$image:$TAG\-&~g") docker manifest create --amend "${REGISTRY}/${image}:${TAG}" "${manifest[@]}" - # We will need the full registry name in order to set the "os.version" for Windows images. - # If the ${REGISTRY} dcesn't have any slashes, it means that it's on dockerhub. - registry_prefix="" - if [[ ! $REGISTRY =~ .*/.* ]]; then - registry_prefix="docker.io/" - fi - # The images in the manifest list are stored locally. The folder / file name is almost the same, - # with a few changes. - manifest_image_folder=$(echo "${registry_prefix}${REGISTRY}/${image}:${TAG}" | sed "s|/|_|g" | sed "s/:/-/") - for os_arch in ${os_archs}; do splitOsArch "${image}" "${os_arch}" - docker manifest annotate --os "${os_name}" --arch "${arch}" "${REGISTRY}/${image}:${TAG}" "${REGISTRY}/${image}:${TAG}-${suffix}" # For Windows images, we also need to include the "os.version" in the manifest list, so the Windows node # can pull the proper image it needs. if [[ "$os_name" = "windows" ]]; then full_version="${WINDOWS_OS_VERSIONS_MAP[$os_version]}" - - # At the moment, docker manifest annotate doesn't allow us to set the os.version, so we'll have to - # it ourselves. The manifest list can be found locally as JSONs. - sed -i -r "s/(\"os\"\:\"windows\")/\0,\"os.version\":$full_version/" \ - "${HOME}/.docker/manifests/${manifest_image_folder}/${manifest_image_folder}-${suffix}" + docker manifest annotate --os "${os_name}" --arch "${arch}" --os-version "${full_version}" "${REGISTRY}/${image}:${TAG}" "${REGISTRY}/${image}:${TAG}-${suffix}" + else + docker manifest annotate --os "${os_name}" --arch "${arch}" "${REGISTRY}/${image}:${TAG}" "${REGISTRY}/${image}:${TAG}-${suffix}" fi done popd