Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/publish-tool-images.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ jobs:
- {name: terraform, kind: toolcache}
- {name: tflint, kind: toolcache}
- {name: awscli, kind: toolcache}
- {name: strace, kind: toolcache}
- {name: openmpi, kind: sysroot}
- {name: highs, kind: sysroot}
- {name: libpq, kind: sysroot}
Expand Down Expand Up @@ -134,6 +135,7 @@ jobs:
- {name: terraform, kind: toolcache}
- {name: tflint, kind: toolcache}
- {name: awscli, kind: toolcache}
- {name: strace, kind: toolcache}
- {name: openmpi, kind: sysroot}
- {name: highs, kind: sysroot}
- {name: libpq, kind: sysroot}
Expand Down
2 changes: 1 addition & 1 deletion roles/github_runner_arc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ A tool image is any image that has:

`<tool>` and `<version>` are what the consuming setup action looks up: `node` and the plain version (`24.21.0`, no leading `v`) for `actions/setup-node`, `tflint` and the version without its `v` for `setup-tflint`. `<arch>` is named the way that action names the architecture, and actions differ: `actions/setup-node` uses Node's `os.arch()` (`x64`, `arm64`), while `setup-tflint` maps `x64` to `amd64` (`amd64`, `arm64`). For a tool used only through `path` the name does not matter, since `path` finds whichever architecture is there; the reference images use `os.arch()` names, the tool cache's own default. A multi-architecture image holds, for each platform, only that platform's `<arch>` directory, so the tool cache in any one pod has one architecture per tool, which is what `path` relies on. `path` adds `<tool>/<version>/<arch>[/<subdirectory>]` for the one `<arch>` with a `.complete` marker, and the job fails at its start if there is none or more than one.

`tool-images/` holds Dockerfiles for reference images following this contract: Node.js, Terraform, TFLint and the AWS CLI. Each downloads the official release for the target architecture in a first stage, verifies it (against the release's checksums, and for Terraform and the AWS CLI against the vendor's signing key, pinned by fingerprint), lays it out under `/toolcache`, and copies that into `busybox`, which supplies `sh`, `cp` and `rm`. To build one yourself, for both architectures:
`tool-images/` holds Dockerfiles for reference images following this contract: Node.js, Terraform, TFLint, the AWS CLI and strace. Each downloads the official release for the target architecture in a first stage (strace builds its source release into one static executable), verifies it (against the release's checksums, and for Terraform, the AWS CLI and strace against the vendor's signing key, pinned by fingerprint), lays it out under `/toolcache`, and copies that into `busybox`, which supplies `sh`, `cp` and `rm`. To build one yourself, for both architectures:

```sh
docker buildx build --platform linux/amd64,linux/arm64 --build-arg NODE_VERSION=24.21.0 \
Expand Down
36 changes: 36 additions & 0 deletions tool-images/strace/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Tool-cache capability image for strace, following the tool-image contract in roles/github_runner_arc/README.md (Capabilities): /toolcache/strace/<version>/<arch>/strace is one statically linked executable, with <arch>.complete beside it, and <arch> is Node's os.arch() name (x64 or arm64), the tool cache's own default. No setup action looks strace up in the tool cache, so this capability is meant to be declared with path: strace/<version>, which puts strace on PATH at job start. It is linked statically so it needs nothing of the runner image's libraries, and without a Linux capability: a runner pod's processes may trace their own descendants (ptrace_scope 1), which is all a job tracing its own test run needs. The final stage is busybox, which supplies the sh, cp, rm and chmod the role's init containers run.
#
# Build for both architectures: docker buildx build --platform linux/amd64,linux/arm64 --build-arg STRACE_VERSION=<version> --build-arg STRACE_SHA256=<digest of that release's tarball> -t <registry>/<name>:<version> tool-images/strace
FROM alpine:3.22 AS build
SHELL ["/bin/ash", "-eo", "pipefail", "-c"]
ARG STRACE_VERSION=7.2
ARG TARGETARCH
# The SHA-256 of the release tarball, and the fingerprint of the key that signs the releases (the strace maintainer's primary key, whose signing subkey made this release's signature), both to be re-derived when the version is raised.
ARG STRACE_SHA256=4bde6246926890dcee824f6e6ac42a06752f47d77e5097d86e3c0d6d4b709fe5
ARG STRACE_KEY_FINGERPRINT=7BECFE3AF7B280BB52FF77F104BA4521C996DDE1
RUN apk add --no-cache build-base linux-headers curl gnupg xz
WORKDIR /build
# The tarball is checked against the digest above and its detached signature against the key with the fingerprint above, so neither a changed release asset nor a changed key alone can pass.
RUN release="https://github.com/strace/strace/releases/download/v${STRACE_VERSION}" \
&& curl -fsSLO "${release}/strace-${STRACE_VERSION}.tar.xz" \
&& curl -fsSLO "${release}/strace-${STRACE_VERSION}.tar.xz.asc" \
&& echo "${STRACE_SHA256} strace-${STRACE_VERSION}.tar.xz" | sha256sum -c - \
&& curl -fsSL "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x${STRACE_KEY_FINGERPRINT}" | gpg --batch --import \
&& gpg --batch --with-colons --fingerprint | grep -q "^fpr:::::::::${STRACE_KEY_FINGERPRINT}:" \
&& gpg --batch --verify "strace-${STRACE_VERSION}.tar.xz.asc" "strace-${STRACE_VERSION}.tar.xz"
# One executable with no shared library and no personality (32-bit) support, which needs a multilib toolchain.
RUN case "${TARGETARCH}" in amd64) arch=x64 ;; arm64) arch=arm64 ;; *) echo "unsupported architecture: ${TARGETARCH}" >&2; exit 1 ;; esac \
&& tar -xJf "strace-${STRACE_VERSION}.tar.xz" \
&& cd "strace-${STRACE_VERSION}" \
&& ./configure --enable-mpers=no LDFLAGS=-static \
&& make -j"$(nproc)" \
&& strip src/strace \
&& ! ldd src/strace >/dev/null 2>&1 \
&& destination="/toolcache/strace/${STRACE_VERSION}/${arch}" \
&& mkdir -p "${destination}" \
&& cp src/strace "${destination}/strace" \
&& touch "${destination}.complete" \
&& chmod -R a+rX /toolcache

FROM busybox:1.37
COPY --from=build /toolcache /toolcache
Loading