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 <cpuguy83@gmail.com>
... | ... |
@@ -7,7 +7,9 @@ ARG GO_VERSION=1.13.15 |
7 | 7 |
ARG DEBIAN_FRONTEND=noninteractive |
8 | 8 |
ARG VPNKIT_VERSION=0.4.0 |
9 | 9 |
ARG DOCKER_BUILDTAGS="apparmor seccomp selinux" |
10 |
-ARG GOLANG_IMAGE="golang:${GO_VERSION}-buster" |
|
10 |
+ |
|
11 |
+ARG BASE_DEBIAN_DISTRO="buster" |
|
12 |
+ARG GOLANG_IMAGE="golang:${GO_VERSION}-${BASE_DEBIAN_DISTRO}" |
|
11 | 13 |
|
12 | 14 |
FROM ${GOLANG_IMAGE} AS base |
13 | 15 |
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 \ |
79 | 79 |
&& git checkout -q "$GO_SWAGGER_COMMIT" \ |
80 | 80 |
&& go build -o /build/swagger github.com/go-swagger/go-swagger/cmd/swagger |
81 | 81 |
|
82 |
-FROM base AS frozen-images |
|
82 |
+FROM debian:${BASE_DEBIAN_DISTRO} AS frozen-images |
|
83 | 83 |
ARG DEBIAN_FRONTEND |
84 | 84 |
RUN --mount=type=cache,sharing=locked,id=moby-frozen-images-aptlib,target=/var/lib/apt \ |
85 | 85 |
--mount=type=cache,sharing=locked,id=moby-frozen-images-aptcache,target=/var/cache/apt \ |
86 | 86 |
apt-get update && apt-get install -y --no-install-recommends \ |
87 | 87 |
ca-certificates \ |
88 |
+ curl \ |
|
88 | 89 |
jq |
89 | 90 |
# Get useful and necessary Hub images so we can "docker load" locally instead of pulling |
90 | 91 |
COPY contrib/download-frozen-image-v2.sh / |
... | ... |
@@ -8,7 +8,7 @@ set -eo pipefail |
8 | 8 |
# debian latest f6fab3b798be3174f45aa1eb731f8182705555f89c9026d8c1ef230cbf8301dd 10 weeks ago 85.1 MB |
9 | 9 |
|
10 | 10 |
# check if essential commands are in our PATH |
11 |
-for cmd in curl jq go; do |
|
11 |
+for cmd in curl jq; do |
|
12 | 12 |
if ! command -v $cmd &> /dev/null; then |
13 | 13 |
echo >&2 "error: \"$cmd\" not found!" |
14 | 14 |
exit 1 |
... | ... |
@@ -36,13 +36,11 @@ manifestJsonEntries=() |
36 | 36 |
doNotGenerateManifestJson= |
37 | 37 |
# repositories[busybox]='"latest": "...", "ubuntu-14.04": "..."' |
38 | 38 |
|
39 |
-# bash v4 on Windows CI requires CRLF separator |
|
39 |
+# bash v4 on Windows CI requires CRLF separator... and linux doesn't seem to care either way |
|
40 | 40 |
newlineIFS=$'\n' |
41 |
-if [ "$(go env GOHOSTOS)" = 'windows' ]; then |
|
42 |
- major=$(echo "${BASH_VERSION%%[^0.9]}" | cut -d. -f1) |
|
43 |
- if [ "$major" -ge 4 ]; then |
|
44 |
- newlineIFS=$'\r\n' |
|
45 |
- fi |
|
41 |
+major=$(echo "${BASH_VERSION%%[^0.9]}" | cut -d. -f1) |
|
42 |
+if [ "$major" -ge 4 ]; then |
|
43 |
+ newlineIFS=$'\r\n' |
|
46 | 44 |
fi |
47 | 45 |
|
48 | 46 |
registryBase='https://registry-1.docker.io' |
... | ... |
@@ -201,6 +199,68 @@ handle_single_manifest_v2() { |
201 | 201 |
manifestJsonEntries=("${manifestJsonEntries[@]}" "$manifestJsonEntry") |
202 | 202 |
} |
203 | 203 |
|
204 |
+get_target_arch() { |
|
205 |
+ if [ -n "${TARGETARCH:-}" ]; then |
|
206 |
+ echo "${TARGETARCH}" |
|
207 |
+ return 0 |
|
208 |
+ fi |
|
209 |
+ |
|
210 |
+ if type go > /dev/null; then |
|
211 |
+ go env GOARCH |
|
212 |
+ return 0 |
|
213 |
+ fi |
|
214 |
+ |
|
215 |
+ if type dpkg > /dev/null; then |
|
216 |
+ debArch="$(dpkg --print-architecture)" |
|
217 |
+ case "${debArch}" in |
|
218 |
+ armel | armhf) |
|
219 |
+ echo "arm" |
|
220 |
+ return 0 |
|
221 |
+ ;; |
|
222 |
+ *64el) |
|
223 |
+ echo "${debArch%el}le" |
|
224 |
+ return 0 |
|
225 |
+ ;; |
|
226 |
+ *) |
|
227 |
+ echo "${debArch}" |
|
228 |
+ return 0 |
|
229 |
+ ;; |
|
230 |
+ esac |
|
231 |
+ fi |
|
232 |
+ |
|
233 |
+ if type uname > /dev/null; then |
|
234 |
+ uArch="$(uname -m)" |
|
235 |
+ case "${uArch}" in |
|
236 |
+ x86_64) |
|
237 |
+ echo amd64 |
|
238 |
+ return 0 |
|
239 |
+ ;; |
|
240 |
+ arm | armv[0-9]*) |
|
241 |
+ echo arm |
|
242 |
+ return 0 |
|
243 |
+ ;; |
|
244 |
+ aarch64) |
|
245 |
+ echo arm64 |
|
246 |
+ return 0 |
|
247 |
+ ;; |
|
248 |
+ mips*) |
|
249 |
+ 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." |
|
250 |
+ echo >&2 "Consider installing \"go\" on the system which I can use to determine the correct arch or specify it explictly by setting TARGETARCH" |
|
251 |
+ exit 1 |
|
252 |
+ ;; |
|
253 |
+ *) |
|
254 |
+ echo "${uArch}" |
|
255 |
+ return 0 |
|
256 |
+ ;; |
|
257 |
+ esac |
|
258 |
+ |
|
259 |
+ fi |
|
260 |
+ |
|
261 |
+ # default value |
|
262 |
+ echo >&2 "Unable to determine CPU arch, falling back to amd64. You can specify a target arch by setting TARGETARCH" |
|
263 |
+ echo amd64 |
|
264 |
+} |
|
265 |
+ |
|
204 | 266 |
while [ $# -gt 0 ]; do |
205 | 267 |
imageTag="$1" |
206 | 268 |
shift |
... | ... |
@@ -250,11 +310,12 @@ while [ $# -gt 0 ]; do |
250 | 250 |
unset IFS |
251 | 251 |
|
252 | 252 |
found="" |
253 |
+ targetArch="$(get_target_arch)" |
|
253 | 254 |
# parse first level multi-arch manifest |
254 | 255 |
for i in "${!layers[@]}"; do |
255 | 256 |
layerMeta="${layers[$i]}" |
256 | 257 |
maniArch="$(echo "$layerMeta" | jq --raw-output '.platform.architecture')" |
257 |
- if [ "$maniArch" = "$(go env GOARCH)" ]; then |
|
258 |
+ if [ "$maniArch" = "${targetArch}" ]; then |
|
258 | 259 |
digest="$(echo "$layerMeta" | jq --raw-output '.digest')" |
259 | 260 |
# get second level single manifest |
260 | 261 |
submanifestJson="$( |