Stand up the lab
A four-node kind cluster, the chart from a package, and every image pinned by digest.
What it shows. What the other runs are against, and how to tell an install that finished from one that started.
A replay of a verified run, not a live cluster. 6 checks held while it was recorded. Play types it out in the frame below; the transcript is the same session, already there.
# The lab is one cluster, built from the versions this repository declares.$ demo/bin/lab versionskubernetes 1.37.0kind v0.33.0operator c08fc73ebbae4214f244f1b0d90f4359f0d5ef0aexecutor e2e-registry.demo.svc.cluster.local:5000/ptah-executor@sha256:137662e6db45b7fa5e9aa1f4d188fff8db74d913a13a2f1d426b4dd2b0a4702fptah f6e562c # The operator runs in its own namespace, two replicas, one leader.$ kubectl -n "$OPERATOR_NAMESPACE" get deploymentNAME READY UP-TO-DATE AVAILABLE AGEptah-operator-cert-rotator 1/1 1 1 8m15sptah-operator 2/2 2 2 8m15s # Available means the install finished. The image is a digest, so one exact build runs.$ kubectl -n "$OPERATOR_NAMESPACE" get deployment -o json \ | jq -r '.items[].spec.template.spec.containers[].image'e2e-registry.demo.svc.cluster.local:5000/ptah-operator@sha256:01f5f72a848666b45f2cc2f6df1e16453b94a7f2c54dbb794c6ef5e0c3d69a6be2e-registry.demo.svc.cluster.local:5000/ptah-operator@sha256:01f5f72a848666b45f2cc2f6df1e16453b94a7f2c54dbb794c6ef5e0c3d69a6b # Three resources -- the desired state, the plan, and the decision that lets it run.$ kubectl get crd -o custom-columns=NAME:.metadata.name,ESTABLISHED:'.status.conditions[?(@.type=="Established")].status' \ ptahschemas.operator.ptah.run ptahschemaplans.operator.ptah.run ptahschemaapprovals.operator.ptah.runNAME ESTABLISHEDptahschemas.operator.ptah.run Trueptahschemaplans.operator.ptah.run Trueptahschemaapprovals.operator.ptah.run True # The namespace it works in. Credentials are Secrets; the policy cannot be edited.$ kubectl -n "$NAMESPACE" get secret,configmapNAME TYPE DATA AGEsecret/demo-database Opaque 6 7m56ssecret/demo-database-broken Opaque 1 100ssecret/demo-mysql-database Opaque 5 7m54ssecret/demo-registry Opaque 4 7m57ssecret/demo-registry-pull kubernetes.io/dockerconfigjson 1 7m56ssecret/demo-shadow-database Opaque 2 7m36s NAME DATA AGEconfigmap/demo-migration-verification-policy 1 7m31sconfigmap/demo-verification-policy 1 7m31sconfigmap/e2e-verification-policy 1 8m24sconfigmap/kube-root-ca.crt 1 8m24s
What was checked
Every step states what has to hold before its output may be published. A condition is read as its type, status and reason on the live object, never as a phrase in a message.
| Step | Claim | Held |
|---|---|---|
| 1 | exits 0, prints "kubernetes", prints "kind", prints "operator", prints "executor", prints "ptah" | yes |
| 2 | exits 0, prints "ptah" | yes |
| 3 | deployment/$CONTROLLER: Available=True (MinimumReplicasAvailable) | yes |
| 3 | exits 0, prints "@sha256:" | yes |
| 4 | exits 0, prints "ptahschemas", prints "ptahschemaplans", prints "ptahschemaapprovals" | yes |
| 5 | exits 0, prints "demo-database", prints "demo-registry", prints "demo-verification-policy", never prints "password" | yes |
What it ran against
- Kubernetes1.37.0
- Operatorc08fc73ebbae
- Ptahf6e562c
- Executorsha256:137662e6db45
- Recorded2026-09-28
- Scenarios atc08fc73ebbae
What the commands read
A session is repeated, not admired, so every name in it is one your own environment can carry. There is nothing else: no helper of ours stands between a command and the cluster, and the recorder refuses a step that reads a name this list does not hold. The commands arekubectl, ptah and kubectl ptah, each of which you install once; the last one is the operator’s own read-only client.
- KUBECONFIGthe cluster the commands run against
- NAMESPACEthe namespace the schema and its database credentials live in
- OPERATOR_NAMESPACEwhere the chart installed the operator
- CONTROLLERthe controller Deployment’s name, from that release
- REGISTRY_IN_CLUSTERthe registry address a Pod in the cluster resolves
- PTAH_OCI_REGISTRYthe registry address the push goes to
- PTAH_OCI_USERNAMEthe account that push uses
- PTAH_OCI_PASSWORDits password, which no command prints
A session also uses demo/bin/lab in two places, and both are the lab handing over what it generated rather than doing the demonstration’s work:lab credentials prints the three registry values above, and lab manifestfills the published template with values the step states. Rundemo/acceptance/reproduce.sh to watch the same scenario repeated from a directory where neither exists, by an account that may not create a Job, with the plan approved by a second account that may create neither a schema nor a Job.
The scenario is demo/scenarios/lab-setup.yaml, and make demo replays the whole set against a lab of your own. All recorded runs.