Repository navigation
Conversation
tool-images/build takes RUNNER_UID and RUNNER_GID, the stock 1001 unless set, and moves every file the stock ids owned to the new ones. Under hostUsers: false a runner pod's hostPath volumes are mounted idmapped, so the node cache and capability store files belong on the node to the runner's own uid, which on some nodes is a person's account. The publish workflow builds a build runner entry with a runner_id under the tag <runner version>-uid<id>, and names each digest artifact with the architecture before the tag so one tag's pattern never matches another's. tests/runner_build/run.sh checks both sets of ids on amd64 and arm64.
|
Published If this branch changes, the tag is republished only through this workflow (after the old tag is deleted, since the workflow skips an existing tag), and the pin moves with it.
|
A runner pod that runs with
hostUsers: falsegets its hostPath volumes (the node cache and the capability store) mounted idmapped, and the mapping keeps the container's uid as the node's: on a node, every file in<node cache>/<namespace>/<release>/pnpm-storeand in the capability store is owned by uid and gid 1001, the stock runner user's. On a fleet I run, 1001 is a person's login account on some nodes and the operator's own account on others, so that person owns the CI's shared pnpm store and the tool copies every job runs, and can change them. The role already takesgithub_runner_arc_runner_uidandgithub_runner_arc_runner_gidfor "an image with a different runner user", but no reference image has one.tool-images/buildnow takesRUNNER_UIDandRUNNER_GID(1001 unless set). When one differs it runsgroupmod/usermodand moves every file the old ids owned to the new ones. groupmod and usermod refuse an id the image already uses. With the default ids the step changes no file, and the published2.338.0tag is never rebuilt anyway. A build runner entry inpublish-tool-images.ymlwith arunner_idbuilds the same Dockerfile with both set to that id and tags it<runner version>-uid<id>. I added one for 549, an id in the middle of the system range that the fleet reserves for the runner's own account. Digest artifacts are now named with the architecture before the tag (digests-<kind>-<name>-<arch>-<tag>), because...-2.338.0-*would also have matched the2.338.0-uid549artifacts and joined four digests under one tag.Tested:
tests/runner_build/run.sh(new, run by the newrunner-build.ymlon amd64 and arm64) builds both and checks the runner's uid, gid, name and group, the docker group, no file left with the old ids, a writable home,Runner.Listener --version,sudo -n trueandcc, and thatRUNNER_UID=0is refused. It passed on an arm64 Mac's Docker. Dropping thechgrpstep makes it fail on/home/runner. I also built the 549 variant for amd64 under emulation and checkedid,sudo, a writable home and no file owned by 1001.tests/unit/test_publish_tool_images.pyruns each entry's image step to get its tag, then checks three things: build and merge list the same entries, arunner_identry gets both build arguments and the suffix, and each tag's download pattern matches exactly its own two artifacts. It fails when the pattern is put back to-*. It passed inpython:3.12-slim. On macOS it cannot pass, because BSDwc -lpads its output, and that affects the step's own check, not just the test. actionlint, shellcheck, hadolint and yamllint are clean on the changed files.This overlaps #149, which also edits the matrix and artifact names. Whichever lands second rebases onto the other: both can keep the architecture-before-tag naming, and a
versionentry composes withrunner_id.Order once merged:
gh workflow run publish-tool-images.yml, make the new tag's package public if needed (it is the existinggithub-runner-runner-buildpackage, so it already is), and take the2.338.0-uid549@sha256:...reference from the run summary.