From 22379813b6d949c94709c6c71d5249f57d6e3706 Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Thu, 16 Jan 2025 15:35:24 -0800 Subject: [PATCH] Support GitHub Actions aarch64 runners GitHub now offers free aarch64 runners: https://github.blog/changelog/2025-01-16-linux-arm64-hosted-runners-now-available-for-free-in-public-repositories-public-preview/ Automatically select the default apk-tools-url and arch to match the CPU architecture of the current runner. Run armv7 and armhf without QEMU on aarch64 runners. For symmetry, allow emulating x86 and x86_64 on aarch64. Document how to run aarch64 without emulation. Change existing aarch64 examples to s390x, to avoid encouraging emulation of aarch64. Fixes #11. --- .github/workflows/ci.yml | 11 +++++++++-- README.adoc | 41 +++++++++++++++++++++++++++------------- action.yml | 11 +++++++---- binfmts/qemu-i386 | 8 ++++++++ binfmts/qemu-x86_64 | 8 ++++++++ setup-alpine.sh | 11 +++++++++++ 6 files changed, 71 insertions(+), 19 deletions(-) create mode 100644 binfmts/qemu-i386 create mode 100644 binfmts/qemu-x86_64 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 56b5dd5..a37d8de 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,11 +10,13 @@ jobs: - edge arch: - x86_64 - - aarch64 # emulated + - aarch64 host-os: - ubuntu-latest - ubuntu-24.04 - ubuntu-22.04 + - ubuntu-24.04-arm + - ubuntu-22.04-arm runs-on: ${{ matrix.host-os }} env: MY_JOB_VAR: 'allons-y!' @@ -86,7 +88,12 @@ jobs: run: test -f "${{ steps.setup-alpine.outputs.root-path }}"/etc/alpine-release test-multi: - runs-on: ubuntu-latest + runs-on: ${{ matrix.host-os }} + strategy: + matrix: + host-os: + - ubuntu-latest + - ubuntu-24.04-arm steps: - uses: actions/checkout@v4 diff --git a/README.adoc b/README.adoc index 4479d9f..11cb573 100644 --- a/README.adoc +++ b/README.adoc @@ -53,13 +53,13 @@ URL of the apk-tools static binary to use. It must end with `#!sha256!` followed by a SHA-256 hash of the file. This should normally be left at the default value. + -Default: _see link:action.yml[]_ +Default: _see link:setup-alpine.sh[]_ [[arch]] arch:: CPU architecture to emulate using https://www.qemu.org/docs/master/user/main.html[QEMU user space emulator]. -Allowed values are: `x86_64` (native), `x86` (native), `aarch64`, `armhf` footnote:[armhf is armv6 with hard-float.], `armv7`, `loongarch64` footnote:[loongarch64 is available since v3.21.], `ppc64le`, `riscv64` footnote:[riscv64 is available since v3.20.], and `s390x`. +Allowed values are: `x86_64` (native on x86_64), `x86` (native on x86_64), `aarch64` (native on aarch64), `armhf` footnote:[armhf is armv6 with hard-float.] (native on aarch64), `armv7` (native on aarch64), `loongarch64` footnote:[loongarch64 is available since v3.21.], `ppc64le`, `riscv64` footnote:[riscv64 is available since v3.20.], and `s390x`. + -Default: `x86_64` +Default: _runner's native architecture_ branch:: Alpine branch (aka release) to install: `vMAJOR.MINOR`, `latest-stable`, or `edge`. @@ -159,19 +159,34 @@ steps: ---- +=== Set up and use Alpine natively on aarch64 + +[source, yaml, subs="+attributes"] +---- +runs-on: ubuntu-24.04-arm +steps: + - name: Setup latest Alpine Linux + uses: {action-ref} + + - name: Run script inside Alpine chroot + run: uname -m + shell: alpine.sh {0} +---- + + === Set up and use Alpine for a different CPU architecture [source, yaml, subs="+attributes"] ---- runs-on: ubuntu-latest steps: - - name: Setup Alpine Linux {alpine-latest} for aarch64 + - name: Setup Alpine Linux {alpine-latest} for s390x uses: {action-ref} with: - arch: aarch64 + arch: s390x branch: {alpine-latest} - - name: Run script inside Alpine chroot with aarch64 emulation + - name: Run script inside Alpine chroot with s390x emulation run: uname -m shell: alpine.sh {0} ---- @@ -200,19 +215,19 @@ steps: with: shell-name: alpine-x86_64.sh - - name: Setup latest Alpine Linux for aarch64 + - name: Setup latest Alpine Linux for s390x uses: {action-ref} with: - arch: aarch64 - shell-name: alpine-aarch64.sh + arch: s390x + shell-name: alpine-s390x.sh - name: Run script inside Alpine chroot run: uname -m shell: alpine-x86_64.sh {0} - - name: Run script inside Alpine chroot with aarch64 emulation + - name: Run script inside Alpine chroot with s390x emulation run: uname -m - shell: alpine-aarch64.sh {0} + shell: alpine-s390x.sh {0} - name: Run script on the host system (Ubuntu) run: cat /etc/os-release @@ -229,8 +244,8 @@ runs-on: ubuntu-latest strategy: matrix: include: - - rust-target: aarch64-unknown-linux-musl - os-arch: aarch64 + - rust-target: s390x-unknown-linux-musl + os-arch: s390x env: CROSS_SYSROOT: /mnt/alpine-${{ matrix.os-arch }} steps: diff --git a/action.yml b/action.yml index 61dd1d3..a9f5f60 100644 --- a/action.yml +++ b/action.yml @@ -12,13 +12,16 @@ inputs: hash of the file. This should normally be left at the default value. required: false - default: https://gitlab.alpinelinux.org/api/v4/projects/5/packages/generic/v2.14.7/x86_64/apk.static#!sha256!bdd044e0fd6cc388c5e571e1093efa5f35f7767cc5aa338b0a2576a429009a62 + default: '' arch: description: > - CPU architecture to emulate using QEMU. Allowed values are: `x86_64` (native), `x86` (native), - `aarch64`, `armhf` (armv6 with hard-float), `armv7`, `loongarch64` (available since v3.21), `ppc64le`, `riscv64` (available since v3.20), and `s390x` + CPU architecture to emulate using QEMU. Allowed values are: `x86_64` (native on x86_64), + `x86` (native on x86_64), `aarch64` (native on aarch64), `armhf` (armv6 with hard-float; + native on aarch64), `armv7` (native on aarch64), `loongarch64` (available since v3.21), + `ppc64le`, `riscv64` (available since v3.20), `s390x`, or the empty string to use the + runner's native architecture. required: false - default: x86_64 + default: '' branch: description: Alpine branch (aka release) to install (e.g. `v3.15`, `latest-stable`, `edge`). required: false diff --git a/binfmts/qemu-i386 b/binfmts/qemu-i386 new file mode 100644 index 0000000..788b5c4 --- /dev/null +++ b/binfmts/qemu-i386 @@ -0,0 +1,8 @@ +package none +interpreter /usr/local/bin/qemu-i386 +magic \x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00 +offset 0 +mask \xff\xff\xff\xff\xff\xfe\xfe\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff +credentials yes +fix_binary yes +preserve yes diff --git a/binfmts/qemu-x86_64 b/binfmts/qemu-x86_64 new file mode 100644 index 0000000..80d0bc8 --- /dev/null +++ b/binfmts/qemu-x86_64 @@ -0,0 +1,8 @@ +package none +interpreter /usr/local/bin/qemu-x86_64 +magic \x7f\x45\x4c\x46\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x3e\x00 +offset 0 +mask \xff\xff\xff\xff\xff\xfe\xfe\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff +credentials yes +fix_binary yes +preserve yes diff --git a/setup-alpine.sh b/setup-alpine.sh index 6862376..934d6c2 100755 --- a/setup-alpine.sh +++ b/setup-alpine.sh @@ -84,6 +84,7 @@ needs_emulator() { local host="$(qemu_arch "$(uname -m)")" [ "$target" = "$host" ] && return 1 + [ "$host" = aarch64 ] && [ "$target" = arm ] && return 1 [ "$host" = x86_64 ] && [ "$target" = i386 ] && return 1 return 0 } @@ -133,12 +134,22 @@ mount_bind() { case "$INPUT_APK_TOOLS_URL" in https://*\#\!sha256\!* | http://*\#\!sha256\!*) ;; # valid + "") + # default + case "$(uname -m)" in + x86_64) INPUT_APK_TOOLS_URL="https://gitlab.alpinelinux.org/api/v4/projects/5/packages/generic/v2.14.7/x86_64/apk.static#!sha256!bdd044e0fd6cc388c5e571e1093efa5f35f7767cc5aa338b0a2576a429009a62" ;; + aarch64) INPUT_APK_TOOLS_URL="https://gitlab.alpinelinux.org/api/v4/projects/5/packages/generic/v2.14.7/aarch64/apk.static#!sha256!27a975638ddc95a411c9f17c63383e335da9edf6bb7de2281d950c291a11f878" ;; + *) die "Runner has unexpected CPU architecture $(uname -m)" \ + "Manually configure apk-tools-url for the runner's CPU architecture." ;; + esac + ;; *) die 'Invalid input parameter: apk-tools-url' \ "The value must start with https:// or http:// and end with '#!sha256!' followed by a SHA-256 hash of the file to be downloaded, but got: $INPUT_APK_TOOLS_URL" esac case "$INPUT_ARCH" in x86_64 | x86 | aarch64 | armhf | armv7 | loongarch64 | ppc64le | riscv64 | s390x) ;; # valid + "") INPUT_ARCH="$(uname -m)" ;; # default *) die 'Invalid input parameter: arch' \ "Expected one of: x86_64, x86, aarch64, armhf, armv7, loongarch64, ppc64le, riscv64, s390x, but got: $INPUT_ARCH." esac