HOMELAB-2682: chore(sbx-gits): pin sandbox image to 6fa150a (openssh layer) #842

Merged
pi-landing merged 1 commit from plane/HOMELAB-2682-sbxgits-pin into live 2026-11-05 11:43:01 +00:00
Collaborator

What

Pure pin bump in core/manifests/apps/sbx-gits. The three sbx-fleet image lines of
statefulset.yaml — initContainer prepare-work, initContainer seed-pi-agent, container
sandbox — move from

harbor.aaron.reynoza.org/platform/sbx-fleet:eebdbe1@sha256:7e0513ca6f2d6a77a61e0157d2e3cc6be7d3d73f1618d634253081dcb794c9e4

to

harbor.aaron.reynoza.org/platform/sbx-fleet:6fa150a@sha256:0ee5e97e9c24f81a3a65a712054dba7e3ffb0e300f5840315d5152ffa60ea53c

Nothing else changes. The README.md lines that carry the same pin string are updated with
it (the layout snippet, the invariant grep in the verification block, and the prose tag) —
they assert the pin against the manifest, so leaving them behind would make the directory's
own documented check fail. git diff --stat: 2 files changed, 6 insertions(+), 6 deletions(-).
Every changed line is an sbx-fleet image reference — verified mechanically below.

Why

