docs: developer docs for resource finalizers (#20631)

This commit is contained in:
Semir Patel 2024-02-15 10:41:00 -06:00 committed by GitHub
parent 8425cd0f90
commit 2baf5e78a4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 67 additions and 0 deletions

View File

@ -477,6 +477,73 @@ func (barInitializer) Initialize(ctx context.Context, rt controller.Runtime) err
} }
``` ```
### Finalizer
A finalizer allows a controller to execute teardown logic before a
resource is deleted. This can be useful to perform cleanup or block
deletion until certain conditions are met.
Finalizers are encoded as keys within a resource's metadata map. It
is the responsibility of each controller that adds a finalizer to a
resource to remove the finalizer when it is marked for deletion.
Once a resource has no finalizers present, it is deleted by the
resource service.
When the `Delete` endpoint is called on a resource with one or more
finalizers, the resource is marked for deletion by adding an immutable
`deletionTimestamp` key to the resource's metadata map. The resource is
now effectively frozen and will only accept subsequent `Write`s
that remove finalizers. `WriteStatus` is still allowed.
The `resource` package API can be used to manage finalizers and
check whether a resource has been marked for deletion. You would
typically use this API within the logic of your controller's
`Reconcile` method to either put a finalizer in place or perform
cleanup and then remove a finalizer. Don't forget to `Write` your
changes once you add or remove finalizers.
```Go
package resource
// IsMarkedForDeletion returns true if a resource has been marked for deletion,
// false otherwise.
func IsMarkedForDeletion(res *pbresource.Resource) bool { ... }
// HasFinalizers returns true if a resource has one or more finalizers, false otherwise.
func HasFinalizers(res *pbresource.Resource) bool { ... }
// HasFinalizer returns true if a resource has a given finalizer, false otherwise.
func HasFinalizer(res *pbresource.Resource, finalizer string) bool { ... }
// AddFinalizer adds a finalizer to the given resource.
func AddFinalizer(res *pbresource.Resource, finalizer string) { ... }
// RemoveFinalizer removes a finalizer from the given resource.
func RemoveFinalizer(res *pbresource.Resource, finalizer string) { ... }
// GetFinalizers returns the set of finalizers for the given resource.
func GetFinalizers(res *pbresource.Resource) mapset.Set[string] { ... }
```
Example flow in a controller's `Reconcile` method
```Go
const finalizer = "consul.io/bar-finalizer"
func (barReconciler) Reconcile(ctx context.Context, rt controller.Runtime, req controller.Request) error {
...
// Check if resource is marked for deletion. If yes, perform cleanup, remove finalizer, and Write the resource
if resource.IsMarkedForDeletion(res) {
// Perform some cleanup...
return EnsureFinalizerRemoved(ctx, rt, res, finalizer)
}
// Check if resource has finalizer. If not, add it and Write the resource
if err := EnsureHasFinalizer(ctx, rt, res, finalizer); err != nil {
return err
}
}
```
## Ownership & Cascading Deletion ## Ownership & Cascading Deletion
The resource service implements a lightweight `1:N` ownership model where, on The resource service implements a lightweight `1:N` ownership model where, on