#!/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 IMAGE=$2 KUBE_ROOT="$(cd "$(dirname "${BASH_SOURCE}")/../.." && pwd -P)" # 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" ) # Returns list of all supported architectures from BASEIMAGE file listArchs() { cut -d "=" -f 1 ${IMAGE}/BASEIMAGE } # Returns baseimage need to used in Dockerfile for any given architecture getBaseImage() { arch=$1 echo $(grep "${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() { if [[ -f ${IMAGE}/BASEIMAGE ]]; then archs=$(listArchs) else archs=${!QEMUARCHS[@]} fi for arch in ${archs}; do echo "Building image for ${IMAGE} ARCH: ${arch}..." # Create a temporary directory for every architecture and copy the image content # and build the image from temporary directory temp_dir=$(mktemp -d) 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 ARCH=${arch} TARGET=${temp_dir} fi pushd ${temp_dir} # image tag TAG=$(<VERSION) if [[ -f BASEIMAGE ]]; then BASEIMAGE=$(getBaseImage ${arch}) sed -i "s|BASEIMAGE|${BASEIMAGE}|g" Dockerfile fi # copy the qemu-*-static binary to docker image to build the multi architecture image on x86 platform if [[ $(grep "CROSS_BUILD_" Dockerfile) ]]; then if [[ "${arch}" == "amd64" ]]; then sed -i "/CROSS_BUILD_/d" Dockerfile else sed -i "s|QEMUARCH|${QEMUARCHS[$arch]}|g" Dockerfile # Register qemu-*-static for all supported processors except the current one docker run --rm --privileged multiarch/qemu-user-static:register --reset curl -sSL https://github.com/multiarch/qemu-user-static/releases/download/${QEMUVERSION}/x86_64_qemu-${QEMUARCHS[$arch]}-static.tar.gz | tar -xz -C ${temp_dir} sed -i "s/CROSS_BUILD_//g" Dockerfile fi fi docker build --pull -t ${REGISTRY}/${IMAGE}-${arch}:${TAG} . popd done } # This function will push the docker images push() { TAG=$(<${IMAGE}/VERSION) if [[ -f ${IMAGE}/BASEIMAGE ]]; then archs=$(listArchs) else archs=${!QEMUARCHS[@]} fi for arch in ${archs}; do docker push ${REGISTRY}/${IMAGE}-${arch}:${TAG} done # Make archs list into image manifest. Eg: 'amd64 ppc64le' to '${REGISTRY}/${IMAGE}-amd64:${TAG} ${REGISTRY}/${IMAGE}-ppc64le:${TAG}' manifest=$(echo $archs | sed -e "s~[^ ]*~$REGISTRY\/$IMAGE\-&:$TAG~g") docker manifest create --amend ${REGISTRY}/${IMAGE}:${TAG} ${manifest} for arch in ${archs}; do docker manifest annotate --arch ${arch} ${REGISTRY}/${IMAGE}:${TAG} ${REGISTRY}/${IMAGE}-${arch}:${TAG} done docker manifest push ${REGISTRY}/${IMAGE}:${TAG} } # This function is for building the go code bin() { for SRC in $@; do docker run --rm -it -v ${TARGET}:${TARGET}:Z -v ${KUBE_ROOT}:/go/src/k8s.io/kubernetes:Z \ golang:${GOLANG_VERSION} \ /bin/bash -c "\ cd /go/src/k8s.io/kubernetes/test/images/${SRC_DIR} && \ CGO_ENABLED=0 GOARM=${GOARM} GOARCH=${ARCH} go build -a -installsuffix cgo --ldflags '-w' -o ${TARGET}/${SRC} ./$(dirname ${SRC})" done } shift eval ${TASK} "$@"