Files
Timofei LarkinandClaude Opus 4.7 1dc02d44f4 refactor(lineage-controller-webhook): align with cozystack-api shape
Collapse the chart to a single Deployment shape that mirrors
cozystack-api: 2 replicas, soft (preferred) nodeAffinity to
node-role.kubernetes.io/control-plane via Exists, permissive
tolerations, soft podAntiAffinity on hostname, an unconditional
PodDisruptionBudget with maxUnavailable: 1, and a Service with
spec.trafficDistribution: PreferClose. The same shape works on
Talos / kubeadm / k3s and on managed Kubernetes / Cozy-in-Cozy
tenant clusters without per-distro overrides — fixing #2417 by
making the soft control-plane affinity gracefully fall back to
worker scheduling when no control-plane nodes are visible.

Drop the DaemonSet path entirely. The previous PR's deployment.enabled
toggle, the workload-kind switch in templates/workload.yaml, the
fail-guard for localK8sAPIEndpoint+nodeAffinity=[], the conditional
PDB, and the values-shape knobs for nodeAffinity and tolerations all
go away as a consequence. Override the standard Deployment fields
through the usual component-values mechanism if a non-default topology
is ever needed.

Mark localK8sAPIEndpoint.enabled deprecated and flip the default to
false. The flag injects KUBERNETES_SERVICE_HOST=status.hostIP, which
is only valid when the pod is actually scheduled on an apiserver-
bearing node. With the new soft control-plane affinity, the pod can
land off-control-plane and crash-loop. The latency motivation for the
flag is real but pending separate webhook performance work; once
addressed, the flag can be removed.

Revert all changes to packages/core/platform/images/migrations/migrations/20.
The earlier ds/...-or-deploy/... fallback was over-engineered: per
run-migrations.sh, migration 20 fires only when CURRENT < 20 (i.e.
direct upgrades from pre-0.37 to 1.3+), and that path is unsupported
anyway. The original ds/... rollout-status line is dead code on every
supported install and upgrade path.

Add helm-unittest coverage for: the default Deployment shape (replicas,
soft nodeAffinity, soft podAntiAffinity, tolerations); no env vars at
the default localK8sAPIEndpoint.enabled=false; PDB rendered
unconditionally with maxUnavailable: 1, including at replicas=1 (the
no-op case); replicas value drives spec.replicas; and that
localK8sAPIEndpoint.enabled=true does inject the env vars. The Service
test continues to assert trafficDistribution: PreferClose with no
internalTrafficPolicy.

Add a slim README documenting the topology, parameters, and the
deprecation note for localK8sAPIEndpoint.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Timofei Larkin <lllamnyp@gmail.com>
2026-04-28 14:55:11 +03:00

100 lines
3.1 KiB
YAML

suite: lineage-controller-webhook workload + PDB
templates:
- templates/workload.yaml
- templates/pdb.yaml
release:
name: lineage-controller-webhook
namespace: cozy-system
tests:
# ---- Default Deployment shape ----------------------------------------------
- it: defaults render a 2-replica Deployment with soft control-plane nodeAffinity, soft podAntiAffinity, and Exists tolerations
template: templates/workload.yaml
asserts:
- isKind:
of: Deployment
- equal:
path: spec.replicas
value: 2
- equal:
path: spec.template.spec.tolerations
value:
- operator: Exists
- equal:
path: spec.template.spec.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution
value:
- weight: 100
preference:
matchExpressions:
- key: node-role.kubernetes.io/control-plane
operator: Exists
- notExists:
path: spec.template.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution
- equal:
path: spec.template.spec.affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[0].podAffinityTerm.topologyKey
value: kubernetes.io/hostname
- it: defaults inject no localK8sAPIEndpoint env vars (knob is opt-in)
template: templates/workload.yaml
asserts:
- notExists:
path: spec.template.spec.containers[0].env
# ---- PDB --------------------------------------------------------------------
- it: PDB renders unconditionally with maxUnavailable=1 at the default replica count
template: templates/pdb.yaml
asserts:
- isKind:
of: PodDisruptionBudget
- equal:
path: spec.maxUnavailable
value: 1
- notExists:
path: spec.minAvailable
- it: PDB still renders at replicas=1 (no-op, but consistent shape)
set:
lineageControllerWebhook.replicas: 1
template: templates/pdb.yaml
asserts:
- isKind:
of: PodDisruptionBudget
- equal:
path: spec.maxUnavailable
value: 1
# ---- Replica override -------------------------------------------------------
- it: replicas value drives spec.replicas
set:
lineageControllerWebhook.replicas: 5
template: templates/workload.yaml
asserts:
- equal:
path: spec.replicas
value: 5
# ---- Deprecated localK8sAPIEndpoint knob -----------------------------------
- it: localK8sAPIEndpoint.enabled=true injects KUBERNETES_SERVICE_HOST and PORT env vars
set:
lineageControllerWebhook.localK8sAPIEndpoint.enabled: true
template: templates/workload.yaml
asserts:
- contains:
path: spec.template.spec.containers[0].env
content:
name: KUBERNETES_SERVICE_HOST
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: status.hostIP
- contains:
path: spec.template.spec.containers[0].env
content:
name: KUBERNETES_SERVICE_PORT
value: "6443"