Create oz and preview service #58
No reviewers
Labels
No labels
blocked
bug
duplicate
effort
high
effort
low
effort
medium
effort
minimal
enhancement
help wanted
invalid
pr
feedback
pr
reviewing
question
status
backlog
status
document
status
done
status
implement
status
pending
status
planning
status
reviewing
waiting
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
tepichord/milner!58
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/56-oz-preview-service"
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?
Closes #56
Automated PR created by forgejo-done adapter.
A preview used to render the change set's manifests and run a stand-in image, so "the preview passed" said nothing about the code under review: an edit to `oz/` could not fail the gate and nobody could see it before merge. PLAN.md Phase 6 named the cluster-side registry as the fix; this closes that loop. * `l3-build-oz` builds `oz/Dockerfile` with buildah and pushes `zot.faun-snapper.ts.net/preview/oz:pr-<n>`. That destination is forced by zot's retention policy: `preview/**` with `pr-*` tags is the only tier that gets trimmed, so a tag pushed anywhere else is kept for 90 days or 20 tags. * The image is smoke-tested *before* it is pushed — `buildah run` starts the freshly built image out of local storage — so a Dockerfile that forgot a COPY, or an entrypoint that cannot load, fails in seconds instead of surfacing as a ten-minute readiness timeout in a namespace nobody is watching. The push is then verified against the registry's tag list rather than assumed. * This is the pipeline's only privileged step, and it has to be. Buildah creates a user namespace, these nodes run with `user.max_user_namespaces = 0`, and Woodpecker's Kubernetes backend offers nothing narrower (`capabilities.add` is explicitly unsupported, so SYS_ADMIN alone cannot be requested). Every unprivileged route was measured and closed: rootless and `--userns=host` both fail with `unshare(CLONE_NEWUSER): Operation not permitted`, and `hostUsers: false` — the Kubernetes field for exactly this — cannot create its pod sandbox here at all, with 34 GB free and no DiskPressure. tests/test_static.py fails if privilege appears in any other step. * L3 hands that tag to the preview's values ConfigMap, and `apps/preview/oz.yaml` runs it. `${image}` now means exactly one thing — the image this change set built — so the stand-in keeps a literal one. * The router's `milner.dev/preview-service` label moves from the stand-in to the preview's own Service. The router requires exactly one match, and server-side apply drops the stale label when an existing preview is re-rendered (checked against the live cluster, not assumed). * A preview namespace holds placeholders, never the console's real credentials: it runs the change set's code, so a credential there is readable by any pull request that asks for it. The console boots and cannot sign anyone in — a fixture mode belongs to the service, not to this overlay. * PR-number resolution moves to `ci/preview-pr.sh`, called by both the build and L3 so the tag that gets built is the tag that gets deployed. One fact, one place: drift there would surface as an ImagePullBackOff three steps from the cause. Rehearsed against the live cluster with the real build context, short of pushing the branch: buildah builds `oz/Dockerfile`, the smoke test loads the result and prints "oz image loads", the push lands and the registry lists the tag; the negative case (an image that builds but omits the COPYs) exits non-zero with `ModuleNotFoundError`, so the step would stop before pushing; the kubelet pulls the preview-tier image; the overlay renders and passes kubeconform, conftest and real admission; the console pod reaches Ready on the placeholder env, so L3's readiness wait would pass; and the router serves its login redirect rather than the stand-in's page.Two bugs in the verification I added to catch a silent push, both found by running the commands in a cluster pod rather than by reading them: * `--retry-delay 2` — buildah wants a duration there, so it exited 125 with a usage error before pushing anything. It is `2s`. * `buildah images <name>` is not a filter: it fails with "image not known", so the local digest came back empty. The listing form with the name in the format works, and `{{.ID}}` is already the twelve-character prefix of the config digest, which is the number the registry's manifest carries. That second one is worth noting for how it failed rather than that it did: the guard caught it — an empty local digest fails the step instead of passing quietly — which is exactly the behaviour that was missing when a preview ran an older image with every gate green. Also hardened while here: the bake is checked by mounting the image and looking for the marker rather than by running it, so the check cannot depend on what the image does when it starts, and `buildah rm` is gone (the pod is ephemeral, so removing a container only removed a suspect). Verified end to end in a pod against the real Dockerfile: build, push, digest comparison PASS (0cee210daf80 on both sides), marker present in the mounted image, and the import smoke asserting the bake. Suite at 118, ruff clean.