Summary
Follow-up from #540. That issue fixed the app enum (Overseerr now accepted alongside Seerr
in the generated CRD schema — see LEGACY_APP_TYPE_ALIASES in crates/servarr-crds/src/v1alpha1/spec.rs),
which was the hard-rejection half of the bug (a kubectl apply using the old enum value was
outright rejected).
The other half is quieter and still unfixed: MediaStackSpec/ServarrAppSpec's seerr_sync
field has #[serde(default, alias = "overseerrSync")], but the generated CRD schema only
declares a seerrSync property. Kubernetes CRDs use structural schemas, which silently prune
any property not declared in the schema (no x-kubernetes-preserve-unknown-fields is set here) —
so a manifest that still uses overseerrSync doesn't get rejected, it gets silently dropped
during storage. The Rust-side serde alias never gets a chance to fire because the field never
reaches the operator.
Why this is a separate issue from #540
Unlike the app enum (a scalar with a closed value set — straightforward to extend via a custom
JsonSchema impl backed by a small explicit alias list, see #540's fix), seerr_sync is an
object-typed field. Making the schema accept a second property name that maps to the same field
would require adding a duplicate overseerrSync property to the whole spec struct's generated
properties object. schemars' #[schemars(extend(...))] attribute (used for the #540 fix)
replaces the value at a given top-level key wholesale rather than deep-merging — using it here to
inject one extra key into the derive-generated properties map risks wiping out or drifting from
the rest of the struct's derived properties, which is a correctness footgun, not a Overseerr ->
Seerr-style closed enum this small.
Proposed fix (needs its own design pass)
Options to evaluate:
Scope
Affects both ServarrAppSpec.seerr_sync (crates/servarr-crds/src/v1alpha1/spec.rs) and
MediaStackSpec.seerr_sync (crates/servarr-crds/src/v1alpha1/media_stack.rs).
Summary
Follow-up from #540. That issue fixed the
appenum (Overseerrnow accepted alongsideSeerrin the generated CRD schema — see
LEGACY_APP_TYPE_ALIASESincrates/servarr-crds/src/v1alpha1/spec.rs),which was the hard-rejection half of the bug (a
kubectl applyusing the old enum value wasoutright rejected).
The other half is quieter and still unfixed:
MediaStackSpec/ServarrAppSpec'sseerr_syncfield has
#[serde(default, alias = "overseerrSync")], but the generated CRD schema onlydeclares a
seerrSyncproperty. Kubernetes CRDs use structural schemas, which silently pruneany property not declared in the schema (no
x-kubernetes-preserve-unknown-fieldsis set here) —so a manifest that still uses
overseerrSyncdoesn't get rejected, it gets silently droppedduring storage. The Rust-side serde alias never gets a chance to fire because the field never
reaches the operator.
Why this is a separate issue from #540
Unlike the
appenum (a scalar with a closed value set — straightforward to extend via a customJsonSchemaimpl backed by a small explicit alias list, see #540's fix),seerr_syncis anobject-typed field. Making the schema accept a second property name that maps to the same field
would require adding a duplicate
overseerrSyncproperty to the whole spec struct's generatedpropertiesobject.schemars'#[schemars(extend(...))]attribute (used for the #540 fix)replaces the value at a given top-level key wholesale rather than deep-merging — using it here to
inject one extra key into the derive-generated
propertiesmap risks wiping out or drifting fromthe rest of the struct's derived properties, which is a correctness footgun, not a
Overseerr->Seerr-style closed enum this small.Proposed fix (needs its own design pass)
Options to evaluate:
extend) that duplicates theseerrSyncproperty definition underoverseerrSyncby$ref,applied generically to any field with a known legacy alias — avoids hand-duplicating the object
schema.
call on the
appenum, before this sprint revisited it) and rely on the migration guide (Add a 1.2 -> 1.3 upgrade/migration guide #541)telling users to rename
overseerrSync->seerrSyncin their manifests before applying.Scope
Affects both
ServarrAppSpec.seerr_sync(crates/servarr-crds/src/v1alpha1/spec.rs) andMediaStackSpec.seerr_sync(crates/servarr-crds/src/v1alpha1/media_stack.rs).