processone / ejabberd

Robust, Ubiquitous and Massively Scalable Messaging Platform (XMPP, MQTT, SIP Server)
https://www.process-one.net/ejabberd/
Other
6.12k stars 1.51k forks source link

Update container image generation to build for ARM using direct method #4280

Open badlop opened 2 months ago

badlop commented 2 months ago

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.

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 ```

ARM runner!

Even better news:

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.

sando38 commented 1 month ago

This task is probably still blocked by the issue https://github.com/processone/ejabberd/issues/4178#issuecomment-2135264508 , because the OS packages do not ship the patched Erlang.