Say what an image build is doing, and keep saying it

A build is the slow part of a first run and the thing --install triggers: apt, a Node
tarball, an npm install. Every byte of podman's transcript used to go to a log file, so
minutes of silence looked exactly like a wedge -- and a wedge is what people interrupt,
leaving a half-built image.

One line per build step, plus a notice every AISB_BUILD_QUIET_SECS (15) that a step has
shown the terminal nothing, whether it is producing output the view drops or no output at
all. AISB_BUILD_OUTPUT=progress|full|quiet picks how much the terminal sees; the complete
transcript stays in $AISB_STATE_DIR/build-*.log in all three, because the progress view is
a filter and a failed build has to be diagnosable from the raw apt output. The first line
names the extra packages going in, which is what answers "why is this run building when
the last one did not".

podman build writes its transcript to *stdout* -- the same stdout the
$(ensure_image ...) call reads back as the image ref -- so the transcript is routed onto
stderr and the ref stays one clean line. A failed build now names the package apt could
not find instead of pointing at a file to go read, and reports the time it took.
Resolving a digest by pulling the base says so too: that is a download of the base image.

tests/unit/11_build.sh stubs podman for both heartbeat paths and checks the ref, the
failure text and that a canary credential appears nowhere.

LLM-Generated: true
This commit is contained in:
2026-10-30 22:53:57 -04:00
parent 90d98dcc9e
commit ac2f310d10
5 changed files with 353 additions and 10 deletions
+12
View File
@@ -140,6 +140,18 @@ networking or the image, `make e2e` green too.
* `split_target()` / `classify_allows()` — the mapping from what the user typed to
what the firewall and the proxy enforce.
* `build_argv()` — every isolation flag lives here.
* `build_in()` / `build_progress()` — a build is minutes of apt, a Node tarball and an
npm install, so it has to announce itself and keep announcing: silence is what a hang
looks like from the terminal, and an interrupted build is a half-built image. Note that
`podman build` writes its transcript to **stdout** — the same stdout that the
`$(ensure_image ...)` call reads back as the image ref — so the transcript is routed
onto stderr. Print it
to stdout and the build log comes back spliced into the ref. Whatever the terminal shows
(`AISB_BUILD_OUTPUT=progress|full|quiet`), the complete transcript belongs in
`$AISB_STATE_DIR/build-*.log`, because the progress view is a filter and a failed build
has to be diagnosable from the raw apt output. Tests: `tests/unit/11_build.sh` (a stub
podman, both heartbeat paths, the ref stays one clean line, a canary value appears
nowhere).
* `resolve_workdir()` / `mirror_block_of()` — what the project is called inside the
container. Mirroring the host path is the convenience; the deny list is the safety, because
a bind hides whatever the image has at that destination and podman puts `--tmpfs /tmp` on