From 0358cb3246a7534b26807aecf2bc1af37a8643d6 Mon Sep 17 00:00:00 2001 From: Scot Wells Date: Thu, 20 Aug 2026 21:27:33 -0500 Subject: [PATCH] ci: publish the vpc-controller image and kustomize bundle The repo had no publishing pipeline, so the controller added in #6 could not be deployed anywhere. Add the sibling-standard publish workflow (validate kustomize, build/push the container image, then push the config tree as an OCI kustomize bundle with the image pinned to the same tag). Make the manifests safe to apply in one shot against a live cell: readiness is now gated on the webhook server having started, so the webhook Service takes no endpoint until the controller can admit Pods. The required --attachment-mode moves to an ATTACHMENT_MODE environment variable so an overlay can retarget a cell without rewriting the args list. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/publish.yaml | 40 +++++++++++++++++++++++++++++++ README.md | 7 ++++++ cmd/main.go | 5 +++- config/manager/kustomization.yaml | 4 ++++ config/manager/manager.yaml | 14 +++++++---- 5 files changed, 65 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/publish.yaml diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml new file mode 100644 index 0000000..3a82a01 --- /dev/null +++ b/.github/workflows/publish.yaml @@ -0,0 +1,40 @@ +name: Publish + +on: + push: + release: + types: ["published"] + +jobs: + validate-kustomize: + uses: datum-cloud/actions/.github/workflows/validate-kustomize.yaml@v1.21.0 + + publish-container-image: + needs: + - validate-kustomize + permissions: + id-token: write + contents: read + packages: write + attestations: write + uses: datum-cloud/actions/.github/workflows/publish-docker.yaml@v1.21.0 + with: + image-name: vpc-controller + platforms: linux/amd64,linux/arm64 + secrets: inherit + + # The bundle pins the image to this build, so it publishes after the image. + publish-kustomize-bundles: + needs: + - publish-container-image + permissions: + id-token: write + contents: read + packages: write + uses: datum-cloud/actions/.github/workflows/publish-kustomize-bundle.yaml@v1.21.0 + with: + bundle-name: ghcr.io/datum-cloud/vpc-controller-kustomize + bundle-path: config + image-name: ghcr.io/datum-cloud/vpc-controller + image-overlays: config/manager + secrets: inherit diff --git a/README.md b/README.md index 639fec0..6e4b83f 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,13 @@ kubectl apply -k config/crd # types only kubectl apply -k config/default # types, RBAC and the controller ``` +`config/default` requires cert-manager: it issues the webhook serving certificate and injects the CA into the `MutatingWebhookConfiguration`. The attachment mode is carried as the `ATTACHMENT_MODE` environment variable on the manager container (default `Hypervisor`), so a cell selects its mode with a small overlay patch rather than rewriting the args list. + +CI publishes on every push and release: + +- image: `ghcr.io/datum-cloud/vpc-controller` +- kustomize bundle (OCI, for Flux `OCIRepository`): `ghcr.io/datum-cloud/vpc-controller-kustomize`, with the image pinned to the matching tag + ## Development ```bash diff --git a/cmd/main.go b/cmd/main.go index 24882de..6e55155 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -137,7 +137,10 @@ func main() { setupLog.Error(err, "unable to set up health check") os.Exit(1) } - if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil { + // Gate readiness on the webhook server: with failurePolicy Fail, a Pod that + // reports Ready before the webhook serves would take endpoints and reject + // every labelled Pod in the cell. + if err := mgr.AddReadyzCheck("webhook", mgr.GetWebhookServer().StartedChecker()); err != nil { setupLog.Error(err, "unable to set up ready check") os.Exit(1) } diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml index 2926b52..2b29d45 100644 --- a/config/manager/kustomization.yaml +++ b/config/manager/kustomization.yaml @@ -2,3 +2,7 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - manager.yaml +images: + - name: ghcr.io/datum-cloud/vpc-controller + newName: ghcr.io/datum-cloud/vpc-controller + newTag: latest diff --git a/config/manager/manager.yaml b/config/manager/manager.yaml index ce62694..a7807e9 100644 --- a/config/manager/manager.yaml +++ b/config/manager/manager.yaml @@ -27,13 +27,16 @@ spec: type: RuntimeDefault containers: - name: manager - image: ghcr.io/datum-cloud/vpc-controller:latest + image: ghcr.io/datum-cloud/vpc-controller args: - --leader-elect - # Required. Hypervisor for microVM cells, Netns for container cells. - - --attachment-mode=Hypervisor + - --attachment-mode=$(ATTACHMENT_MODE) - --health-probe-bind-address=:8081 - --metrics-bind-address=:8080 + env: + # Required flag, carried as env so an overlay can retarget a cell by name. + - name: ATTACHMENT_MODE + value: Hypervisor ports: - name: metrics containerPort: 8080 @@ -49,12 +52,15 @@ spec: port: 8081 initialDelaySeconds: 15 periodSeconds: 20 + # /readyz includes the webhook server's started check, so the Service + # only gets an endpoint once the webhook can actually admit Pods. readinessProbe: httpGet: path: /readyz port: 8081 initialDelaySeconds: 5 - periodSeconds: 10 + periodSeconds: 5 + failureThreshold: 3 securityContext: allowPrivilegeEscalation: false capabilities: