docs: first container test pass, and what it found
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) <noreply@anthropic.com>
This commit is contained in:
@@ -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.
|
||||
Reference in New Issue
Block a user