Files
home-network-k3s-impl/platform/image-automation/per-service/README.md
T
jakman85andClaude Opus 4.8 f538f8ff38 feat(updates): per-service update-policy render contract + Renovate config (R-UPD-01/R-UPD-03)
Map a ServiceDefinition `update` block to ImageRepository/ImagePolicy + the
$imagepolicy setter marker: stable-only (semver range + bare-X.Y.Z filterTags,
pre-release excluded, R-UPD-01), pin -> fixed image with no marker / suspended
policy (R-UPD-03). Worked pihole example under per-service/ (reference only, not
deployed; WS-GITOPS emits the equivalent into apps/<svc>/). Add renovate.json for
Helm chart / dependency / operator-manifest bumps: auto-merge minor/patch/digest on
green CI, major needs review, image managers disabled so Renovate never fights Flux
over a tag.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-08-24 22:14:48 -05:00

3.7 KiB

Per-service image-automation — the render contract (update block → Flux CRs)

Owner: WS-UPDATE (this contract) + WS-GITOPS (emits these next to each app's Deployment/HelmRelease under apps/). Serves: R-UPD-01 (stable-only), R-UPD-02 (no human/AI authoring), R-UPD-03 (pin / auto-rollback). Source of truth: renderer-contract.md §update, ADR-0009, docs/11.

These files are reference examples, deliberately not wired into any kustomization.yaml, so they never deploy. WS-GITOPS renders the equivalent per real container service into apps/<svc>/. The cluster-wide write-back engine that consumes the setter markers is ../image-update-automation.yaml.

What a container kind ServiceDefinition update block renders

For every kind: container service whose update.pin is unset, render THREE things:

update field Renders to Notes
(implicit — source.image) ImageRepository scans the registry repo on interval.
channel: stable + range ImagePolicy .spec.policy.semver.range stable-only: the range plus a filter that excludes pre-release tags (-alpha/-rc/…).
cadence ImageRepository.spec.interval (scan schedule) the "on a schedule" of R-UPD-02. Cron cadence → nearest Flux duration (Flux scans on a duration, not cron).
(image ref in the Deployment) a setter marker comment on the image: field # {"$imagepolicy": "<ns>:<name>"} — where image-automation writes the advanced tag.
autoRollbackOnFailedHealth: true delivery-side health gate + rollback see below — HelmRelease remediation, or Deployment progressDeadline + revert.
pin: <version> freeze render the image image: pinned to <version> with NO setter marker, and suspend (or omit) the ImagePolicy. Automation cannot advance a pinned service (R-UPD-03).

kind: vm services do not render these — they update in-guest (dnf-automatic/unattended-upgrades on cadence, cloud-init), per docs/11 §3. See catalog/vm-demo.yaml.

Stable-only (R-UPD-01) — the two guardrails

  1. semver range (.spec.policy.semver.range) — only versions matching the operator's range.
  2. pre-release exclusion — either a filterTags pattern that only admits X.Y.Z (no -suffix), or rely on semver's rule that pre-releases (1.2.3-rc1) sort below their release and are only selected if the range explicitly asks for them. We do BOTH (belt-and-braces) so an upstream latest or -rc tag can never be picked.

Auto-rollback (R-UPD-03) — where the health gate lives

The setter write only changes a tag in git; the rollback is enforced at delivery:

  • HelmRelease-delivered services (preferred): Flux HelmRelease.spec.upgrade.remediation.retries
    • .spec.rollback — a failed, health-gated upgrade auto-rolls-back to the last-good Helm revision. The image tag lives in the HelmRelease values with the setter marker, so a bad advance is caught and reverted by Flux with no human step. This is the mechanism the conformance test exercises.
  • Plain-Deployment services: the Deployment progressDeadlineSeconds + readiness probe make a bad image a stalled (never-Available) rollout; the old ReplicaSet keeps serving, and the UpdateHealthGateFailed alert fires (see platform/monitoring/alerts.yaml). Recovery is the next good advance or the operator pin escape hatch.

Either way a failed/rolled-back update alerts by email (R-UPD-02 + R-OBS) via the automated-updates PrometheusRule group.