fix(kanidm): align kanidm-provision to trixie, and stop its always-changed churn #265

Sammanfogat
supernaut sammanfogade 1 incheckning från fix/kanidm-provision-trixie in i main 2026-07-30 20:22:41 +00:00
Ägare

1. The build was on Debian bookworm while the estate is trixie

Everything else is trixie — the host (kernel 6.12.73+deb13), node:24.18.0-trixie-slim (×8),
postgres:17.10-trixie — and this one image pair was bookworm/bookworm.

The Containerfile's stated reason was "Builder and runtime are both bookworm so the glibc matches".
That is a builder↔runtime constraint — the runtime glibc must not be older than the one the binary
was linked against — and a trixie/trixie pair satisfies it identically. ADR 0016 imposes no Debian
version.
The QEMU-segfault comment concerns building natively on the host, not the Debian generation.

So there was no reason for it; just drift onto oldstable.

Verified by building it, not by reasoning about it. rust:1-trixie compiles kanidm-provision
v1.3.0 cleanly, and the binary runs on the new runtime:

kanidm-provision 1.3.0
PRETTY_NAME="Debian GNU/Linux 13 (trixie)"
ldd (Debian GLIBC 2.41-12+deb13u3) 2.41

Why the runtime is debian:13-slim and not trixie-slim

Same image (identical manifests — verified by hashing both), but numeric, so renovate can bump it.

This is the mechanism behind the drift, and it's worth recording. Renovate's dependency dashboard for
this repo found one dependency in this file:

ansible/roles/kanidm/files/kanidm-provision.Containerfile (1)
 - docker.io/library/rust 1-bookworm

debian:bookworm-slim was silently ignored — a bare codename carries no version to compare. Contrast
caddy-ratelimit.Containerfile (2), where both FROMs are versioned and both are tracked. So renovate
kept the rust base current within bookworm indefinitely, with no way to express "trixie exists".

A numeric tag means Debian 14 shows up as a PR. The rust suffix stays untrackable (renovate bumps
the 1, never the -trixie), so that one still needs a human at the next Debian release — noted in the
file rather than pretended solved.

The role rebuilds when the Containerfile changes (_kanidm_provision_containerfile is changed), not only
on a tag bump, so this takes effect on the next apply. It does not have the image-tag apply gap of #63.

2. changed_when matched a string the tool never prints

changed_when: "'no changes' not in (_kanidm_provision_run.stdout | default('') | lower)"

kanidm-provision emits no such message. Verified against the compiled binary rather than the docs
(two doc summaries were unreliable while investigating this):

occurrences of "no changes": 0
status strings present: Syncing groups · Syncing persons · Syncing oauth2 resource servers
                        Syncing group members · Tracking provisioned entities · Removing orphaned entities

Those are unconditional phase headers. There is no summary line, the exit code is 0 either way, and
--help offers no --dry-run/--diff — only --url, --state, --accept-invalid-certs,
--no-auto-remove.

So the condition could never evaluate false: the task has reported changed on every apply since it
was written, against output that never existed. It was never prod disagreeing with the state file.

Now changed_when: false. "We cannot detect this" is the honest encoding, and strictly better than a
permanent changed that masks real drift — which is how the merged-but-unapplied Caddyfile in #250 hid
for a day. If upstream gains a --dry-run or a summary line, match that instead.

Effect

This was the last always-changed task. gitborg-prod goes from 13 spurious changed this morning to
0
; gitborg-monitoring is already at 0.

--syntax-check passes; ansible-lint clean at the production profile.

Note on the apply

The next apply rebuilds the image on the host (compiling Rust natively), so that task will take
several minutes and is the one real risk here — the Containerfile itself warns that a link step can be
OOM-killed on a small host, with CARGO_BUILD_JOBS=1 as the remedy. Worth watching rather than
assuming.

