Unfortunately, QEMU + arm64 + Erlang/OTP 25/26/27 crashes with segmentation fault. The temporary workaround applied since ejabberd 23.04 is to use the binary installers (and Dockerfile uses METHOD=package), as detailed in #3983.
QEMU is fixed!
Good news: the original problem is solved in QEMU 8.1.0, so we can revert that temporary workaround and use a newer QEMU to build the container images from source directly again.
This patch contains:
* Use QEMU 8.1.5 which includes the fix for arm64 crash
```
The QEMU issue is
https://gitlab.com/qemu-project/qemu/-/issues/1034
The fix commit is
https://gitlab.com/qemu-project/qemu/-/commit/9719f125b803f4e0fda834cd74a60dfa4ca398e2
which was first included in QEMU 8.1.0, so 8.1.5 should be good
```
* Update Erlang to 27.0 and Elixir to 1.17.3 to fix arm compilation
```
Erlang 27.1 is not yet available in https://hub.docker.com/_/erlang
Compiling with Erlang 26.2 crashes with:
==> eex (compile)
=ERROR REPORT==== 20-Sep-2024::11:58:41.754278 ===
Error in process <0.115.0> with exit value:
{function_clause,
[{'Elixir.Module.Types','-warnings/5-inlined-1-',
[{column,8}],
[{file,"lib/module/types.ex"},{line,13}]},
{'Elixir.Enum',flat_map_list,2,[{file,"lib/enum.ex"},{line,4353}]},
{'Elixir.Module.ParallelChecker',check_module,3,
[{file,"lib/module/parallel_checker.ex"},{line,264}]},
{'Elixir.Module.ParallelChecker','-spawn/4-fun-0-',6,
[{file,"lib/module/parallel_checker.ex"},{line,82}]}]}
```
* TODO: Remove in Dockerfile the `METHOD=package` and all associated lines, as they would be unnecessary
```diff
diff --git a/.github/container/Dockerfile b/.github/container/Dockerfile
index f9a97e0af..e592d6e7d 100644
--- a/.github/container/Dockerfile
+++ b/.github/container/Dockerfile
@@ -1,7 +1,7 @@
#' Define default build variables
## specifc ARGs for METHOD='direct'
-ARG OTP_VSN='26.2'
-ARG ELIXIR_VSN='1.16.2'
+ARG OTP_VSN='27.0'
+ARG ELIXIR_VSN='1.17.3'
## specifc ARGs for METHOD='package'
ARG ALPINE_VSN='3.19'
## general ARGs
diff --git a/.github/workflows/container.yml b/.github/workflows/container.yml
index 33ae16960..53e7d204c 100644
--- a/.github/workflows/container.yml
+++ b/.github/workflows/container.yml
@@ -1,8 +1,6 @@
name: Container
on:
- schedule:
- - cron: '22 2 */6 * *' # every 6 days to avoid gha cache being evicted
push:
paths-ignore:
- '.devcontainer/**'
@@ -28,52 +26,6 @@ jobs:
with:
fetch-depth: 0
- - name: Cache build directory
- uses: actions/cache@v4
- with:
- path: ~/build/
- key: ${{runner.os}}-ctr-ct-ng-1.26.0
-
- - name: Get erlang/OTP version for bootstrapping
- run: |
- echo "OTP_VSN=$(awk '/^otp_vsn=/ {{gsub(/[^0-9.rc-]/, ""); print}}' tools/make-binaries)" >> $GITHUB_ENV
- echo "ELIXIR_VSN=$(awk '/^elixir_vsn=/ {{gsub(/[^0-9.]/, ""); print}}' tools/make-binaries)" >> $GITHUB_ENV
-
- - name: Install prerequisites
- run: |
- sudo apt-get -qq update
- sudo apt-get -qq install makeself
- # https://github.com/crosstool-ng/crosstool-ng/blob/master/testing/docker/ubuntu21.10/Dockerfile
- sudo apt-get -qq install build-essential autoconf bison flex gawk
- sudo apt-get -qq install help2man libncurses5-dev libtool libtool-bin
- sudo apt-get -qq install python3-dev texinfo unzip
-
- - name: Install erlang/OTP
- uses: erlef/setup-beam@v1
- with:
- otp-version: ${{ env.OTP_VSN }}
- elixir-version: ${{ env.ELIXIR_VSN }}
- version-type: strict
-
- - name: Remove Elixir Matchers
- run: |
- echo "::remove-matcher owner=elixir-mixCompileWarning::"
- echo "::remove-matcher owner=elixir-credoOutputDefault::"
- echo "::remove-matcher owner=elixir-mixCompileError::"
- echo "::remove-matcher owner=elixir-mixTestFailure::"
- echo "::remove-matcher owner=elixir-dialyzerOutputDefault::"
-
- - name: Build musl-libc based binary archives
- run: |
- sed -i "s|targets='.*'|targets='x86_64-linux-musl aarch64-linux-musl'|" tools/make-binaries
- mv .github/container/ejabberdctl.template .
- CHECK_DEPS=false tools/make-binaries
-
- - name: Collect packages
- run: |
- mkdir tarballs
- mv ejabberd-*.tar.gz tarballs
-
- name: Checkout ejabberd-contrib
uses: actions/checkout@v4
with:
@@ -103,6 +55,8 @@ jobs:
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
+ with:
+ image: tonistiigi/binfmt:qemu-v8.1.5
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
@@ -111,7 +65,6 @@ jobs:
uses: docker/build-push-action@v6
with:
build-args: |
- METHOD=package
VERSION=${{ steps.gitdescribe.outputs.ver }}
cache-from: type=gha
cache-to: type=gha,mode=max
```
We expect to begin offering Arm runners for open source projects by the end of the year.
That would allow us to generate arm64 container images without using QEMU at all: faster image generation and smaller build scripts (Dockerfile and container.yml).
Proposal
Maybe, instead of switching now to QEMU 8.1.0 and build image directly from source, we can wait a few months and jump directly to the definitive solution: build ARM image using ARM-based runner.
And once that simplification is done, #4261 can be updated and finally applied.
Summary of past events
ejabberd 22.05 introduced the
ejabberd
container image, generated in Github Actions with variants for amd64... and arm64 thanks to QEMU.Unfortunately, QEMU + arm64 + Erlang/OTP 25/26/27 crashes with segmentation fault. The temporary workaround applied since ejabberd 23.04 is to use the binary installers (and Dockerfile uses
METHOD=package
), as detailed in #3983.QEMU is fixed!
Good news: the original problem is solved in QEMU 8.1.0, so we can revert that temporary workaround and use a newer QEMU to build the container images from source directly again.
ARM runner!
Even better news:
That would allow us to generate arm64 container images without using QEMU at all: faster image generation and smaller build scripts (
Dockerfile
andcontainer.yml
).Proposal
Maybe, instead of switching now to QEMU 8.1.0 and build image directly from source, we can wait a few months and jump directly to the definitive solution: build ARM image using ARM-based runner.
And once that simplification is done, #4261 can be updated and finally applied.