2 Commits
Author SHA1 Message Date
ergosteurandClaude Opus 5 ab0b4d7d0f Make update-image-pins.sh shellcheck-clean
shellcheck flagged three things, one of which was worth acting on beyond
silencing it.

echo was emitting a script fragment containing a literal \n meant for the
generated code, not for this shell. Bash's echo leaves it alone by default,
but the handling of backslashes is implementation-defined and xpg_echo would
have expanded it and corrupted the fragment. printf '%s\n' instead.

The discover_* functions were dispatched as "discover_$distro", which reads as
dead code to shellcheck and to anyone grepping for a caller. An explicit case
dispatch replaces it, which is what SC2317 was really complaining about.

The two remaining SC2016 hits are intentional single quotes, one a sed address
matching a literal $DISTRO_CHOICE and one emitting code, and are annotated
rather than fixed.

Also reject an unknown --distro. It previously filtered every distro out and
reported "all pins are already current" with exit 0, so a typo looked like a
clean run.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 16:10:51 +00:00
ergosteurandClaude Opus 5 e9fcdd6d1a Add update-image-pins.sh
Refreshing the pins by hand meant checking five mirrors and hand-building
URLs to confirm them, which is how Fedora and Alpine drifted two releases
behind without anyone noticing. This does the lookup and the checking.

Prefers each distribution's own metadata over scraping where it exists:
Ubuntu from changelogs.ubuntu.com/meta-release, the same file
do-release-upgrade reads, filtered to supported LTS; Debian from the stable
suite's Release file, so it follows Debian's own definition of stable rather
than guessing from directory names. Fedora, AlmaLinux and Alpine have no such
feed and are read from mirror listings.

Alpine turns out to be automatable after all. latest-stable is a symlink to
the current branch, so the filename there yields the branch, the patch level
and the prefix together, and reading the prefix rather than assuming it is
what would have caught the nocloud_ rename.

Two properties matter more than the lookups:

Candidate URLs are derived by evaluating the pin block and the case statement
out of build-cloudinit-template.sh itself, not by repeating its URL templates
here. A second copy would eventually disagree with the builder and verify
something the builder never downloads.

Nothing is written until the image has been confirmed to serve qcow2 magic,
not merely a 200. Mirrors answer for a deleted image with an HTML error page
under a 200, which would otherwise be pinned as good and fail at build time.
A distro that fails verification keeps its old pin and does not hold up the
others.

Dry run by default. Exit 3 distinguishes "pins are stale" from success, so it
can run as a periodic staleness check, and 2 means a lookup or verification
failed.

The template is read by anchor, so a restructured pin block or case statement
is detected and refused rather than silently producing URLs from unset
variables.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 16:04:56 +00:00