Skip to main content

Module invariants

Module invariants 

Source
Expand description

Security-context invariants for the resolved mover pod.

The mover’s effective container + pod security contexts are produced by the field-wise merge hardened ⊂ moverDefaults ⊂ recipe/inheritSecurityContextFrom (crate::common::resolve_mover). Because each field is taken from whichever layer set it, the merge can assemble a combination no single layer intended — and some such combinations are rejected by the kubelet or the API server. A rejected pod never reaches a terminal phase, so the Job’s backoffLimit never trips and only the (long, hours-scale) activeDeadlineSeconds would ever stop it: the mover hangs, hammering the API, exactly the production failure that motivated this module.

This is the single place that normalizes a resolved (SecurityContext, PodSecurityContext) pair into a spec the kubelet/apiserver always accept. Each invariant is a small, pure, individually-tested function; enforce_security_context_invariants composes them. Normalization only ever relaxes a self-contradiction into the intent the merge clearly expressed (e.g. an inherited root UID means “run as root”) — it never grants privilege the layers didn’t ask for, and elevated results are still caught by the privileged-mover gate (crate::common::requires_privilege_resolved).

Adding a new invariant: write a fn(SecurityContext[, PodSecurityContext]) -> … that is idempotent (applying it twice equals applying it once) and a no-op on already-valid input, chain it in enforce_security_context_invariants, and add a focused test plus a case to the all_invariants_are_idempotent test.

Functions§

enforce_security_context_invariants
Enforce every security-context invariant on a fully-resolved mover (container, pod) context pair, returning a kubelet/apiserver-valid pair. Pure; the composition order is irrelevant because the invariants touch disjoint fields. Idempotent.