From dedf8528a51c6db40686ed6676e9486d1ed5f9c0 Mon Sep 17 00:00:00 2001 From: Brian Goff Date: Fri, 18 Sep 2020 22:40:45 +0000 Subject: [PATCH] Allow download-frozen-images to work without `go` Currently we use the `go` command to read GOARCH and use the value for matching manifests. This change allows: 1. Specifying the arch through `TARGETARCH` 2. Falling back to `dpkg` if `go` is not available 3. Falling back to `uname -m` if `dpkg` is not available 4. A default value (amd64) if none of these commands is available. Signed-off-by: Brian Goff --- Dockerfile | 7 ++- contrib/download-frozen-image-v2.sh | 77 ++++++++++++++++++++++++++--- 2 files changed, 74 insertions(+), 10 deletions(-) diff --git a/Dockerfile b/Dockerfile index 67906b1b5d..822f97ea1b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,7 +7,9 @@ ARG GO_VERSION=1.13.15 ARG DEBIAN_FRONTEND=noninteractive ARG VPNKIT_VERSION=0.4.0 ARG DOCKER_BUILDTAGS="apparmor seccomp selinux" -ARG GOLANG_IMAGE="golang:${GO_VERSION}-buster" + +ARG BASE_DEBIAN_DISTRO="buster" +ARG GOLANG_IMAGE="golang:${GO_VERSION}-${BASE_DEBIAN_DISTRO}" FROM ${GOLANG_IMAGE} AS base RUN echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache @@ -79,12 +81,13 @@ RUN --mount=type=cache,target=/root/.cache/go-build \ && git checkout -q "$GO_SWAGGER_COMMIT" \ && go build -o /build/swagger github.com/go-swagger/go-swagger/cmd/swagger -FROM base AS frozen-images +FROM debian:${BASE_DEBIAN_DISTRO} AS frozen-images ARG DEBIAN_FRONTEND RUN --mount=type=cache,sharing=locked,id=moby-frozen-images-aptlib,target=/var/lib/apt \ --mount=type=cache,sharing=locked,id=moby-frozen-images-aptcache,target=/var/cache/apt \ apt-get update && apt-get install -y --no-install-recommends \ ca-certificates \ + curl \ jq # Get useful and necessary Hub images so we can "docker load" locally instead of pulling COPY contrib/download-frozen-image-v2.sh / diff --git a/contrib/download-frozen-image-v2.sh b/contrib/download-frozen-image-v2.sh index 51186d74b0..27a9b6c44b 100755 --- a/contrib/download-frozen-image-v2.sh +++ b/contrib/download-frozen-image-v2.sh @@ -8,7 +8,7 @@ set -eo pipefail # debian latest f6fab3b798be3174f45aa1eb731f8182705555f89c9026d8c1ef230cbf8301dd 10 weeks ago 85.1 MB # check if essential commands are in our PATH -for cmd in curl jq go; do +for cmd in curl jq; do if ! command -v $cmd &> /dev/null; then echo >&2 "error: \"$cmd\" not found!" exit 1 @@ -36,13 +36,11 @@ manifestJsonEntries=() doNotGenerateManifestJson= # repositories[busybox]='"latest": "...", "ubuntu-14.04": "..."' -# bash v4 on Windows CI requires CRLF separator +# bash v4 on Windows CI requires CRLF separator... and linux doesn't seem to care either way newlineIFS=$'\n' -if [ "$(go env GOHOSTOS)" = 'windows' ]; then - major=$(echo "${BASH_VERSION%%[^0.9]}" | cut -d. -f1) - if [ "$major" -ge 4 ]; then - newlineIFS=$'\r\n' - fi +major=$(echo "${BASH_VERSION%%[^0.9]}" | cut -d. -f1) +if [ "$major" -ge 4 ]; then + newlineIFS=$'\r\n' fi registryBase='https://registry-1.docker.io' @@ -201,6 +199,68 @@ handle_single_manifest_v2() { manifestJsonEntries=("${manifestJsonEntries[@]}" "$manifestJsonEntry") } +get_target_arch() { + if [ -n "${TARGETARCH:-}" ]; then + echo "${TARGETARCH}" + return 0 + fi + + if type go > /dev/null; then + go env GOARCH + return 0 + fi + + if type dpkg > /dev/null; then + debArch="$(dpkg --print-architecture)" + case "${debArch}" in + armel | armhf) + echo "arm" + return 0 + ;; + *64el) + echo "${debArch%el}le" + return 0 + ;; + *) + echo "${debArch}" + return 0 + ;; + esac + fi + + if type uname > /dev/null; then + uArch="$(uname -m)" + case "${uArch}" in + x86_64) + echo amd64 + return 0 + ;; + arm | armv[0-9]*) + echo arm + return 0 + ;; + aarch64) + echo arm64 + return 0 + ;; + mips*) + echo >&2 "I see you are running on mips but I don't know how to determine endianness yet, so I cannot select a correct arch to fetch." + echo >&2 "Consider installing \"go\" on the system which I can use to determine the correct arch or specify it explictly by setting TARGETARCH" + exit 1 + ;; + *) + echo "${uArch}" + return 0 + ;; + esac + + fi + + # default value + echo >&2 "Unable to determine CPU arch, falling back to amd64. You can specify a target arch by setting TARGETARCH" + echo amd64 +} + while [ $# -gt 0 ]; do imageTag="$1" shift @@ -250,11 +310,12 @@ while [ $# -gt 0 ]; do unset IFS found="" + targetArch="$(get_target_arch)" # parse first level multi-arch manifest for i in "${!layers[@]}"; do layerMeta="${layers[$i]}" maniArch="$(echo "$layerMeta" | jq --raw-output '.platform.architecture')" - if [ "$maniArch" = "$(go env GOARCH)" ]; then + if [ "$maniArch" = "${targetArch}" ]; then digest="$(echo "$layerMeta" | jq --raw-output '.digest')" # get second level single manifest submanifestJson="$(