7.5 KiB
WARNING: This document describes only the change applied in this PR. It may already be outdated once the next PR is merged. Historic PR-documentation is not maintained along with new PRs — treat it as a snapshot, not as current documentation.
The Problem
PR #6 grew Werkdock as a standalone sandbox CLI, but BwrapBuildRunner still assembled its own raw bwrap invocation — the extraction was only half done, and the two implementations could drift.
Separately, the webspace deployment path in tools/remote still followed the original self-build prototype: clone Werkator's own repository onto the target and build it there, which is exactly the pattern ADR 0006 rejected ("build locally, install the bundle") and step 21 set out to correct.
Non-Goals
tools/remote's configuration-writing duplication (heredocs/sedinto the machine config) — that is step 23, PR #8/#9.- Multi-repository support for one Werkator instance (step 22, PR #10).
- RFC 0002 levels 2/3 and RFC 0003 (composable toolchain mounts) stay deferred/candidate.
The Scenarios
Feature: BwrapBuildRunner delegates to Werkdock
Scenario#7.01: A build runs through werkdock run instead of a raw bwrap invocation
So that Werkator and Werkdock never carry two implementations of the same sandbox invocation.
- Given
bwrap.enabledand a configured rootfs archive - When a build needs the sandbox
- Then
BwrapBuildRunnerloads the image viawerkdock images/werkdock load(once, keyed byimageName(rootfs)=werkator-buildenv-<hash-of-source>) and runs the build viawerkdock run --rm- and the configured
bwrap.werkdockbinary (default:werkdockviaPATH) is what gets invoked.
- and the configured
Verified by
- assembles the exact werkdock run command for a loaded image
- loads the image once when werkdock does not know it yet
- does not load an image werkdock already has
- uses the configured werkdock binary path
Scenario#7.02: The git-metadata mask survives the move to ordered -v/--tmpfs flags
So that secrets stay outside the sandbox exactly as before, now expressed as flag order instead of an internal mount list.
- Given a worktree build
- When the invocation is assembled
- Then
.gitis bound read-only, then.git/werkator/is masked with--tmpfs, then the worktree's admin dir is bound read-write, in that exact order- and Werkdock's
Mountlist (replacing the earlier unorderedBindlist) preserves the order flags were given in.
- and Werkdock's
Verified by
- exposes git metadata read-only with the werkator dir masked, in mount order
- mounts no git metadata when the workspace is not a worktree
- TestParseRunKeepsMountFlagOrderAcrossVolumeAndTmpfs
Scenario#7.03: Werkdock gained what the delegation needed
So that images/:rw were built because Werkator's runner needed them, not speculatively.
- Given the new
werkdock imagesverb and:rwvolume option - When the runner checks whether an image is already loaded, or mounts the admin dir read-write
- Then
imageslists loaded image names (one per line,docker images --formatshaped) and-v src:dst:rwis accepted alongside the existing:ro.
Verified by
- TestListNamesLoadedImagesAndIgnoresTmpLeftovers
- TestParseRunAcceptsTheExplicitRwVolumeOption
- TestImageNameFromArchive
Scenario#7.04: The TMPDIR workaround is gone because it is now structurally impossible
So that the fix and its own workaround do not both linger in the codebase.
- Given Werkdock's
--clearenv - When a build runs in the sandbox
- Then no host
TMPDIR/TMPreaches the sandboxed process at all, soBwrapBuildRunner's earlier explicit--setenv TMPDIR /tmpworkaround (PR #4) is removed as dead code, not merely redundant.
Verified by
Feature: the webspace install path replaces the self-build prototype
Scenario#7.05: tools/remote separates the builder role from the built (watched) repository role
So that "build Werkator on the webspace" and "Werkator watches a repository on the webspace" are never conflated again.
- Given a Managed Webspace target
- When the wrapper manages the Werkator runtime versus a repository Werkator watches
- Then
instance-install/instance-update/instance-startinstall and run the Werkator builder binary+bundle- and
repo-initprepares a repository to be built by that instance - and the retired
install/build/startcommands fail loudly, naming their successors, instead of silently doing the old thing.
- and
Verified by
- manual invocation of the retired commands on mih34 (shell script; no automated test harness for
tools/remote)
Scenario#7.06: The self-build prototype is gone
So that Werkator is never again built by checking out its own source onto the target and compiling there.
- Given the old prototype cloned werkator's own repository onto the webspace and built it in place
- When an instance is installed or updated now
- Then the runtime bundle is built locally and transported (
instance-install/instance-update), never cloned-and-built on the target.
Verified by
- live run on mih34:
instance-updateagainst a runtime bundle built locally
The Solution
BwrapBuildRunner.invocation() no longer builds a bwrap argv; it shells out to the werkdock binary named by bwrap.werkdock (a new pinned config key, alongside bwrap.enabled/bwrap.rootfs) for images, load, and run --rm.
werkdock/internal/engine/engine.go was rewritten from an unordered Bind list to an ordered Mount list (MountBind/MountRoBind/MountTmpfs) specifically so the CLI's -v/--tmpfs flag order — which the git-metadata mask depends on — survives into the sandbox invocation unchanged.
werkdock/internal/cli/images.go is new; run.go's volume parsing gained the :rw option.
tools/remote was reorganized around two roles instead of one flat command list: builder lifecycle (instance-install/instance-update/instance-start) versus watched-repository lifecycle (repo-init); the old install/build/start now die with the successor's name.
require_idle()/FORCE=1 guards a runtime swap against a build in progress.
Additional Changes
docs/deployment.md: the webspace section now describes the role-separated commands.docs/configuration.mdandAGENTS.md:bwrap.werkdockdocumented as a fourth pinned bwrap key.- Step 21 plan: sessions C and D marked done with live-verification notes.
Prerequisite PRs
- PR #6 (Werkdock bootstrap) — this PR is the consumer of the CLI it built.
Follow-up PRs
- PR #8/#9:
tools/remote's remaining configuration-writing duplication withwerkator initis resolved next (step 23). - PR #10: multi-repository support for one Werkator instance (step 22).