#!/usr/bin/env bash # Copyright 2017 The Kubernetes Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -o errexit set -o nounset set -o pipefail TASK=$1 WHAT=$2 # docker buildx command is still experimental as of Docker 19.03.0 export DOCKER_CLI_EXPERIMENTAL="enabled" # Connecting to a Remote Docker requires certificates for authentication, which can be found # at this path. By default, they can be found in the ${HOME} folder. We're expecting to find # here ".docker-${os_version}" folders which contains the necessary certificates. DOCKER_CERT_BASE_PATH="${DOCKER_CERT_BASE_PATH:-${HOME}}" KUBE_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd -P)" source "${KUBE_ROOT}/hack/lib/logging.sh" source "${KUBE_ROOT}/hack/lib/util.sh" # Mapping of go ARCH to actual architectures shipped part of multiarch/qemu-user-static project declare -A QEMUARCHS=( ["amd64"]="x86_64" ["arm"]="arm" ["arm64"]="aarch64" ["ppc64le"]="ppc64le" ["s390x"]="s390x" ) windows_os_versions=(1809 1903 1909 2004) 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 WINDOWS_OS_VERSIONS_MAP["${os_version}"]="${full_version}" done } initWindowsOsVersions # Returns list of all supported architectures from BASEIMAGE file listOsArchs() { image=$1 cut -d "=" -f 1 "${image}"/BASEIMAGE } splitOsArch() { image=$1 os_arch=$2 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) 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) os_version="" suffix="$os_name-$arch" else 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 fi } # Returns baseimage need to used in Dockerfile for any given architecture getBaseImage() { os_arch=$1 grep "${os_arch}=" BASEIMAGE | cut -d= -f2 } # This function will build test image for all the architectures # mentioned in BASEIMAGE file. In the absence of BASEIMAGE file, # it will build for all the supported arch list - amd64, arm, # arm64, ppc64le, s390x build() { image=$1 output_type=$2 docker_version_check if [[ -f ${image}/BASEIMAGE ]]; then os_archs=$(listOsArchs "$image") else # prepend linux/ to the QEMUARCHS items. os_archs=$(printf 'linux/%s\n' "${!QEMUARCHS[*]}") fi kube::util::ensure-gnu-sed for os_arch in ${os_archs}; do splitOsArch "${image}" "${os_arch}" if [[ "${os_name}" == "windows" && "${output_type}" == "docker" ]]; then echo "Cannot build the image '${image}' for ${os_arch}. Built Windows container images need to be pushed to a registry." continue fi echo "Building image for ${image} OS/ARCH: ${os_arch}..." # Create a temporary directory for every architecture and copy the image content # and build the image from temporary directory mkdir -p "${KUBE_ROOT}"/_tmp temp_dir=$(mktemp -d "${KUBE_ROOT}"/_tmp/test-images-build.XXXXXX) kube::util::trap_add "rm -rf ${temp_dir}" EXIT cp -r "${image}"/* "${temp_dir}" if [[ -f ${image}/Makefile ]]; then # make bin will take care of all the prerequisites needed # for building the docker image make -C "${image}" bin OS="${os_name}" ARCH="${arch}" TARGET="${temp_dir}" fi pushd "${temp_dir}" # image tag TAG=$(