You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2026/08/30 10:56:28 UTC

(skywalking-swck) branch fix-multiarch-targetarch-default created (now 9612d7f)

This is an automated email from the ASF dual-hosted git repository.

wu-sheng pushed a change to branch fix-multiarch-targetarch-default
in repository https://gitbox.apache.org/repos/asf/skywalking-swck.git


      at 9612d7f  Declare TARGETARCH with no default, so buildx can actually set it

This branch includes the following new commits:

     new 9612d7f  Declare TARGETARCH with no default, so buildx can actually set it

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(skywalking-swck) 01/01: Declare TARGETARCH with no default, so buildx can actually set it

Posted by wu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

wu-sheng pushed a commit to branch fix-multiarch-targetarch-default
in repository https://gitbox.apache.org/repos/asf/skywalking-swck.git

commit 9612d7fe16271b50bdaee174f0928e8e41eca22f
Author: Wu Sheng <wu...@foxmail.com>
AuthorDate: Sun Aug 30 18:56:21 2026 +0800

    Declare TARGETARCH with no default, so buildx can actually set it
    
    The arm64 fix did not work. Each Dockerfile declared `ARG TARGETARCH=amd64`, and giving a
    predefined platform argument a default makes BuildKit treat it as an ordinary build argument
    and use that default -- so TARGETARCH read amd64 even when the target was linux/arm64. The
    builder stage, pinned to BUILDPLATFORM, therefore ran exactly once, and its amd64 binary was
    copied into both manifests. Verified directly against the published image: the arm64 entry of
    ghcr.io/apache/skywalking-swck/operator:eb86203 has a config saying architecture arm64 and a
    /manager that is ELF x86-64.
    
    The default was added deliberately, to keep a plain `docker build` working for the e2e
    suites. It also broke that: on an arm64 host `make docker-build` was producing amd64 binaries
    for a kind cluster that wanted native ones. The shell fallback keeps that case working
    without shadowing what buildx supplies.
    
    Confirmed with an A/B build before and after -- `ARG TARGETARCH=amd64` reports amd64 when
    building for arm64, a bare `ARG TARGETARCH` reports arm64 -- and by building the operator
    image for each platform and reading the ELF header of the binary inside: aarch64 for arm64,
    x86-64 for amd64, native for a plain build.
    
    The publish workflow's ELF verification is what caught this. That workflow had never once run
    to completion before, because its actions were pinned to SHAs outside the ASF allow-list and
    the gateway rejected it before any job started; the run on the merge commit was the first,
    and it failed on exactly the check written for this.
---
 adapter/Dockerfile              | 15 ++++++++-------
 build/images/Dockerfile.release | 14 +++++---------
 docs/en/changes/changes.md      |  3 +++
 operator/Dockerfile             | 15 ++++++++-------
 4 files changed, 24 insertions(+), 23 deletions(-)

diff --git a/adapter/Dockerfile b/adapter/Dockerfile
index 32c4e60..25c8944 100644
--- a/adapter/Dockerfile
+++ b/adapter/Dockerfile
@@ -32,13 +32,14 @@ COPY main.go main.go
 COPY pkg/ pkg/
 
 # Build
-# TARGETARCH is supplied per platform by buildx. .github/workflows/publish-docker.yml
-# builds this image for linux/amd64 AND linux/arm64, and now stamps release version tags
-# on the result; a hardcoded GOARCH=amd64 would put an amd64 binary inside the arm64
-# manifest, so every arm64 node would fail with "exec format error". The default keeps a
-# plain `docker build` (make docker-build, used by the e2e suites) building amd64 as before.
-ARG TARGETARCH=amd64
-RUN CGO_ENABLED=0 GOOS=linux GOARCH=${TARGETARCH} GO111MODULE=on go build -a -o adapter main.go
+# TARGETARCH is supplied per platform by buildx, and MUST be declared with no default. Giving a
+# predefined platform argument a default makes BuildKit treat it as an ordinary build argument and
+# use that default, so `ARG TARGETARCH=amd64` reported amd64 even when building for arm64 -- which
+# put an amd64 binary inside the arm64 manifest, the exact failure this was meant to prevent. The
+# shell default below covers a plain `docker build` (make docker-build, used by the e2e suites),
+# where the variable may be unset.
+ARG TARGETARCH
+RUN CGO_ENABLED=0 GOOS=linux GOARCH=${TARGETARCH:-$(go env GOARCH)} GO111MODULE=on go build -a -o adapter main.go
 
 # Use distroless as minimal base image to package the manager binary
 # Refer to https://github.com/GoogleContainerTools/distroless for more details
