feat(api): expose deletionPolicy so CRs are safe to rename #109
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/deletion-policy"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Renaming a
ForgejoRepositoryis a delete plus a create, and the delete's finalizer calledDeleteRepo()— destroying all code, refs and history. That single fact is why 56 gitmirror CRnames are frozen with a stale
-alice-<5char>stem and why the fleet Kustomization runsprune: falseforever. A name should not be un-editable because the operator has no way to say"release this CR, keep the thing".
Almost none of this is new.
libseanfarm-operator's reconcile harness already implementsDeletionPolicy(Retain|Delete) and already skips the remote delete forRetain, via theoptional
DeletionPolicyProviderinterface on the object. openbao and minio alreadyimplement it. The Forgejo types simply never exposed the field — and objects that don't
implement the interface are treated as always-
Delete.Defaults follow what the remote state is, not the kind's name.
Retainfor theirreplaceable:
repository(code + history) andteam(membership and permissions); alsouserandorganization, whoseDelete()already returnednil, so the field just makesexisting behaviour legible.
Deletefor grants, credentials and config — a collaborator grantor access token that outlives its CR is a security residue, so uniform
Retainwould be theless safe choice.
⚠ Behaviour change: deleting a
ForgejoRepositoryCR no longer deletes the repositoryunless
deletionPolicy: Deleteis set. The gitmirror decommission runbook needs updating.Each accessor re-encodes its default for the empty string as well as via
+kubebuilder:default. Both are required: kubebuilder defaults apply at write time, so the56 CRs already stored read back empty and would otherwise fall through to the harness default of
Delete— destroying precisely the state this field exists to protect.The coverage test derives the kind set from the scheme rather than a hand-written list, so a
CRD added later cannot inherit always-
Deletesilently; the per-kind defaults stay ahand-written table because that table is the spec. Mutation-tested both ways — flipping the
repository default to
Delete, and removing an accessor entirely — each is caught.make testgreen (incl. envtest); 14/14 CRDs carry the field with the library's enum.