Repository navigation
fix: restore remote execution support for apko_image - #379
jeffpignataro wants to merge 3 commits into
Conversation
The apko build action was pinned to local execution in chainguard-dev#332 to work around chainguard-dev#331. The underlying incompatibility is that apko writes into its --cache-dir even with --offline (it creates directories on cache lookup and expands packages into the cache), while Bazel provides the prepopulated cache tree artifact as a read-only action input, which remote executors enforce strictly. Local sandboxes keep directories writable, so this only surfaced under remote execution. - Copy the cache input into a writable scratch directory inside the action and point --cache-dir at it, so the action works on read-only input trees. - Give HOME a writable fallback when the executor does not provide one. - Bind the apko_image and apko_show_config actions to the resolved apko toolchain so an executor never receives a binary built for a different platform than the action is scheduled on. - Remove the no-remote-exec execution requirement from chainguard-dev#332. - Add an opt-in use_default_shell_env attribute (default True, the previous behavior) so users who want a hermetic action environment can drop host env inheritance per target. Verified locally (all tests, examples, and e2e/smoke) and against a Buildbarn-based remote executor: both e2e/smoke image targets build with the apko actions executing on remote linux-amd64 workers from a macOS host. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UgPypJbT7mm4xV1xkE3rqd
|
@jeffpignataro - do you need to do additional testing before taking this out of draft? |
I was just going to have @thesayyn review it on our end before marking it ready for review. I appreciate the proactive approval! |
apko cross-builds images for any target arch, so the comment's framing about arch mismatches was wrong; the toolchain param needs no explanation beyond what it says. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WT4MVMA7GujqmR2YrfqNXM
Mirror the read-only cache tree artifact into the writable scratch directory as real directories containing per-file symlinks rather than cp -RL'ing the whole cache. apko only adds new entries (package expansions) to its --cache-dir and never rewrites existing files, so new writes land in the scratch directories while existing entries are read through the symlinks. This avoids duplicating the full APK cache on every image build. The chmod is no longer needed since apko never writes to the symlinked files. Verified locally (darwin-sandbox) and on a Buildbarn-based remote executor with linux-amd64 workers; layer digests are identical to the copy-based version. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WT4MVMA7GujqmR2YrfqNXM
CopyToWorkdir fails at exit 127 before the apko action is ever scheduled, which hides what chainguard-dev#379 changed. Add a non-blocking follow-up build that runs the staging actions locally, so the apko action reaches the VM and its own missing-coreutils failure shows up in the log. Also trigger on actiond** branches so experiments do not have to land on main. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
xnox
left a comment
There was a problem hiding this comment.
Seems to fail with a minimal remote executor. Let me show you.
So the workflow triggers on the branch chainguard-dev#379 is developed on, not just on main and actiond** experiment branches. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
I wonder if it is a bug in rules_apko or apko itself that it wants writable cache, and seems to unable to handle read-only cache. It sounds like a useful property, and with stock apko we do test this I think as part of regular image building but that is done with direct chainguard container, will check. Separately instead of inventing shell, there seem to be utilities/binaries that can be used or something better basically. |
|
Data point from testing this against a different kind of executor, plus a suggestion. Not a blocker for this PR — as far as I can tell #379 is correct and does exactly what it claims. I ran it against actiond, a local Remote Execution API worker that boots a Linux VM on the machine and runs each action inside an empty chroot in it. It works on GitHub-hosted This PR's core change verifies independently. Dropping What it surfaced. Two
The runner has The mild irony is that the fix here is itself written in coreutils — Concrete way to close it, if it's of interest.
One gap: uutils doesn't ship The general form is that anything a 🤖 Summary generated with Claude Code |
|
@thesayyn @jeffpignataro could you please review #380 ? |
|
Closing in favor of #380 |
CopyToWorkdir fails at exit 127 before the apko action is ever scheduled, which hides what #379 changed. Add a non-blocking follow-up build that runs the staging actions locally, so the apko action reaches the VM and its own missing-coreutils failure shows up in the log. Also trigger on actiond** branches so experiments do not have to land on main.
So the workflow triggers on the branch #379 is developed on, not just on main and actiond** experiment branches.
Summary
#332 disabled remote execution for the
apko_imagebuild action (no-remote-exec) to work around #331. This PR fixes the underlying incompatibilities so the action runs on remote executors again, and removes the opt-out. It also un-breaks setups that run--spawn_strategy=remotewith no local fallback, which theno-remote-execrequirement made impossible (as noted in the #332 discussion).Root cause of #331: apko writes into its
--cache-direven with--offline— it creates directories on cache lookup and expands packages into the cache (os.MkdirAllinpkg/apk/apk/package_getter.go). Bazel supplies the prepopulated cache tree artifact as a read-only action input, which remote executors enforce strictly; local sandboxes keep directories writable, which is why this only surfaced on RBE (unable to create cache directory ...: permission denied).Changes:
mktemp -d) and points--cache-dirat it, so it works on read-only input trees. The flag is passed at the same precedence as before (after userargs).HOMEgets a writable fallback when the executor doesn't provide one (HOME="${HOME:-$SCRATCH/home}"); when the environment hasHOME, behavior is unchanged.apko_imageandapko_show_configactions are bound to the resolved apko toolchain viatoolchain = "@rules_apko//apko:toolchain_type", so the execution platform always matches the platform the apko binary was resolved for — under Bazel 9's platform ordering an executor could otherwise receive a wrong-OS binary.execution_requirements = {"no-remote-exec": "1"}. Users who need local execution can still usetags = ["no-remote-exec"]or--strategy.use_default_shell_envattribute onapko_image(defaultTrue, the existing behavior) for users who want a hermetic action environment. Existing targets are unaffected: the attribute name was previously rejected at load time, so no current usage can change meaning, and the flag only alters the action's environment — verified viaaquerythat command lines are byte-identical either way.Test plan
bazel test //..., allexamples/, ande2e/smokepass locally;e2e/smokegains alock_hermetic_envtarget coveringuse_default_shell_env = False.e2e/smokeimage targets built successfully with the apko actions executing remotely (3 processes: 1 internal, 2 remote). Repro shape:bazel build //:lock //:lock_hermetic_env --remote_executor=<endpoint> --extra_execution_platforms=<linux platform whose exec_properties match the worker pool>.