Step 21 session C: BwrapBuildRunner delegates to the werkdock CLI
The runner no longer assembles raw bwrap argv: it checks image existence via 'werkdock images', loads the rootfs archive once per source as image werkator-buildenv-<hash> into werkdock's store (shared across every repository of the OS user — resolving step 22's buildenv-sharing question), and runs builds through 'werkdock run --rm' with the git-metadata mask expressed as ordered -v/--tmpfs flags. New pinned config key bwrap.werkdock (the executing binary, default via PATH) — a branch must not substitute the executing binary; synced in WerkatorConfig, BwrapOverrides, the pinned-key strip, the init template, docs/configuration.md, and AGENTS.md. werkdock's --clearenv means the server environment no longer leaks into builds; the TMPDIR workaround is gone with the raw invocation. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
f2d685932e
commit
823c8adc36
+11
-10
@@ -91,7 +91,7 @@ single branch may decide it:
|
||||
- the repository-side settings: the whole `gitea`, `executor`, and `watcher` sections;
|
||||
- the trust gate: `requirePullRequest`, and the Gitea status context: `statusContext`;
|
||||
- the container sandbox policy: `docker.enabled`/`docker.network` and
|
||||
`bwrap.enabled`/`bwrap.rootfs` — host-pinned as
|
||||
`bwrap.enabled`/`bwrap.rootfs`/`bwrap.werkdock` — host-pinned as
|
||||
long as only the host's configuration sets them, master-pinned once the committed
|
||||
configuration does.
|
||||
|
||||
@@ -353,7 +353,7 @@ Both parts combine as an intersection.
|
||||
|
||||
Settings: `buildCommand`, `cleanCommand`, `artifactDirs`, `stdoutLog`/`stderrLog`, `requirePullRequest`, `statusContext`, and `docker` and `bwrap` with all their keys.
|
||||
A definition carries the complete description of its build; unset keys fall back to `builds.default` and then to Werkator's own defaults.
|
||||
`requirePullRequest`, `statusContext`, `docker.enabled`, `docker.network`, `bwrap.enabled`, and `bwrap.rootfs` are pinned (master-pinned, see [the branch layer](#the-branch-layer-a-branch-describes-its-own-ci)): they are read from the repo install/project config even when a branch sets them in its own committed config.
|
||||
`requirePullRequest`, `statusContext`, `docker.enabled`, `docker.network`, `bwrap.enabled`, `bwrap.rootfs`, and `bwrap.werkdock` are pinned (master-pinned, see [the branch layer](#the-branch-layer-a-branch-describes-its-own-ci)): they are read from the repo install/project config even when a branch sets them in its own committed config.
|
||||
Inheritance from `builds.default` covers the settings only — the `trigger` block says when and where *this* build runs and is never inherited.
|
||||
Definitions are part of the branch layer: a branch may add its own and override those from the project config, for its own builds only.
|
||||
Because the inheritance is applied after all layers are merged, a build a branch invents still inherits the host's `builds.default` — its sandbox policy included, which is what keeps the pinning effective for a build the host has never heard of.
|
||||
@@ -411,16 +411,17 @@ All Werkator containers carry `org.hoennig.werkator` labels; stale build contain
|
||||
|
||||
### Notes on `builds.<name>.bwrap`
|
||||
|
||||
With `bwrap.enabled`, Werkator shells out to the `bwrap` CLI (bubblewrap) instead of native execution.
|
||||
This is the third runtime, for hosts without root and without a Docker daemon (e.g. Hostsharing managed webspaces); see `docs/plan/17-bwrap-build-runtime.md` and ADR 0007.
|
||||
`bwrap` must be on the `PATH`.
|
||||
With `bwrap.enabled`, Werkator runs the build in a bubblewrap sandbox instead of native execution.
|
||||
This is the third runtime, for hosts without root and without a Docker daemon (e.g. Hostsharing managed webspaces); see `docs/plan/17-bwrap-build-runtime.md` and ADR 0008.
|
||||
Since step 21 session C the sandbox is executed by the `werkdock` CLI (`bwrap.werkdock`, default: resolved via `PATH`) — Werkator no longer invokes `bwrap` itself; `bwrap` must be installed for werkdock.
|
||||
`werkdock doctor` checks the host's capability, superseding `tools/werkator-build-prerequisites.sh`.
|
||||
|
||||
`bwrap.rootfs` names the prepared root filesystem archive — a Debian-base rootfs with the build tools (JDK, git, locales, project-specific tooling) built elsewhere, since `debootstrap` is unavailable on the target.
|
||||
It is a local path or an `http(s)` URL; a URL is downloaded once.
|
||||
Build the archive with `tools/build-bwrap-rootfs.sh` on any machine with Docker; verify the host's user-namespace capability first with `tools/werkator-build-prerequisites.sh`.
|
||||
The archive is unpacked on demand (`tar --no-same-owner`) into `.git/werkator/buildenv/<envKey>/rootfs`, shared across all branch worktrees like the Docker Gradle cache volume; `<envKey>` derives from a hash of the source, so a changed `rootfs` unpacks a fresh environment and stale ones can be pruned.
|
||||
Per-branch Gradle caches persist in `.git/werkator/buildenv/home`, bound as `/root`.
|
||||
`bwrap.env` adds environment variables inside the sandbox.
|
||||
It is a local path or an `http(s)` URL; a URL is downloaded once into `.git/werkator/buildenv/`.
|
||||
Build the archive with `tools/build-bwrap-rootfs.sh` on any machine with Docker.
|
||||
The archive is loaded once per source as the werkdock image `werkator-buildenv-<hash>` into werkdock's store (`$WERKDOCK_HOME`, default `~/.werkdock`) — shared by every repository of this OS user; the hash derives from the source string, so a changed `rootfs` loads a fresh image and stale ones can be removed from the store.
|
||||
Per-repo Gradle caches persist in `.git/werkator/buildenv/home`, bound as `/root`.
|
||||
`bwrap.env` adds environment variables inside the sandbox; the environment is otherwise cleared (docker semantics) — the server's environment does not leak in.
|
||||
Files created inside the sandbox are owned by the host user, because uid 0 maps back to the unprivileged webspace user.
|
||||
|
||||
`docker` and `bwrap` are mutually exclusive per branch: enabling both is rejected at start, not silently picked.
|
||||
|
||||
@@ -64,11 +64,14 @@ A docker-like CLI over `bwrap`, filesystem isolation only.
|
||||
- Own docs, plan, and ADRs under `werkdock/` from the start, so the later repository split is a directory move; the Werkator side only keeps what is Werkator-specific (the git-metadata mounts of step 16 and the config pinning).
|
||||
- Keep `werkdock/` self-contained: no imports from Werkator code, no Gradle coupling to the Werkator build — it must build and test on its own.
|
||||
|
||||
### C — Werkator consumes Werkdock (this repo, after B)
|
||||
### C — Werkator consumes Werkdock (this repo, after B; implemented 2026-09-01 on branch `werkator-consumes-werkdock`)
|
||||
|
||||
- `BwrapBuildRunner` shells out to `werkdock run` instead of assembling the raw `bwrap` argv — same pattern as git and docker: CLI, no library.
|
||||
- Config keys (`bwrap.enabled`, `bwrap.rootfs`) and their pinning stay as they are; only the executor behind them changes.
|
||||
- Decide in the step: whether the git-metadata mounts stay Werkator-side (passed as extra `--bind`/`--tmpfs` options to `werkdock run`) or become a Werkdock feature; the secrets-masking of `.git/werkator/` must hold either way.
|
||||
One key was added: `bwrap.werkdock` (the executing binary, default via PATH) — pinned like the rest of the sandbox policy, since a branch must not substitute the executing binary.
|
||||
- Decided: the git-metadata mounts stay Werkator-side, passed as `-v …:ro` / `--tmpfs` / `-v` options whose flag order werkdock preserves (it grew `--tmpfs` and an ordered mount list for exactly this); the secrets-masking of `.git/werkator/` holds unchanged.
|
||||
- Decided: the rootfs archive becomes a werkdock *image* (`werkator-buildenv-<source-hash>`, checked via `werkdock images`, loaded via `werkdock load`) in werkdock's own store — shared across every repository of the OS user, which resolves step 22's buildenv-sharing question; only the URL download cache and the persistent `/root` toolchain home stay under `.git/werkator/buildenv/`.
|
||||
- Consequence of werkdock's `--clearenv`: the server environment no longer leaks into builds, and the runner's TMPDIR workaround is gone.
|
||||
|
||||
### D — The Managed-Webspace install path (this repo, independent of B/C)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user