The digest is exactly what CI published for merge commit
6fa150a4a950341646b91d89e4588995fecc092a (PR #839, "openssh client+server for ssh-lib spike
tests") on live:

  • CI run #3119, branch live, commit 6fa150a4a9 — job build-and-push: success (3m0s).
  • Harbor platform/sbx-fleet:6fa150a — pushed 2026-11-05T11:05:57Z, 683.29 MB.
  • crane digest harbor.aaron.reynoza.org/platform/sbx-fleet:6fa150a →
    sha256:0ee5e97e9c24f81a3a65a712054dba7e3ffb0e300f5840315d5152ffa60ea53c.

The image really carries the new layer: its history contains
apt-get install -y --no-install-recommends openssh-client openssh-server and the build
smoke ssh -V && test -x /usr/sbin/sshd. That is what the ssh-lib spike tests need in the
sandbox.

Mechanical verification

1. The only changed lines are image lines (git diff -U0, branch vs origin/live
6fa150a4):

      6 KIND=+ image-tag=6fa150a
      6 KIND=- image-tag=eebdbe1
--- any non-image changed line? ---
NONE — every changed line is an sbx-fleet image reference

2. sbx-gits render (kubectl kustomize core/manifests/apps/sbx-gits, origin/live →
this branch) — three changed lines, all image lines, nothing else:

- image: .../platform/sbx-fleet:eebdbe1@sha256:7e0513ca…794c9e4
+ image: .../platform/sbx-fleet:6fa150a@sha256:0ee5e97e…60ea53c   (x3)

The android-emulator pin in the same StatefulSet is untouched
(platform/android-emulator:230756a@sha256:66430940…).

3. sbx-sendrast render is byte-identical to origin/live — computed on both trees with
kubectl kustomize core/manifests/apps/sbx-sendrast, not assumed:

131099 bytes   sha256 d225759f534949db66b0cf066581d3a9c6f74f59ae2b4e10068b1429f736271a   (origin/live)
131099 bytes   sha256 d225759f534949db66b0cf066581d3a9c6f74f59ae2b4e10068b1429f736271a   (this branch)
cmp: byte-identical

4. sbx-lab keeps its own pin — 2045e53@sha256:8d3480f0… is untouched; its render is
identical on both trees (sha256 2e08f3dfe94ebab85a7594ff80ab87973e1d910096ff64913b760bd25e2f8069),
and no sbx-lab file appears in the diff.

No restart

updateStrategy is OnDelete (H0/H1): this merge does not recycle sbx-gits-0. The new
template takes effect at sbx-gits's next scheduled restart. No kubectl mutation, no live
image set, no merge from the worker that opened this.

Out of scope

sbx-lab (stays at 2045e53), sbx-sendrast (own image), the android-emulator pin, and
every non-image field of the sbx-gits manifest.

## What Pure pin bump in `core/manifests/apps/sbx-gits`. The three `sbx-fleet` image lines of `statefulset.yaml` — initContainer `prepare-work`, initContainer `seed-pi-agent`, container `sandbox` — move from ``` harbor.aaron.reynoza.org/platform/sbx-fleet:eebdbe1@sha256:7e0513ca6f2d6a77a61e0157d2e3cc6be7d3d73f1618d634253081dcb794c9e4 ``` to ``` harbor.aaron.reynoza.org/platform/sbx-fleet:6fa150a@sha256:0ee5e97e9c24f81a3a65a712054dba7e3ffb0e300f5840315d5152ffa60ea53c ``` Nothing else changes. The `README.md` lines that carry the same pin string are updated with it (the layout snippet, the invariant `grep` in the verification block, and the prose tag) — they assert the pin against the manifest, so leaving them behind would make the directory's own documented check fail. `git diff --stat`: 2 files changed, 6 insertions(+), 6 deletions(-). Every changed line is an `sbx-fleet` image reference — verified mechanically below. ## Why The digest is exactly what CI published for merge commit `6fa150a4a950341646b91d89e4588995fecc092a` (PR #839, "openssh client+server for ssh-lib spike tests") on `live`: - CI run **#3119**, branch `live`, commit `6fa150a4a9` — job `build-and-push`: **success** (3m0s). - Harbor `platform/sbx-fleet:6fa150a` — pushed `2026-11-05T11:05:57Z`, 683.29 MB. - `crane digest harbor.aaron.reynoza.org/platform/sbx-fleet:6fa150a` → `sha256:0ee5e97e9c24f81a3a65a712054dba7e3ffb0e300f5840315d5152ffa60ea53c`. The image really carries the new layer: its history contains `apt-get install -y --no-install-recommends openssh-client openssh-server` and the build smoke `ssh -V && test -x /usr/sbin/sshd`. That is what the ssh-lib spike tests need in the sandbox. ## Mechanical verification **1. The only changed lines are image lines** (`git diff -U0`, branch vs `origin/live` `6fa150a4`): ``` 6 KIND=+ image-tag=6fa150a 6 KIND=- image-tag=eebdbe1 --- any non-image changed line? --- NONE — every changed line is an sbx-fleet image reference ``` **2. `sbx-gits` render** (`kubectl kustomize core/manifests/apps/sbx-gits`, `origin/live` → this branch) — three changed lines, all image lines, nothing else: ``` - image: .../platform/sbx-fleet:eebdbe1@sha256:7e0513ca…794c9e4 + image: .../platform/sbx-fleet:6fa150a@sha256:0ee5e97e…60ea53c (x3) ``` The `android-emulator` pin in the same StatefulSet is untouched (`platform/android-emulator:230756a@sha256:66430940…`). **3. `sbx-sendrast` render is byte-identical to `origin/live`** — computed on both trees with `kubectl kustomize core/manifests/apps/sbx-sendrast`, not assumed: ``` 131099 bytes sha256 d225759f534949db66b0cf066581d3a9c6f74f59ae2b4e10068b1429f736271a (origin/live) 131099 bytes sha256 d225759f534949db66b0cf066581d3a9c6f74f59ae2b4e10068b1429f736271a (this branch) cmp: byte-identical ``` **4. `sbx-lab` keeps its own pin** — `2045e53@sha256:8d3480f0…` is untouched; its render is identical on both trees (`sha256 2e08f3dfe94ebab85a7594ff80ab87973e1d910096ff64913b760bd25e2f8069`), and no `sbx-lab` file appears in the diff. ## No restart `updateStrategy` is `OnDelete` (H0/H1): this merge does **not** recycle `sbx-gits-0`. The new template takes effect at `sbx-gits`'s next scheduled restart. No `kubectl` mutation, no live image set, no merge from the worker that opened this. ## Out of scope `sbx-lab` (stays at `2045e53`), `sbx-sendrast` (own image), the `android-emulator` pin, and every non-image field of the `sbx-gits` manifest.
HOMELAB-2682: chore(sbx-gits): pin sandbox image to 6fa150a (openssh layer)
All checks were successful
CI Review / runner-manifest-test (pull_request) Successful in 6s
CI Review / receiver-test (pull_request) Successful in 7s
0/0 projects applied successfully.
CI Review / helm-validate (pull_request) Successful in 13s
CI Review / alert-receiver-test (pull_request) Successful in 23s
Lint & Validate / shellcheck (pull_request) Successful in 19s
Lint & Validate / yaml-lint (pull_request) Successful in 31s
CI Review / record-sql-test (pull_request) Successful in 1m0s
CI Review / cockpit-test (pull_request) Successful in 2m40s
CI Review / dispatcher-test (pull_request) Successful in 3m6s
Lint & Validate / terraform-validate (pull_request) Successful in 8m5s
CI Review / cockpit-e2e (pull_request) Successful in 9m13s
50dceb096f
Pure pin bump. The three sbx-gits sbx-fleet image lines (initContainers
prepare-work and seed-pi-agent, container sandbox) move from

  platform/sbx-fleet:eebdbe1@sha256:7e0513ca...794c9e4

to

  platform/sbx-fleet:6fa150a@sha256:0ee5e97e...60ea53c

which is the digest CI published for merge commit
6fa150a4a9 of PR #839 on live (run #3119,
build-and-push success). That image adds openssh-client + openssh-server
for the ssh-lib spike tests.

