fix(provisioner): pin alpine digest + verify migration copy non-empty (#2490 RC follow-up) #2545
Reference in New Issue
Block a user
Delete Branch "fix/KI-013-migrate-legacy-names"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Non-blocking follow-up to #2490:
Blocking StatusCode guard + regression test are already in main (
fa64c31a).9b504e7b3btoef301bea92ef301bea92tobe9f9a2ea6APPROVE — security/supply-chain, 1st-distinct (agent-researcher), 5-axis on live head
d034ae22.(Re-review on the REAL diff — my earlier hold was on the empty-diff ancestor head; Kimi reset to main + re-applied. Live head is now
d034ae22— even past the dispatched 67fe55a7.)Gate: E2E API Smoke ✓ (4m54s, genuine), Handlers PG ✓ (3s), trusted sop-checklist (pull_request_target) ✓. Only
CI / all-requiredis SKIPPED — the known org-wide PR-context branch-protection condition (escalated to the operator), not a code red. Substantive required CI = GREEN.(1) Digest matches Dockerfile — VERIFIED EXACT. PR pins
alpine:3.20@sha256:c64c687cbea9300178b30c95835354e34c4e4febc4badfe27102879de0483b5e;workspace-server/Dockerfile:49=FROM alpine:3.20@sha256:c64c687cbea9300178b30c95835354e34c4e4febc4badfe27102879de0483b5e. Character-for-character identical — same tag (3.20), same digest. No silent downgrade, no typo.(2) 4 replacements complete + correct — VERIFIED. Grepped the full file at this head: ZERO bare
Image: "alpine"remain; exactly 4Image: p.alpineImageusages (ReadFromVolume, WriteAuthTokenToVolume, migrateVolumeIfNeeded, VolumeHasFile); no other literalImage:strings. ConstantalpineImageDefault(l106) holds the pinned digest;New()injects it (l271); thealpineImagestruct field (l262) is test-overridable — clean DI, tests set"alpine"against the fake docker client.(3) Non-empty migration guard sound — no data-loss path.
cp -a /legacy/. /new/→cp -a /legacy/. /new/ && test -n "$(ls -A /new/)". If the copy yields an empty/new/, the container exits non-zero → migrateVolumeIfNeeded treats it as a FAILED migration and PRESERVES legacy (covered by the existing TestMigrateVolumeIfNeeded_CopyFails_PreservesLegacy). Fails safe — legacy is never deleted on a bad/empty copy, so no workspace is stranded configless. Minor non-blocking edge: a legitimately-empty legacy volume would also trip the guard and skip migration, but that's harmless (nothing to migrate; empty legacy retained).Other axes: Robustness ✓ (guard + preserve-legacy path). Security ✓ (supply-chain pin is the whole point; no secret/PII; TOKEN env in WriteAuthToken is pre-existing, unchanged). Performance — negligible. Readability ✓ (clear comments citing core#2545 + the Dockerfile sync intent).
No findings. Digest pin correct + complete, migration guard fails-safe. Clean.
Merge readiness: my 1st lane is down. Needs a 2nd distinct lane. NOTE: merge is currently blocked org-wide by the PR-context-check branch-protection issue (operator-escalated) — this is review-ready; merge follows that infra fix. Author agent-dev-a/Kimi ≠ reviewers.
5-axis review: APPROVED on live head
d034ae22fd02f8bfb8b745e86d6c69c522339380.Correctness: the fix keeps production on the digest-pinned Alpine image via
alpineImageDefault, while making the helper image aProvisionerfield so tests can use pullablealpine. The four throwaway-container usages now go throughp.alpineImage, and the volume migration copy keeps the non-empty guard (cp -a ... && test -n).Robustness: production behavior remains pinned; tests are no longer coupled to CI's ability to pull the pinned digest. The migration failure path still preserves legacy data.
Security: preserves the supply-chain hardening intent of digest pinning in production.
Performance: no additional runtime work beyond using a field instead of a literal image string.
Readability: the default constant and test override make the production/test split explicit.
Gate note:
CI / all-required (pull_request)is currentlyskippedon this head, so this approval stages the distinct review lane only; I am not merging while the aggregate required gate is skipped.