diff --git a/build/images/Dockerfile.release b/build/images/Dockerfile.release
index c0dd2df..4333568 100644
--- a/build/images/Dockerfile.release
+++ b/build/images/Dockerfile.release
@@ -52,15 +52,11 @@ RUN set -eux; \
 
 FROM gcr.io/distroless/static:nonroot
 WORKDIR /
-# TARGETARCH is supplied per platform by buildx, and the release tarball carries a binary per
-# supported architecture (operator/Makefile and adapter/Makefile release-build).
-#
-# Hardcoding -linux-amd64 here is how apache/skywalking-swck:0.10.0 came to advertise linux/arm64
-# while its arm64 manifest reused the amd64 layers byte for byte: /manager inside it is an x86-64
-# ELF, so an arm64 node gets "exec format error". Selecting on TARGETARCH is what makes the
-# multi-platform manifest honest, and it fails the build loudly -- rather than silently shipping
-# the wrong binary -- if a release tarball does not carry that architecture.
-ARG TARGETARCH=amd64
+# TARGETARCH is supplied per platform by buildx, and MUST be declared with no default: giving a
+# predefined platform argument a default makes BuildKit use that default instead of the target's
+# architecture, which is how an amd64 binary ended up inside an arm64 manifest. The release tarball
+# carries a binary per architecture and this selects the right one.
+ARG TARGETARCH
 COPY --from=builder --chown=65532:65532 /swck/bin/manager-linux-${TARGETARCH} /manager
 COPY --from=builder --chown=65532:65532 /swck/bin/adapter-linux-${TARGETARCH} /adapter
 USER 65532:65532
diff --git a/docs/en/changes/changes.md b/docs/en/changes/changes.md
index 3035077..9ff155d 100644
--- a/docs/en/changes/changes.md
+++ b/docs/en/changes/changes.md
@@ -1,5 +1,8 @@
 ## 0.11.0
 
+#### Bugs
+- Build genuinely multi-architecture images, again. The previous fix declared `ARG TARGETARCH=amd64` in each Dockerfile, and giving a *predefined* platform argument a default makes BuildKit use that default instead of the target's architecture -- so `TARGETARCH` read `amd64` even when building for `linux/arm64`, the builder stage ran once, and the amd64 binary was copied into the arm64 manifest. The publish workflow's own ELF check caught it on the first run that was ever able to start.  [...]
+
 #### Features
 - Release the `skywalking-swck` Helm chart from this repository. One chart installs the operator and, behind a values flag, the custom metrics adapter. The CRDs, the operator's ClusterRole and the admission webhook configurations it ships are generated from the operator sources by `make chart-manifests`, and CI fails on any drift.
 
diff --git a/operator/Dockerfile b/operator/Dockerfile
index e50bf6a..e9d9e51 100644
--- a/operator/Dockerfile
+++ b/operator/Dockerfile
@@ -34,13 +34,14 @@ COPY controllers/ controllers/
 COPY pkg/ pkg/
 
 # Build
-# TARGETARCH is supplied per platform by buildx. .github/workflows/publish-docker.yml
-# builds this image for linux/amd64 AND linux/arm64, and now stamps release version tags
-# on the result; a hardcoded GOARCH=amd64 would put an amd64 binary inside the arm64
-# manifest, so every arm64 node would fail with "exec format error". The default keeps a
-# plain `docker build` (make docker-build, used by the e2e suites) building amd64 as before.
-ARG TARGETARCH=amd64
-RUN CGO_ENABLED=0 GOOS=linux GOARCH=${TARGETARCH} GO111MODULE=on go build -a -o manager main.go
+# TARGETARCH is supplied per platform by buildx, and MUST be declared with no default. Giving a
+# predefined platform argument a default makes BuildKit treat it as an ordinary build argument and
+# use that default, so `ARG TARGETARCH=amd64` reported amd64 even when building for arm64 -- which
+# put an amd64 binary inside the arm64 manifest, the exact failure this was meant to prevent. The
+# shell default below covers a plain `docker build` (make docker-build, used by the e2e suites),
+# where the variable may be unset.
+ARG TARGETARCH
+RUN CGO_ENABLED=0 GOOS=linux GOARCH=${TARGETARCH:-$(go env GOARCH)} GO111MODULE=on go build -a -o manager main.go
 
 # Use distroless as minimal base image to package the manager binary
 # Refer to https://github.com/GoogleContainerTools/distroless for more details