diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 93a2850c..d9e95834 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -116,11 +116,11 @@ jobs: run: | docker run --rm --privileged tonistiigi/binfmt:test --uninstall qemu-* docker run --rm --privileged tonistiigi/binfmt:test --install all - docker run --rm arm64v8/alpine uname -a - docker run --rm arm32v7/alpine uname -a - docker run --rm ppc64le/alpine uname -a - docker run --rm s390x/alpine uname -a - docker run --rm tonistiigi/debian:riscv uname -a + docker run --rm --platform linux/arm64/v8 arm64v8/alpine uname -a + docker run --rm --platform linux/arm/v7 arm32v7/alpine uname -a + docker run --rm --platform linux/ppc64le ppc64le/alpine uname -a + docker run --rm --platform linux/s390x s390x/alpine uname -a + docker run --rm --platform linux/riscv64 riscv64/alpine uname -a docker run --rm yangzewei2023/debian:loongarch64 uname -a docker run --rm --platform=linux/s390x s390x/ubuntu apt update docker run --rm --platform=linux/ppc64le ppc64le/ubuntu apt update diff --git a/README.md b/README.md index 602d9ac8..3a2eb789 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,7 @@ services: network_mode: bridge restart: "no" ``` + Only use container `restart-policy` as `no`, otherwise docker will keep restarting the container. ## Uninstalling emulators @@ -88,6 +89,7 @@ docker run --privileged --rm tonistiigi/binfmt --uninstall qemu-* ```bash docker run --privileged --rm tonistiigi/binfmt --version ``` + ``` binfmt/9a44d27 qemu/v6.0.0 go/1.15.11 ``` @@ -111,11 +113,11 @@ binfmt/9a44d27 qemu/v6.0.0 go/1.15.11 ## Test current emulation support ``` -docker run --rm arm64v8/alpine uname -a -docker run --rm arm32v7/alpine uname -a -docker run --rm ppc64le/alpine uname -a -docker run --rm s390x/alpine uname -a -docker run --rm tonistiigi/debian:riscv uname -a +docker run --rm --platform linux/arm64/v8 arm64v8/alpine uname -a +docker run --rm --platform linux/arm/v7 arm32v7/alpine uname -a +docker run --rm --platform linux/ppc64le ppc64le/alpine uname -a +docker run --rm --platform linux/s390x s390x/alpine uname -a +docker run --rm --platform linux/riscv64 riscv64/alpine uname -a ``` ## `buildkit` target diff --git a/hack/install-and-test b/hack/install-and-test index e42d2b28..ad94ea3b 100755 --- a/hack/install-and-test +++ b/hack/install-and-test @@ -1,49 +1,76 @@ #!/usr/bin/env bash -. $(dirname $0)/util +. "$(dirname "$0")/util" + set -eu TAG=${TAG:-test} buildxCmd bake $setFlags --load mainline -set -o pipefail -x -docker run --rm --privileged tonistiigi/binfmt:${TAG:-test} --uninstall qemu-* -status=$(docker run --rm --privileged tonistiigi/binfmt:${TAG:-test} --install all) +set -o pipefail + +echo "operation: uninstalling handlers..." +docker run --rm --privileged "tonistiigi/binfmt:${TAG:-test}" --uninstall qemu-* + +echo "operation: installing all handlers..." +status=$(docker run --rm --privileged "tonistiigi/binfmt:${TAG:-test}" --install all) +supported=$(echo "${status}" | jq -r '.supported[]' | xargs) +emulators=$(echo "${status}" | jq -r '.emulators[]' | xargs) + +if checkMatch linux/arm64 "${supported}"; then printSupported "linux/arm64"; fi +if checkMatch linux/amd64 "${supported}"; then printSupported "linux/amd64"; fi +if checkMatch linux/arm/v6 "${supported}"; then printSupported "linux/arm/v6"; fi +if checkMatch linux/arm/v7 "${supported}"; then printSupported "linux/arm/v7"; fi +if checkMatch linux/ppc64le "${supported}"; then printSupported "linux/ppc64le"; fi +if checkMatch linux/riscv64 "${supported}"; then printSupported "linux/riscv64"; fi +if checkMatch linux/386 "${supported}"; then printSupported "linux/386"; fi + +if checkMatch qemu-arm "${emulators}"; then printEmulated "qemu-arm"; fi +if checkMatch qemu-riscv64 "${emulators}"; then printEmulated "qemu-riscv64"; fi + +if ! checkPlatform linux/386 i386/alpine x86_64; then bail 254 "Mismatching platform for 386"; fi +if ! checkPlatform linux/arm64/v8 arm64v8/alpine aarch64; then bail 253 "Mismatching platform for arm64v8"; fi +if ! checkPlatform linux/arm/v6 arm32v6/alpine armv7l; then bail 252 "Mismatching platform for arm32v6"; fi +if ! checkPlatform linux/arm/v7 arm32v7/alpine armv7l; then bail 251 "Mismatching platform for arm32v7"; fi +if ! checkPlatform linux/ppc64le ppc64le/alpine ppc64le; then bail 250 "Mismatching platform for ppc64le"; fi +if ! checkPlatform linux/s390x s390x/alpine s390x; then bail 249 "Mismatching platform for s390x"; fi +if ! checkPlatform linux/riscv64 riscv64/alpine riscv64; then bail 248 "Mismatching platform for riscv64"; fi + +if [ "$(uname -m)" != "x86_64" ]; then bail 0 "$(basename "$0") is not running on x86_64 architecture"; fi -echo $status | jq .supported | grep linux/arm64 -echo $status | jq .supported | grep linux/amd64 -echo $status | jq .supported | grep linux/arm/v7 -echo $status | jq .supported | grep linux/arm/v6 -echo $status | jq .supported | grep linux/riscv64 -echo $status | jq .supported | grep linux/ppc64le -echo $status | jq .supported | grep linux/386 +echo "operation: uninstalling aarch64 and riscv64 handler" +status=$(docker run --rm --privileged "tonistiigi/binfmt:${TAG:-test}" --uninstall aarch64,riscv64) +supported=$(echo "${status}" | jq -r '.supported[]' | xargs) +emulators=$(echo "${status}" | jq -r '.emulators[]' | xargs) -echo $status | jq .emulators | grep qemu-riscv64 -echo $status | jq .emulators | grep qemu-arm +if checkMatch "linux/arm64 ${supported}"; then bail 247 "linux/arm64 should not be supported"; fi +if checkMatch "linux/riscv64 ${supported}"; then bail 246 "linux/riscv64 should not be supported"; fi -docker run --rm arm64v8/alpine uname -a -docker run --rm arm32v7/alpine uname -a -docker run --rm ppc64le/alpine uname -a -docker run --rm s390x/alpine uname -a -docker run --rm i386/alpine uname -a -docker run --rm tonistiigi/debian:riscv uname -a +if checkMatch linux/arm/v6 "${supported}"; then printSupported "linux/arm/v6"; fi +if checkMatch linux/arm/v7 "${supported}"; then printSupported "linux/arm/v7"; fi +if checkMatch linux/ppc64le "${supported}"; then printSupported "linux/ppc64le"; fi -if [ "$(uname -m)" != "x86_64" ]; then exit 0; fi +if checkMatch qemu-aarch64 "${emulators}"; then bail 245 "qemu-aarch64 should not be supported"; fi +if checkMatch qemu-riscv64 "${emulators}"; then bail 244 "qemu-riscv64 should not be supported"; fi -status=$(docker run --rm --privileged tonistiigi/binfmt:${TAG:-test} --uninstall aarch64,riscv64) +if checkMatch qemu-arm "${supported}"; then printEmulated "qemu-arm"; fi +if checkMatch qemu-ppc64le "${supported}"; then printEmulated "qemu-ppc64le"; fi -if echo $status | jq .supported | grep linux/arm64; then exit 1; fi -if echo $status | jq .supported | grep linux/riscv64; then exit 1; fi -echo $status | jq .supported | grep linux/ppc64le -echo $status | jq .supported | grep linux/arm/v7 +if docker run --rm --platform linux/arm64/v8 arm64v8/alpine uname -m 2>/dev/null; then bail 243 "unexpected uname error in linux/arm64/v8"; fi -echo $status | jq .emulators | grep qemu-arm -echo $status | jq .emulators | grep qemu-ppc64le -if echo $status | jq .emulators | grep aarch64; then exit 1; fi -if echo $status | jq .emulators | grep riscv64; then exit 1; fi +echo "operation: installing arm64 handler..." +docker run --rm --privileged "tonistiigi/binfmt:${TAG:-test}" --install arm64 -if docker run --rm arm64v8/alpine uname -a 2>/dev/null; then exit 1; fi +if ! checkPlatform linux/arm64/v8 arm64v8/alpine aarch64; then + bail 242 "Mismatching platform for arm64v8" +else + printSupported "linux/arm64/v8" +fi -docker run --rm --privileged tonistiigi/binfmt:${TAG:-test} --install arm64 -docker run --rm arm64v8/alpine uname -a +echo "operation: installing riscv64 handler..." +docker run --rm --privileged "tonistiigi/binfmt:${TAG:-test}" --install riscv64 -docker run --rm --privileged tonistiigi/binfmt:${TAG:-test} --install riscv64 +if ! checkPlatform linux/riscv64 riscv64/alpine riscv64; then + bail 241 "Mismatching platform for riscv64" +else + printSupported "linux/riscv64" +fi diff --git a/hack/util b/hack/util index 75330093..91c6ba42 100755 --- a/hack/util +++ b/hack/util @@ -1,4 +1,5 @@ #!/usr/bin/env sh + export BUILDX_NO_DEFAULT_LOAD=true : ${CI=} @@ -13,13 +14,13 @@ fi buildxCmd() { if docker buildx version >/dev/null 2>&1; then - set -x + # set -x docker buildx "$@" $progressFlag elif buildx version >/dev/null 2>&1; then - set -x + # set -x buildx "$@" $progressFlag elif docker version >/dev/null 2>&1; then - set -x + # set -x DOCKER_BUILDKIT=1 docker "$@" $progressFlag else echo >&2 "ERROR: Please enable DOCKER_BUILDKIT or install standalone buildx" @@ -40,3 +41,58 @@ if [ "$GITHUB_ACTIONS" = "true" ]; then done fi fi + +bail() { + CODE=$1 + shift + + echo "ERROR: $*" + + exit $CODE +} + +checkMatch() { + NEEDLE=$1 + shift + HAYSTACK="$*" + + if [ "$(echo "${HAYSTACK}" | grep -w "${NEEDLE}")" != "" ]; then + return 0 + else + return 1 + fi +} + +checkPlatform() { + PLATFORM=$1 + IMAGE=$2 + EXPECTED_RESULT=$3 + + RESULT=$(docker run --rm --platform "${PLATFORM}" "${IMAGE}" uname -m 2>&1) + + if [ "${RESULT}" = "${EXPECTED_RESULT}" ]; then + return 0 + else + return 1 + fi +} + +printOK() { + CATEGORY=$1 + shift + MESSAGE=$* + + echo "${CATEGORY}: ${MESSAGE} OK" +} + +printEmulated() { + MESSAGE=$* + + printOK emulated "${MESSAGE}" +} + +printSupported() { + MESSAGE=$* + + printOK supported "${MESSAGE}" +}