test images: Adds multiple Windows channels support

This commit adds support for building test images for multiple
Windows versions, as we have to support both LTS and SAC channels.

With this, the format for Windows images in the BASEIMAGE files is:

OS/ARCH/OS_VERSION

Also adds --isolation-hyperv to the Windows docker build command, making sure
that container images for multiple OS versions can be built using the same
Windows node.
This commit is contained in:
Claudiu Belu 2019-08-01 16:08:51 -07:00
parent 296464d968
commit 3cdb7a89cb
4 changed files with 38 additions and 14 deletions

View File

@ -3,4 +3,6 @@ linux/arm=arm32v6/alpine:3.6
linux/arm64=arm64v8/alpine:3.6 linux/arm64=arm64v8/alpine:3.6
linux/ppc64le=ppc64le/alpine:3.6 linux/ppc64le=ppc64le/alpine:3.6
linux/s390x=s390x/alpine:3.6 linux/s390x=s390x/alpine:3.6
windows/amd64=REGISTRY/busybox:1.29-windows-amd64 windows/amd64/1809=REGISTRY/busybox:1.29-windows-amd64-1809
windows/amd64/1903=REGISTRY/busybox:1.29-windows-amd64-1903
windows/amd64/1909=REGISTRY/busybox:1.29-windows-amd64-1909

View File

@ -639,4 +639,5 @@ The Windows `agnhost` image includes a `nc` binary that is 100% compliant with i
## Image ## Image
The image can be found at `us.gcr.io/k8s-artifacts-prod/e2e-test-images/agnhost:2.11` for both Linux and The image can be found at `us.gcr.io/k8s-artifacts-prod/e2e-test-images/agnhost:2.11` for both Linux and
Windows containers (based on `mcr.microsoft.com/windows/servercore:ltsc2019`). Windows containers (based on `mcr.microsoft.com/windows/servercore:ltsc2019`,
`mcr.microsoft.com/windows/servercore:1903`, and `mcr.microsoft.com/windows/servercore:1909`).

View File

@ -1 +1,3 @@
windows/amd64=mcr.microsoft.com/windows/servercore:ltsc2019 windows/amd64/1809=mcr.microsoft.com/windows/servercore:ltsc2019
windows/amd64/1903=mcr.microsoft.com/windows/servercore:1903
windows/amd64/1909=mcr.microsoft.com/windows/servercore:1909

View File