## 1. The build was on Debian bookworm while the estate is trixie Everything else is trixie — the host (kernel `6.12.73+deb13`), `node:24.18.0-trixie-slim` (×8), `postgres:17.10-trixie` — and this one image pair was bookworm/bookworm. The Containerfile's stated reason was *"Builder and runtime are both bookworm so the glibc matches"*. That is a **builder↔runtime** constraint — the runtime glibc must not be older than the one the binary was linked against — and a trixie/trixie pair satisfies it identically. **ADR 0016 imposes no Debian version.** The QEMU-segfault comment concerns building natively on the host, not the Debian generation. So there was no reason for it; just drift onto oldstable. **Verified by building it, not by reasoning about it.** `rust:1-trixie` compiles kanidm-provision v1.3.0 cleanly, and the binary runs on the new runtime: ``` kanidm-provision 1.3.0 PRETTY_NAME="Debian GNU/Linux 13 (trixie)" ldd (Debian GLIBC 2.41-12+deb13u3) 2.41 ``` ### Why the runtime is `debian:13-slim` and not `trixie-slim` Same image (identical manifests — verified by hashing both), but **numeric, so renovate can bump it**. This is the mechanism behind the drift, and it's worth recording. Renovate's dependency dashboard for this repo found **one** dependency in this file: ``` ansible/roles/kanidm/files/kanidm-provision.Containerfile (1) - docker.io/library/rust 1-bookworm ``` `debian:bookworm-slim` was silently ignored — a bare codename carries no version to compare. Contrast `caddy-ratelimit.Containerfile (2)`, where both `FROM`s are versioned and both are tracked. So renovate kept the rust base current **within bookworm** indefinitely, with no way to express "trixie exists". A numeric tag means Debian 14 shows up as a PR. The **rust suffix stays untrackable** (renovate bumps the `1`, never the `-trixie`), so that one still needs a human at the next Debian release — noted in the file rather than pretended solved. The role rebuilds when the Containerfile changes (`_kanidm_provision_containerfile is changed`), not only on a tag bump, so this takes effect on the next apply. It does **not** have the image-tag apply gap of #63. ## 2. `changed_when` matched a string the tool never prints ```yaml changed_when: "'no changes' not in (_kanidm_provision_run.stdout | default('') | lower)" ``` kanidm-provision emits no such message. Verified against the **compiled binary** rather than the docs (two doc summaries were unreliable while investigating this): ``` occurrences of "no changes": 0 status strings present: Syncing groups · Syncing persons · Syncing oauth2 resource servers Syncing group members · Tracking provisioned entities · Removing orphaned entities ``` Those are unconditional phase headers. There is no summary line, the exit code is 0 either way, and `--help` offers no `--dry-run`/`--diff` — only `--url`, `--state`, `--accept-invalid-certs`, `--no-auto-remove`. So the condition **could never evaluate false**: the task has reported `changed` on every apply since it was written, against output that never existed. It was never prod disagreeing with the state file. Now `changed_when: false`. "We cannot detect this" is the honest encoding, and strictly better than a permanent `changed` that masks real drift — which is how the merged-but-unapplied Caddyfile in #250 hid for a day. If upstream gains a `--dry-run` or a summary line, match that instead. ## Effect This was the last always-changed task. `gitborg-prod` goes from **13 spurious `changed` this morning to 0**; `gitborg-monitoring` is already at 0. `--syntax-check` passes; `ansible-lint` clean at the `production` profile. ## Note on the apply The next apply **rebuilds the image on the host** (compiling Rust natively), so that task will take several minutes and is the one real risk here — the Containerfile itself warns that a link step can be OOM-killed on a small host, with `CARGO_BUILD_JOBS=1` as the remedy. Worth watching rather than assuming.
supernaut lade till 1 incheckning 2026-07-30 20:13:16 +00:00
fix(kanidm): align kanidm-provision to trixie, and stop its always-changed churn
Alla kontroller lyckades
ci / ci (pull_request) Successful in 1m35s
d775637ccd
Two changes, both in the kanidm-provision path.

1. The build was on Debian bookworm while the estate is trixie

Everything else is trixie — the host (kernel 6.12.73+deb13), node:24.18.0-trixie-slim
(x8), postgres:17.10-trixie — and this one image pair was bookworm/bookworm.

The Containerfile's stated reason was "Builder and runtime are both bookworm so the
glibc matches". That is a builder<->runtime constraint (the runtime glibc must not be
older than the one the binary was linked against), and a trixie/trixie pair satisfies
it identically. ADR 0016 imposes no Debian version. The QEMU-segfault comment is
about building natively on the host, not about the Debian generation. So: no reason,
just drift onto oldstable.

Verified by building it, twice: rust:1-trixie compiles kanidm-provision v1.3.0
cleanly, and the binary runs on the new runtime (`kanidm-provision 1.3.0`,
Debian GNU/Linux 13, glibc 2.41).

The runtime uses `debian:13-slim`, not `trixie-slim` — the same image (identical
manifests, verified) but NUMERIC, because renovate cannot bump a bare codename. Its
dashboard found only ONE dependency in this file, `rust 1-bookworm`, and silently
ignored `debian:bookworm-slim`: a codename carries no version to compare. That is the
mechanism behind the drift — renovate kept the rust base current WITHIN bookworm
forever with no way to express "trixie exists". A numeric tag means Debian 14 arrives
as a PR. The rust suffix stays untrackable (renovate bumps the `1`, never the
`-trixie`), so that one still needs a human at the next release; noted in the file.

The role rebuilds when the Containerfile changes (`_kanidm_provision_containerfile is
changed`), not only on a tag bump, so this takes effect on the next apply — it does
not have the image-tag apply gap of #63.

2. changed_when matched a string the tool never prints

  changed_when: "'no changes' not in (stdout | lower)"

kanidm-provision emits no such message. Verified against the compiled binary:
`grep -aci "no changes"` returns 0, and the only status strings are unconditional
phase headers — "Syncing groups", "Syncing persons", "Syncing oauth2 resource
servers", "Syncing group members", "Tracking provisioned entities", "Removing
orphaned entities". No summary line, exit 0 either way, and `--help` offers no
--dry-run.

So the condition could never be false: the task reported changed on EVERY apply since
it was written, against output that never existed. Now `changed_when: false` —
"we cannot detect this" is the honest encoding, and it is strictly better than a
permanent `changed` that masks real drift (which is how the unapplied Caddyfile in
#250 hid for a day). If upstream gains a --dry-run or a summary line, match that.

This was the last always-changed task: prod goes from 13 spurious `changed` this
morning to 0.
supernaut sammanfogade incheckning 963cc4d511 till main 2026-07-30 20:22:41 +00:00
supernaut tog bort grenen fix/kanidm-provision-trixie 2026-07-30 20:22:41 +00:00
Logga in för att delta i denna konversation.
Inga granskare
Ingen milstolpe
Inget projekt
Inga tilldelade
1 deltagare
Notiser
Förfallodatum
Förfallodatumet är ogiltigt eller utanför gränserna. Använd formatet "åååå-mm-dd".

Inget förfallodatum satt.

Beroenden

Inga beroenden satta

Referens
bitborg/bitborg-infra!265
Ingen beskrivning angiven.