No restart: updateStrategy is OnDelete, so sbx-gits-0 keeps its image
until the next scheduled restart.

sbx-lab keeps its own pin (2045e53); sbx-sendrast keeps its base image.
sbx-sendrast kustomize render is byte-identical to origin/live.
Collaborator

Verdict of record — ld-reviewer — head 50dceb096f: APPROVE
model: deepseek-flash
session: 01a1ab74-35e4-757a-b84d-274a1755f652

Independent seat, fresh context. Everything below was measured from primary sources — git objects in a fresh clone, the registry, the rendered output, and the live cluster — not taken from the PR description.

Blockers

  • None.

Concerns

  • C1: scripts/gits-sbx-epic-test.sh still pins the outgoing digest, so the repo's own invariant harness goes red after this merge. Check [3] hardcodes the expected image set at line 981 and check [3b] assigns the sbx-gits expectation at line 1006; both name platform/sbx-fleet:eebdbe1, as do the message strings at lines 984/986/1021 and the prose note at line 997. I re-ran both checks' exact logic against this head and both fail: manifest[3] reports an image-set mismatch, and [3b] raises sbx-gits-sin-sbx-fleet plus sbx-gits-otro-sbx-fleet. This gates nothing here — no workflow under .forgejo/ references the script, so CI stays green — but core/manifests/apps/sbx-gits/README.md and docs/gits-sbx/manifiesto.md both advertise bash scripts/gits-sbx-epic-test.sh as an exit-0 verification, so the pinned set needs re-measuring before the epic's official run. Precedent cuts both ways: the earlier sbx-gits pin bump moved the script in the same commit (3d4fa961), while the sbx-lab pin bump left it and a follow-up re-measured (3b711783, then 3833682e). The PR's own stated reasoning — that leaving an asserting line behind makes the directory's documented check fail — applies verbatim to this file, so the follow-up is small and mechanical: line 981, line 1006, and the four message strings.
  • C2: Two non-asserting mentions of the outgoing tag remain, and nothing parses them: the comment in core/manifests/monitoring/rules/sbx-gits-alerts.yaml (line 16) and two rows of docs/gits-sbx/sbx-checklist.md (lines 71 and 99). Cosmetic; worth sweeping whenever C1 is touched.

Verification

1. Diff scope — clean. In a fresh clone, git diff -U0 from the live head to this head is exactly 2 files, 6 insertions and 6 deletions. Filtering the changed lines down to those that do NOT carry an sbx-fleet image reference returns an empty set — every changed line is the pin. The three statefulset.yaml lines are the prepare-work and seed-pi-agent initContainers and the sandbox container; the three README lines are the layout snippet, the invariant grep, and the prose tag. No env, no volume, no resource, no updateStrategy, no other field, and nothing outside core/manifests/apps/sbx-gits/.

2. Digest — matches, and its provenance is the tag convention. crane digest harbor.aaron.reynoza.org/platform/sbx-fleet:6fa150a returns sha256:0ee5e97e9c24f81a3a65a712054dba7e3ffb0e300f5840315d5152ffa60ea53c, byte-equal to the pin in all six changed lines. The Harbor artifact API corroborates it: same digest, pushed 2026-11-05T11:05:57Z, 683.29 MiB, tag set ['6fa150a'], docker v2 manifest with 27 layers — a real image manifest, not an index or an attestation. The outgoing tag resolves to sha256:7e0513ca6f2d6a77a61e0157d2e3cc6be7d3d73f1618d634253081dcb794c9e4, which is exactly the digest this PR replaces. That 6fa150a is the tag CI published for the openssh merge follows from the workflow's own rule: sbx-fleet-image-build.yaml derives the tag as the first seven characters of the commit sha on pushes to live, and 6fa150a4… is that merge commit on live. One caveat on honesty of method: the Forgejo actions API was returning a database connection error throughout this review, so I could not re-read run #3119 directly; the provenance above is established independently of it.

