| 285 |
285 |
|
`PROFILE=server` and `ARCH=aarch64`; fw12 sets no dials at all and carries only
|
| 286 |
286 |
|
identity and answers, below.
|
| 287 |
287 |
|
|
|
288 |
+ |
## Preflight
|
|
289 |
+ |
|
|
290 |
+ |
`build/preflight.sh <host>` answers, before any mint, what a mint would otherwise
|
|
291 |
+ |
answer slowly. Run it whenever a recipe or the package set changes:
|
|
292 |
+ |
|
|
293 |
+ |
```sh
|
|
294 |
+ |
build/preflight.sh fw13 # everything
|
|
295 |
+ |
build/preflight.sh fw13 --fast # the instant checks only, no probe
|
|
296 |
+ |
```
|
|
297 |
+ |
|
|
298 |
+ |
Four checks:
|
|
299 |
+ |
|
|
300 |
+ |
| check | how | catches |
|
|
301 |
+ |
|---|---|---|
|
|
302 |
+ |
| `dials` | mirrors the Containerfile's own validator | a recipe that cannot pass step 20 |
|
|
303 |
+ |
| `requires` | `command -v`, `pkg-config`, `find` inside a probe image | a role's capability the mint does not deliver |
|
|
304 |
+ |
| `var-payload` | `bootc container lint` on that probe | undeclared `/var` content, which fails at step 101 of 103 |
|
|
305 |
+ |
| `guards` | grep, on the host | a known workaround being dropped |
|
|
306 |
+ |
|
|
307 |
+ |
`build/hosts/<name>.requires` is the second half of a recipe. The `.env` says
|
|
308 |
+ |
which dials to set; the `.requires` says what has to exist on the other side.
|
|
309 |
+ |
That distinction is the one four thrown-away mints on 2026-09-04 turned on: every
|
|
310 |
+ |
dial was set correctly and the image still could not build a Tauri app or restore
|
|
311 |
+ |
a production dump, because nothing anywhere said fw13 had to be able to do either.
|
|
312 |
+ |
|
|
313 |
+ |
The last two checks run against a **probe image** -- this mint's package set plus
|
|
314 |
+ |
the tmpfiles files it would ship -- rather than against a prediction. Predicting
|
|
315 |
+ |
was tried first and was wrong twice in the same way: `var-payload` derived bootc's
|
|
316 |
+ |
rule from the symptom and flagged paths the real build accepts, and `requires`
|
|
317 |
+ |
compared a capability's provider against the packages the Containerfile names, so
|
|
318 |
+ |
`bin:git` failed because `/usr/bin/git` comes from `git-core`. Building the
|
|
319 |
+ |
smallest image that can be asked directly removes both. It is a build, which is
|
|
320 |
+ |
what the script exists to avoid, but it is one dnf transaction rather than 103
|
|
321 |
+ |
steps, and it is right rather than close.
|
|
322 |
+ |
|
|
323 |
+ |
**What the preflight cannot see**, stated so a clean run is not read as more than
|
|
324 |
+ |
it is:
|
|
325 |
+ |
|
|
326 |
+ |
- `/var` content that arrives from something other than a package. The
|
|
327 |
+ |
Containerfile copies `etc/` and `usr/` and runs its own steps.
|
|
328 |
+ |
- Packages the real build takes from a repo the probe does not configure.
|
|
329 |
+ |
Tailscale is the measured case: a bare base resolves the name to a different
|
|
330 |
+ |
build with a different payload, so it is excluded and reported rather than
|
|
331 |
+ |
installed.
|
|
332 |
+ |
- COPR and Terra packages, which do not resolve in a bare base at all.
|
|
333 |
+ |
- Runtime interactions. linuxdeploy bundling a binutils that cannot read Fedora
|
|
334 |
+ |
43's `.relr.dyn` sections is the example, and no static check finds it. What
|
|
335 |
+ |
`guards` catches is that workaround being *lost*, which is how it was.
|
|
336 |
+ |
|
| 288 |
337 |
|
## The answer sheet
|
| 289 |
338 |
|
|
| 290 |
339 |
|
A recipe can also answer the questions `alloy install` would otherwise ask. The
|