diff --git a/anago b/anago index 5a91f4d35c1..2acb651786a 100755 --- a/anago +++ b/anago @@ -357,6 +357,16 @@ check_prerequisites () { for rb in ${WRITE_RELEASE_BUCKETS[*]}; do release::gcs::ensure_release_bucket $rb || return 1 done + + logecho -n "Checking for manifest-tool: " + if [[ ! -f $(which manifest-tool) ]]; then + logecho -r "$FAILED" + logecho "No manifest-tool found in the path. Please install it from" \ + "https://github.com/estesp/manifest-tool/releases and set the path variable" + logecho + return 1 + fi + logecho -r "$OK" } ############################################################################### diff --git a/build/Dockerfile.k8s-cloud-builder b/build/Dockerfile.k8s-cloud-builder index cb674a10eb5..d082201b989 100644 --- a/build/Dockerfile.k8s-cloud-builder +++ b/build/Dockerfile.k8s-cloud-builder @@ -48,3 +48,7 @@ RUN \ ARG DOCKER_VERSION=17.09.0~ce-0~ubuntu RUN apt-get install -y docker-ce=${DOCKER_VERSION} unzip + +ARG MANIFEST_TOOL_VERSION=v0.7.0 +ADD https://github.com/estesp/manifest-tool/releases/download/${MANIFEST_TOOL_VERSION}/manifest-tool-linux-amd64 /usr/local/bin/manifest-tool +RUN chmod +x /usr/local/bin/manifest-tool diff --git a/lib/releaselib.sh b/lib/releaselib.sh index 0537c04b8b0..fce8038505d 100644 --- a/lib/releaselib.sh +++ b/lib/releaselib.sh @@ -910,6 +910,8 @@ release::docker::release () { "kube-proxy" "hyperkube" ) + # platforms should be in the os1/arch1,os2/arch2,os3/arch3 form + local -r platforms= $(IFS=, ; echo "${KUBE_SERVER_PLATFORMS[*]}") if [[ -n $G_AUTH_USER && $registry == "gcr.io/google_containers" ]];then logrun $GCLOUD config set account $G_AUTH_USER @@ -927,8 +929,8 @@ release::docker::release () { # 'gcloud docker' gives lots of internal_failure's so add retries to # all of the invocations - for arch in "${KUBE_SERVER_PLATFORMS[@]##*/}"; do - for binary in "${binaries[@]}"; do + for binary in "${binaries[@]}"; do + for arch in "${KUBE_SERVER_PLATFORMS[@]##*/}"; do docker_target="$binary-$arch:$version" if ! logrun -r 5 ${docker_push_cmd[@]} \ history "$registry/$docker_target"; then @@ -939,23 +941,10 @@ release::docker::release () { logecho "Release $docker_target:" logecho -n "- Pushing: " logrun -r 5 -s ${docker_push_cmd[@]} push "$registry/$docker_target" - - # If we have a amd64 docker image. Tag it without -amd64 also - # and push it for compatibility with earlier versions - if [[ $arch == "amd64" ]]; then - legacy_docker_target="$binary:$version" - logecho "Release legacy $legacy_docker_target:" - - logecho -n "- Tagging: " - logrun docker rmi "$registry/$legacy_docker_target" || true - logrun -r 5 -s docker tag "$registry/$docker_target" \ - "$registry/$legacy_docker_target" 2>/dev/null - - logecho -n "- Pushing: " - logrun -r 5 -s ${docker_push_cmd[@]} \ - push "$registry/$legacy_docker_target" - fi done + logecho -n "- Pushing manifest image: " + # This command will push a manifest list: "${registry}/${binary}-ARCH:${version}" that points to each architecture depending on which platform you're pulling from + logrun -r 5 -s manifest-tool push from-args --platforms ${platforms} --template ${registry}/${binary}-ARCH:${version} --target ${registry}/${binary}:${version} done fi @@ -977,7 +966,7 @@ release::docker::release_from_tarfiles () { local registry=$1 local version=$2 local build_output=$3 - local docker_push_cmd=(docker) + local docker_push_cmd=(gcloud docker --) local release_images=$build_output/release-images local arch local -a arches @@ -986,6 +975,7 @@ release::docker::release_from_tarfiles () { local binary local -a new_tags local new_tag + local -A manifest_images [[ "$registry" =~ gcr.io/ ]] && docker_push_cmd=("$GCLOUD" "docker" "--") @@ -1003,28 +993,25 @@ release::docker::release_from_tarfiles () { fi binary=${BASH_REMATCH[1]} - # If amd64, tag both the legacy tag and -amd64 tag - if [[ "$arch" == "amd64" ]]; then - # binary may or may not already contain -amd64, so strip it first - new_tags=(\ - "$registry/${binary/-amd64/}:$version" - "$registry/${binary/-amd64/}-amd64:$version" - ) - else - new_tags=("$registry/$binary:$version") - fi + new_tag="$registry/${binary/-$arch/}" + new_tag_with_arch=("$new_tag-$arch:$version") + manifest_images["${new_tag}"]+=" linux/$arch" docker load -qi $tarfile >/dev/null - for new_tag in ${new_tags[@]}; do - docker tag $orig_tag $new_tag - logecho -n "Pushing $new_tag: " - # 'gcloud docker' gives lots of internal_failure's so add retries - logrun -r 5 -s ${docker_push_cmd[@]} push "$new_tag" || return 1 - done - docker rmi $orig_tag ${new_tags[@]} &>/dev/null || true - + docker tag $orig_tag ${new_tag_with_arch} + logecho -n "Pushing ${new_tag_with_arch}: " + # 'gcloud docker' gives lots of internal_failure's so add retries + logrun -r 5 -s ${docker_push_cmd[@]} push "${new_tag_with_arch}" || return 1 + docker rmi $orig_tag ${new_tag_with_arch} &>/dev/null || true done done + + for image in "${!manifest_images[@]}"; do + logecho "Pushing manifest image $image..." + local manifest_platforms=$(echo "${manifest_images[$image]}" | sed -e 's/^[[:space:]]*//' | sed -e 's/[[:space:]]/,/g') + # This command will push a manifest list: "${registry}/${image}-ARCH:${version}" that points to each architecture depending on which platform you're pulling from + logrun -r 5 -s manifest-tool push from-args --platforms ${manifest_platforms} --template ${image}-ARCH:${version} --target ${image}:${version} || return 1 + done } ###############################################################################