From 236a3a5481e336a213c428d240728b0baf805b59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Padez?= Date: Thu, 13 Aug 2026 04:00:31 +0000 Subject: [PATCH] docs: first container test pass, and what it found MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ubuntu 24.04, Debian 12, Arch and Fedora 41. OS and package-manager detection correct on all four; --help works unprivileged; and the install report is written end to end in a container that had never seen this code — task 1's mechanism confirmed off the machine it was written on. Three real findings. --only does not isolate a step. Running --only "Core utils" still created a user account, because ask_username and the account creation sit in the preamble above the step framework, so everything before the first `step` runs every time. It is defensible and it is not what the flag appears to promise. .setup-answers travels with a copy of the tree. Correctly gitignored and 0600, but it lives inside the repository directory, so `cp -r` carries it — a container that had never run setup came up already knowing the username and created that account. Nothing secret in it; it is a surprise, which in an installer is the expensive kind. adduser leaks its own interactive prompt ("Try again? [y/N]") on the account-creation path. Harmless here because the run had already stopped, but a hang on a real unattended install. Also records what containers cannot reach: no init means systemd, netplan, ufw and the sshd drop-ins are only verifiable as "wrote the right file"; Docker and Postgres are untested; macOS is unreachable entirely and everything about it is reasoned rather than executed. Co-Authored-By: Claude Opus 5 (1M context) --- docs/install-container-testing.md | 74 +++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 docs/install-container-testing.md diff --git a/docs/install-container-testing.md b/docs/install-container-testing.md new file mode 100644 index 00000000..8915e7ec --- /dev/null +++ b/docs/install-container-testing.md @@ -0,0 +1,74 @@ +# Testing the installer in containers + +**2026-08-13.** First pass. Ubuntu 24.04, Debian 12, Arch, Fedora 41. + +## What passed + +**OS and package-manager detection is correct on all four.** + +| image | `OS` | `PM` | +| --- | --- | --- | +| ubuntu:24.04 | `ubuntu` | `apt` | +| debian:12 | `debian` | `apt` | +| archlinux | `arch` | `pacman` | +| fedora:41 | `fedora` | `dnf` | + +**`--help` and argument handling work unprivileged** in a clean container, before any escalation. + +**The install report is written**, end to end, in a container that had never seen this code. That is +task 1's mechanism confirmed outside the machine it was written on. + +**Refusing beats hanging.** With no answer available the run stopped with +`FAIL: No answer. Set ASSUME_YES=1 to run without prompts.` rather than blocking forever on a prompt +nobody could see. That is the behaviour an unattended run needs, and it already exists. + +--- + +## What it found + +### 1. `--only` does not isolate a step + +Running `--only "Core utils"` still **created a user account**, because `ask_username` and the +account creation happen in the preamble, above the step framework. Everything before the first +`step` call runs on every invocation. + +Defensible — every step needs to know who it is installing for — but it means `--only` is not the +surgical tool it appears to be, and a first-time reader will assume it is. Either the preamble +becomes lazy, or `--only` says plainly what it will still do. + +### 2. `.setup-answers` travels with a copy of the tree + +It lives at `scripts/setup/machine-setup/.setup-answers`, is correctly gitignored, and is `0600` +root-owned. But it is **inside the repository directory**, so `cp -r` or a tarball of the tree +carries it — which is exactly what happened here: a container that had never run setup came up +already knowing the username `pastilhas` and created that account. + +Not a leak (username and install path, nothing secret). It is a surprise, and surprises in an +installer are the expensive kind. Worth moving outside the repo, next to the progress file. + +### 3. `adduser` leaks its own prompts + +``` +Use of uninitialized value $answer in pattern match (m//) at /usr/sbin/adduser line 848. +Try again? [y/N] +``` + +The account-creation path reaches an interactive `adduser` question the script does not answer. +Harmless here because the run stopped anyway, but on a real unattended install this is a hang. + +--- + +## Coverage this cannot reach + +Containers have no init by default, so **`systemctl`, netplan, ufw and the sshd drop-ins were not +exercised**. Those sections can only be verified as "wrote the right file", not "the service came +up". Running privileged containers with systemd would close most of that gap and is the obvious next +step. + +**Docker-in-Docker** was not attempted, so the Docker section and Postgres provisioning are +untested. Mounting the host socket would test the section's logic while telling us nothing about the +install path. + +**macOS is untestable here entirely.** The 17 skipped sections, the Homebrew paths, the Xcode +command line tools step and the refusal-to-run-as-root are all reasoned from documentation and +unverified by execution.