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.
This commit is contained in:
Claudiu Belu 2021-06-24 13:39:44 +00:00
parent 164ce31e7f
commit a7c48e9707
4 changed files with 14 additions and 33 deletions

View File

@ -81,21 +81,13 @@ push-manifest:
docker manifest create --amend $(IMAGE):$(TAG) $(shell echo $(ALL_OS_ARCH) | sed -e "s~[^ ]*~$(IMAGE):$(TAG)\-&~g") 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 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. # 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. # we use awk to also trim the quotes around the OS version string.
# 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.
set -x; \ 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 arch in $(ALL_ARCH.windows); do \
for osversion in ${ALL_OSVERSIONS.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}; \ BASEIMAGE=${BASE.windows}:$${osversion}; \
full_version=`docker manifest inspect ${BASE.windows}:$${osversion} | grep "os.version" | head -n 1 | awk '{print $$2}'` || true; \ full_version=`docker manifest inspect ${BASE.windows}:$${osversion} | grep "os.version" | head -n 1 | awk -F\" '{print $$4}'` || 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}"; \ docker manifest annotate --os windows --arch $${arch} --os-version $${full_version} ${IMAGE}:${TAG} ${IMAGE}:${TAG}-windows-$${arch}-$${osversion}; \
done; \ done; \
done done
docker manifest push --purge ${IMAGE}:${TAG} docker manifest push --purge ${IMAGE}:${TAG}

View File

@ -4,7 +4,7 @@ options:
substitution_option: ALLOW_LOOSE substitution_option: ALLOW_LOOSE
machineType: 'N1_HIGHCPU_8' machineType: 'N1_HIGHCPU_8'
steps: steps:
- name: 'gcr.io/k8s-testimages/gcb-docker-gcloud:v20200422-b25d964' - name: 'gcr.io/k8s-testimages/gcb-docker-gcloud:v20210622-762366a'
entrypoint: 'bash' entrypoint: 'bash'
dir: ./build/pause dir: ./build/pause
env: env:

View File

@ -9,7 +9,7 @@ options:
substitution_option: ALLOW_LOOSE substitution_option: ALLOW_LOOSE
machineType: 'N1_HIGHCPU_8' machineType: 'N1_HIGHCPU_8'
steps: steps:
- name: 'gcr.io/k8s-testimages/gcb-docker-gcloud:v20201130-750d12f' - name: 'gcr.io/k8s-testimages/gcb-docker-gcloud:v20210622-762366a'
entrypoint: 'bash' entrypoint: 'bash'
dir: ./test/images/ dir: ./test/images/
env: env:

View File

@ -42,7 +42,8 @@ declare -A WINDOWS_OS_VERSIONS_MAP
initWindowsOsVersions() { initWindowsOsVersions() {
for os_version in "${windows_os_versions[@]}"; do for os_version in "${windows_os_versions[@]}"; do
img_base="mcr.microsoft.com/windows/nanoserver:${os_version}" 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}" WINDOWS_OS_VERSIONS_MAP["${os_version}"]="${full_version}"
done done
} }
@ -189,10 +190,11 @@ build() {
} }
docker_version_check() { 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) docker_version=$(docker version --format '{{.Client.Version}}' | cut -d"-" -f1)
if [[ ${docker_version} != 19.03.0 && ${docker_version} < 19.03.0 ]]; then if [[ ${docker_version} != 20.10.0 && ${docker_version} < 20.10.0 ]]; then
echo "Minimum docker version 19.03.0 is required for using docker buildx: ${docker_version}]" echo "Minimum docker version 20.10.0 is required for annotating the OS Version in the manifest list images: ${docker_version}]"
exit 1 exit 1
fi 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") 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[@]}" 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 for os_arch in ${os_archs}; do
splitOsArch "${image}" "${os_arch}" 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 # 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. # can pull the proper image it needs.
if [[ "$os_name" = "windows" ]]; then if [[ "$os_name" = "windows" ]]; then
full_version="${WINDOWS_OS_VERSIONS_MAP[$os_version]}" full_version="${WINDOWS_OS_VERSIONS_MAP[$os_version]}"
docker manifest annotate --os "${os_name}" --arch "${arch}" --os-version "${full_version}" "${REGISTRY}/${image}:${TAG}" "${REGISTRY}/${image}:${TAG}-${suffix}"
# At the moment, docker manifest annotate doesn't allow us to set the os.version, so we'll have to else
# it ourselves. The manifest list can be found locally as JSONs. docker manifest annotate --os "${os_name}" --arch "${arch}" "${REGISTRY}/${image}:${TAG}" "${REGISTRY}/${image}:${TAG}-${suffix}"
sed -i -r "s/(\"os\"\:\"windows\")/\0,\"os.version\":$full_version/" \
"${HOME}/.docker/manifests/${manifest_image_folder}/${manifest_image_folder}-${suffix}"
fi fi
done done
popd popd