@ -36,9 +36,8 @@ listOsArchs() {
# Returns baseimage need to used in Dockerfile for any given architecture # Returns baseimage need to used in Dockerfile for any given architecture
getBaseImage() { getBaseImage() {
os_name=$1 os_arch=$1
arch=$2 grep "${os_arch}=" BASEIMAGE | cut -d= -f2
grep "${os_name}/${arch}=" BASEIMAGE | cut -d= -f2
} }
# This function will build test image for all the architectures # This function will build test image for all the architectures
@ -57,7 +56,13 @@ build() {
kube::util::ensure-gnu-sed kube::util::ensure-gnu-sed
for os_arch in ${os_archs}; do for os_arch in ${os_archs}; do
if [[ $os_arch =~ .*/.* ]]; then if [[ $os_arch =~ .*/.*/.* ]]; then
# for Windows, we have to support both LTS and SAC channels, so we're building multiple Windows images.
# the format for this case is: OS/ARCH/OS_VERSION.
os_name=$(echo "$os_arch" | cut -d "/" -f 1)
arch=$(echo "$os_arch" | cut -d "/" -f 2)
os_version=$(echo "$os_arch" | cut -d "/" -f 3)
elif [[ $os_arch =~ .*/.* ]]; then
os_name=$(echo "$os_arch" | cut -d "/" -f 1) os_name=$(echo "$os_arch" | cut -d "/" -f 1)
arch=$(echo "$os_arch" | cut -d "/" -f 2) arch=$(echo "$os_arch" | cut -d "/" -f 2)
else else
@ -84,7 +89,7 @@ build() {
TAG=$(<VERSION) TAG=$(<VERSION)
if [[ -f BASEIMAGE ]]; then if [[ -f BASEIMAGE ]]; then
BASEIMAGE=$(getBaseImage "${os_name}" "${arch}" | ${SED} "s|REGISTRY|${REGISTRY}|g") BASEIMAGE=$(getBaseImage "${os_arch}" | ${SED} "s|REGISTRY|${REGISTRY}|g")
# NOTE(claudiub): Some Windows images might require their own Dockerfile # NOTE(claudiub): Some Windows images might require their own Dockerfile
# while simpler ones will not. If we're building for Windows, check if # while simpler ones will not. If we're building for Windows, check if
@ -123,7 +128,7 @@ build() {
# NOTE(claudiub): We're using a remote Windows node to build the Windows Docker images. # NOTE(claudiub): We're using a remote Windows node to build the Windows Docker images.
# The node requires TLS authentication, and thus it is expected that the # The node requires TLS authentication, and thus it is expected that the
# ca.pem, cert.pem, key.pem files can be found in the ~/.docker folder. # ca.pem, cert.pem, key.pem files can be found in the ~/.docker folder.
docker --tlsverify -H "${REMOTE_DOCKER_URL}" build --pull -t "${REGISTRY}/${image}:${TAG}-${os_name}-${arch}" --build-arg BASEIMAGE="${BASEIMAGE}" -f $dockerfile_name . docker --tlsverify -H "${REMOTE_DOCKER_URL}" build --isolation=hyperv --pull -t "${REGISTRY}/${image}:${TAG}-${os_name}-${arch}-${os_version}" --build-arg BASEIMAGE="${BASEIMAGE}" -f $dockerfile_name .
else else
echo "Cannot build the image '${image}' for ${os_arch}. REMOTE_DOCKER_URL should be set, containing the URL to a Windows docker daemon." echo "Cannot build the image '${image}' for ${os_arch}. REMOTE_DOCKER_URL should be set, containing the URL to a Windows docker daemon."
fi fi
@ -159,7 +164,13 @@ push() {
os_archs=$(printf 'linux/%s\n' "${!QEMUARCHS[*]}") os_archs=$(printf 'linux/%s\n' "${!QEMUARCHS[*]}")
fi fi
for os_arch in ${os_archs}; do for os_arch in ${os_archs}; do
if [[ $os_arch =~ .*/.* ]]; then if [[ $os_arch =~ .*/.*/.* ]]; then
# for Windows, we have to support both LTS and SAC channels, so we're building multiple Windows images.
# the format for this case is: OS/ARCH/OS_VERSION.
os_name=$(echo "$os_arch" | cut -d "/" -f 1)
arch=$(echo "$os_arch" | cut -d "/" -f 2)
os_version=$(echo "$os_arch" | cut -d "/" -f 3)
elif [[ $os_arch =~ .*/.* ]]; then
os_name=$(echo "$os_arch" | cut -d "/" -f 1) os_name=$(echo "$os_arch" | cut -d "/" -f 1)
arch=$(echo "$os_arch" | cut -d "/" -f 2) arch=$(echo "$os_arch" | cut -d "/" -f 2)
else else
@ -171,7 +182,7 @@ push() {
docker push "${REGISTRY}/${image}:${TAG}-${os_name}-${arch}" docker push "${REGISTRY}/${image}:${TAG}-${os_name}-${arch}"
else else
# NOTE(claudiub): We're pushing the image we built on the remote Windows node. # NOTE(claudiub): We're pushing the image we built on the remote Windows node.
docker --tlsverify -H "${REMOTE_DOCKER_URL}" push "${REGISTRY}/${image}:${TAG}-${os_name}-${arch}" docker --tlsverify -H "${REMOTE_DOCKER_URL}" push "${REGISTRY}/${image}:${TAG}-${os_name}-${arch}-${os_version}"
fi fi
done done
@ -182,17 +193,25 @@ push() {
# reset manifest list; needed in case multiple images are being built / pushed. # reset manifest list; needed in case multiple images are being built / pushed.
manifest=() manifest=()
# Make os_archs list into image manifest. Eg: 'linux/amd64 linux/ppc64le' to '${REGISTRY}/${image}:${TAG}-linux-amd64 ${REGISTRY}/${image}:${TAG}-linux-ppc64le' # Make os_archs list into image manifest. Eg: 'linux/amd64 linux/ppc64le' to '${REGISTRY}/${image}:${TAG}-linux-amd64 ${REGISTRY}/${image}:${TAG}-linux-ppc64le'
while IFS='' read -r line; do manifest+=("$line"); done < <(echo "$os_archs" | ${SED} "s~\/~-~" | ${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[@]}"
for os_arch in ${os_archs}; do for os_arch in ${os_archs}; do
if [[ $os_arch =~ .*/.* ]]; then if [[ $os_arch =~ .*/.*/.* ]]; then
# for Windows, we have to support both LTS and SAC channels, so we're building multiple Windows images.
# the format for this case is: OS/ARCH/OS_VERSION.
os_name=$(echo "$os_arch" | cut -d "/" -f 1) os_name=$(echo "$os_arch" | cut -d "/" -f 1)
arch=$(echo "$os_arch" | cut -d "/" -f 2) arch=$(echo "$os_arch" | cut -d "/" -f 2)
os_version=$(echo "$os_arch" | cut -d "/" -f 3)
suffix="$os_name-$arch-$os_version"
elif [[ $os_arch =~ .*/.* ]]; then
os_name=$(echo "$os_arch" | cut -d "/" -f 1)
arch=$(echo "$os_arch" | cut -d "/" -f 2)
suffix="$os_name-$arch"
else else
echo "The BASEIMAGE file for the ${image} image is not properly formatted. Expected entries to start with 'os/arch', found '${os_arch}' instead." echo "The BASEIMAGE file for the ${image} image is not properly formatted. Expected entries to start with 'os/arch', found '${os_arch}' instead."
exit 1 exit 1
fi fi
docker manifest annotate --os "${os_name}" --arch "${arch}" "${REGISTRY}/${image}:${TAG}" "${REGISTRY}/${image}:${TAG}-${os_name}-${arch}" docker manifest annotate --os "${os_name}" --arch "${arch}" "${REGISTRY}/${image}:${TAG}" "${REGISTRY}/${image}:${TAG}-${suffix}"
done done
docker manifest push --purge "${REGISTRY}/${image}:${TAG}" docker manifest push --purge "${REGISTRY}/${image}:${TAG}"
} }