fix(omni): make the oci-lab template and machine classes actually usable - #30
Merged
Conversation
Neither had ever worked, which is why oci-lab could not allocate machines.
1. oci-lab.yaml nested controlPlane and workers under the Cluster document.
omnictl rejects that outright:
field controlPlane not found in type models.Cluster
field workers not found in type models.Cluster
They must be separate --- documents. The template could never be validated,
let alone synced, so the cluster was built some other way and the file was
decorative.
2. The machine classes wrote matchLabels as a camelCase map. Omni takes
matchlabels (lowercase) as a LIST of selector strings and rejects the map
with "machine class should either have auto provision or match labels set".
So oci-cp and oci-worker did not exist in Omni at all — only the unraid-*
classes were registered.
Also drops the stale hint to use `omnictl machine set-labels`, which does not
exist in omnictl 1.9.3; labels are set with a MachineLabels resource.
Verified live: both classes now apply, the template validates, and a sync
allocates both OCI machines to oci-lab.
oci-lab.yaml holds Cluster/ControlPlane/Workers as separate YAML docs; safe_load only grabbed whichever loaded first. Filter to kind: Cluster.
Task 8f.6. The oci-lab cluster template referenced its patches as '../patches/...', which escape the template's parent dir. omnictl sync accepted them only with --allowed-dir; status failed outright with 'path escapes from parent'. That forced every CLI invocation to carry --allowed-dir and made the bare form unusable. Move the four oci-lab-only patches into omni/cluster-templates/patches/ (a sibling of the template) and reference them as patches/... — no upward traversal, so neither sync nor status needs --allowed-dir. generate-manifests.sh and docs/deploy/runbook.md pointed at the namespace so they'd write/push to the new path. The omni/patches directory is now empty and removed. Drift gate + selftest still pass; patches are oci-lab-only so nothing else references the former location.
Task 4.1b (automate-talos-upgrade-pipeline): make the drift gate capable of repairing the derived files it already validates, not only reporting drift. --write resolves oci-lab's version pairing from the hand-owned omni/versions.yaml and rewrites its owned files (machine classes' installImage tag, cluster template's talos.version/kubernetes.version) to agree with it. Conservative: touches only oci-lab-owned files, never omni/talos-image.yaml (the machine build ledger), and refuses to invent a pairing when oci-lab's kubernetes pin is unresolvable (talos override with no explicit kubernetes). This is the gitops-side half of moving the derived-file rewrite out of the talos-images build job. The build.yml rewiring that invokes it unattended is deliberately deferred (it reverses tested tasks 4.2/4.2a); --write alone is reviewable and independently testable.
The previous --write could point oci-lab's machine-class installImage at a ghcr.io/talos-images/installer tag the build had not pushed yet, so a versions.yaml edit ahead of a build would make oci provisioning pull a nonexistent image. installer_built() checks ghcr.io for the tag's manifest (anonymous pull token); write() refuses to proceed when the target installer is missing any --allow-unbuilt, which the build job itself passes once it has pushed the tag. Failures collapse to a clear message rather than silently leaving derived syntax in sync with an image that does not exist. Verified: built pin passes, simulated unbuilt refuses (rc 1), --allow-unbuilt overrides (rc 0).
…ment MetalLB was considered but this cluster already runs Cilium (kube-proxy replacement mode), which has the same ARP-based L2 VIP mechanism built in. Running MetalLB alongside would race Cilium for L2 announcement of the same addresses. Single /32 (10.10.210.30, verified free against wrt-london's live DHCP+ARP state), opt-in only via the syscode.dev/lan-vip label so it doesn't silently grab the address for an unrelated LoadBalancer Service. Plan: openspec/changes/add-metallb-lan-exposure (syscode-ai-internal-plans).
syscod3
added a commit
that referenced
this pull request
Aug 8, 2026
fix(omni): make the oci-lab template and machine classes actually usable
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
fix(omni): make the oci-lab template and machine classes actually usable
Neither had ever worked, which is why oci-lab could not allocate machines.
oci-lab.yaml nested controlPlane and workers under the Cluster document.
omnictl rejects that outright:
field controlPlane not found in type models.Cluster
field workers not found in type models.Cluster
They must be separate --- documents. The template could never be validated,
let alone synced, so the cluster was built some other way and the file was
decorative.
The machine classes wrote matchLabels as a camelCase map. Omni takes
matchlabels (lowercase) as a LIST of selector strings and rejects the map
with "machine class should either have auto provision or match labels set".
So oci-cp and oci-worker did not exist in Omni at all — only the unraid-*
classes were registered.
Also drops the stale hint to use
omnictl machine set-labels, which does notexist in omnictl 1.9.3; labels are set with a MachineLabels resource.
Verified live: both classes now apply, the template validates, and a sync
allocates both OCI machines to oci-lab.