3. Siblings untouched — proven by rendering both trees, not by file scope. kubectl kustomize on each app at the live head and at this head: sbx-sendrast is byte-identical on both sides (131099 bytes, sha256 d225759f534949db66b0cf066581d3a9c6f74f59ae2b4e10068b1429f736271a), sbx-lab is byte-identical on both sides (sha256 2e08f3dfe94ebab85a7594ff80ab87973e1d910096ff64913b760bd25e2f8069), and the android-emulator pin inside sbx-gits is unchanged. The sbx-gits render delta is exactly three image-line swaps: six changed lines in the resolved output, zero of them non-image, so the rendered object graph is unchanged apart from the image strings.

4. The outgoing pin really was the live pin — confirmed on the branch and on the cluster. On the live branch all three sbx-gits image lines carried the outgoing digest, and in the cluster both the sbx-gits StatefulSet and the running sbx-gits-0 pod carry it on all three containers (the emulator container keeps its own pin). updateStrategy is OnDelete, so merging does not recycle the pod — the PR's no-restart claim is honest, and the new template takes effect at the next scheduled restart.

The live branch is the branch base and has not moved since this branch forked, so there is no drift to re-review; the diff I judged is the diff that would land.

**Verdict of record — ld-reviewer — head 50dceb096fb4e6cdc5cc494b67c3d3b4545b8382: APPROVE** model: deepseek-flash session: 01a1ab74-35e4-757a-b84d-274a1755f652 Independent seat, fresh context. Everything below was measured from primary sources — git objects in a fresh clone, the registry, the rendered output, and the live cluster — not taken from the PR description. ## Blockers - None. ## Concerns - C1: `scripts/gits-sbx-epic-test.sh` still pins the outgoing digest, so the repo's own invariant harness goes red after this merge. Check `[3]` hardcodes the expected image set at line 981 and check `[3b]` assigns the `sbx-gits` expectation at line 1006; both name `platform/sbx-fleet:eebdbe1`, as do the message strings at lines 984/986/1021 and the prose note at line 997. I re-ran both checks' exact logic against this head and both fail: `manifest[3]` reports an image-set mismatch, and `[3b]` raises `sbx-gits-sin-sbx-fleet` plus `sbx-gits-otro-sbx-fleet`. This gates nothing here — no workflow under `.forgejo/` references the script, so CI stays green — but `core/manifests/apps/sbx-gits/README.md` and `docs/gits-sbx/manifiesto.md` both advertise `bash scripts/gits-sbx-epic-test.sh` as an exit-0 verification, so the pinned set needs re-measuring before the epic's official run. Precedent cuts both ways: the earlier `sbx-gits` pin bump moved the script in the same commit (`3d4fa961`), while the `sbx-lab` pin bump left it and a follow-up re-measured (`3b711783`, then `3833682e`). The PR's own stated reasoning — that leaving an asserting line behind makes the directory's documented check fail — applies verbatim to this file, so the follow-up is small and mechanical: line 981, line 1006, and the four message strings. - C2: Two non-asserting mentions of the outgoing tag remain, and nothing parses them: the comment in `core/manifests/monitoring/rules/sbx-gits-alerts.yaml` (line 16) and two rows of `docs/gits-sbx/sbx-checklist.md` (lines 71 and 99). Cosmetic; worth sweeping whenever C1 is touched. ## Verification **1. Diff scope — clean.** In a fresh clone, `git diff -U0` from the live head to this head is exactly 2 files, 6 insertions and 6 deletions. Filtering the changed lines down to those that do NOT carry an `sbx-fleet` image reference returns an empty set — every changed line is the pin. The three `statefulset.yaml` lines are the `prepare-work` and `seed-pi-agent` initContainers and the `sandbox` container; the three README lines are the layout snippet, the invariant grep, and the prose tag. No env, no volume, no resource, no `updateStrategy`, no other field, and nothing outside `core/manifests/apps/sbx-gits/`. **2. Digest — matches, and its provenance is the tag convention.** `crane digest harbor.aaron.reynoza.org/platform/sbx-fleet:6fa150a` returns `sha256:0ee5e97e9c24f81a3a65a712054dba7e3ffb0e300f5840315d5152ffa60ea53c`, byte-equal to the pin in all six changed lines. The Harbor artifact API corroborates it: same digest, pushed 2026-11-05T11:05:57Z, 683.29 MiB, tag set `['6fa150a']`, docker v2 manifest with 27 layers — a real image manifest, not an index or an attestation. The outgoing tag resolves to `sha256:7e0513ca6f2d6a77a61e0157d2e3cc6be7d3d73f1618d634253081dcb794c9e4`, which is exactly the digest this PR replaces. That `6fa150a` is the tag CI published for the openssh merge follows from the workflow's own rule: `sbx-fleet-image-build.yaml` derives the tag as the first seven characters of the commit sha on pushes to `live`, and `6fa150a4…` is that merge commit on `live`. One caveat on honesty of method: the Forgejo actions API was returning a database connection error throughout this review, so I could not re-read run #3119 directly; the provenance above is established independently of it. **3. Siblings untouched — proven by rendering both trees, not by file scope.** `kubectl kustomize` on each app at the live head and at this head: `sbx-sendrast` is byte-identical on both sides (131099 bytes, sha256 `d225759f534949db66b0cf066581d3a9c6f74f59ae2b4e10068b1429f736271a`), `sbx-lab` is byte-identical on both sides (sha256 `2e08f3dfe94ebab85a7594ff80ab87973e1d910096ff64913b760bd25e2f8069`), and the `android-emulator` pin inside `sbx-gits` is unchanged. The `sbx-gits` render delta is exactly three image-line swaps: six changed lines in the resolved output, zero of them non-image, so the rendered object graph is unchanged apart from the image strings. **4. The outgoing pin really was the live pin — confirmed on the branch and on the cluster.** On the live branch all three `sbx-gits` image lines carried the outgoing digest, and in the cluster both the `sbx-gits` StatefulSet and the running `sbx-gits-0` pod carry it on all three containers (the emulator container keeps its own pin). `updateStrategy` is `OnDelete`, so merging does not recycle the pod — the PR's no-restart claim is honest, and the new template takes effect at the next scheduled restart. The live branch is the branch base and has not moved since this branch forked, so there is no drift to re-review; the diff I judged is the diff that would land.
Collaborator

Reviewer correction — ld-reviewer — head 50dceb096f
model: deepseek-flash
session: 01a1ab74-35e4-757a-b84d-274a1755f652

Correction to my verdict comment 21953 — a note on my own formatting, not a change of stance. The approval stands at this head.

Under my ## Blockers heading I wrote the single bulleted line - None. meaning that nothing is open. The landing lock's leg-4 scan reads a bulleted determination as an id-less finding instead of an empty-section statement, so this PR surfaced as carrying one open finding. That is an artifact of how I shaped my comment, not a defect in the diff.

For the record, then: the blockers reported on this PR are resolved. Nothing is substantively open against this head. The two items I raised stay as Concerns — C1, the epic harness scripts/gits-sbx-epic-test.sh still pinning the outgoing digest, which gates nothing here (no workflow runs it) but needs re-measuring before the epic's official run; and C2, the cosmetic stale tag mentions in the alerts comment and the checklist prose.

My APPROVE of head 50dceb096f is unchanged, and my four verification results in comment 21953 stand as posted.

Note for reviewers handed the same brief: an empty blocker section reads correctly as a bare None. line with no leading bullet. The bulleted form is what trips the scanner.

**Reviewer correction — ld-reviewer — head 50dceb096fb4e6cdc5cc494b67c3d3b4545b8382** model: deepseek-flash session: 01a1ab74-35e4-757a-b84d-274a1755f652 Correction to my verdict comment 21953 — a note on my own formatting, not a change of stance. The approval stands at this head. Under my `## Blockers` heading I wrote the single bulleted line `- None.` meaning that nothing is open. The landing lock's leg-4 scan reads a bulleted determination as an id-less finding instead of an empty-section statement, so this PR surfaced as carrying one open finding. That is an artifact of how I shaped my comment, not a defect in the diff. For the record, then: the blockers reported on this PR are resolved. Nothing is substantively open against this head. The two items I raised stay as Concerns — C1, the epic harness `scripts/gits-sbx-epic-test.sh` still pinning the outgoing digest, which gates nothing here (no workflow runs it) but needs re-measuring before the epic's official run; and C2, the cosmetic stale tag mentions in the alerts comment and the checklist prose. My APPROVE of head 50dceb096fb4e6cdc5cc494b67c3d3b4545b8382 is unchanged, and my four verification results in comment 21953 stand as posted. Note for reviewers handed the same brief: an empty blocker section reads correctly as a bare `None.` line with no leading bullet. The bulleted form is what trips the scanner.
Sign in to join this conversation.
No reviewers
No labels
operator-review
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Homelab/infra-core!842
No description provided.