mirror of
https://github.com/zalando/postgres-operator.git
synced 2026-10-18 14:37:32 +02:00
Use finalizers to avoid losing delete events and to ensure full resource cleanup (#941)
* Add Finalizer functions to Cluster; add/remove finalizer on Create/Delete events * Check if clusters have a deletion timestamp and we missed that event. Run Delete() and remove finalizer when done. * Fix nil handling when using Service from map; Remove Service, Endpoint entries from their maps - just like with Secrets * Add handling of ResourceNotFound to all delete functions (Service, Endpoint, LogicalBackup CronJob, PDB and Secret) - this is not a real error when deleting things * Emit events when there are issues deleting resources to the user is informed * Depend the removal of the Finalizer on all resources being deleted successfully first. Otherwise the next sync run should let us try again * Add config option to enable finalizers * Removed dangling whitespace at EOL * config.EnableFinalizers is a bool pointer --------- Co-authored-by: Felix Kunde <felix-kunde@gmx.de>
This commit is contained in:
co-authored by
Felix Kunde
parent
9581ba969b
commit
743aade45f
+36
-16
@@ -247,9 +247,12 @@ func (c *Cluster) deleteStatefulSet() error {
|
||||
}
|
||||
|
||||
err := c.KubeClient.StatefulSets(c.Statefulset.Namespace).Delete(context.TODO(), c.Statefulset.Name, c.deleteOptions)
|
||||
if err != nil {
|
||||
if k8sutil.ResourceNotFound(err) {
|
||||
c.logger.Debugf("StatefulSet was already deleted")
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.logger.Infof("statefulset %q has been deleted", util.NameFromMeta(c.Statefulset.ObjectMeta))
|
||||
c.Statefulset = nil
|
||||
|
||||
@@ -336,18 +339,21 @@ func (c *Cluster) updateService(role PostgresRole, oldService *v1.Service, newSe
|
||||
func (c *Cluster) deleteService(role PostgresRole) error {
|
||||
c.logger.Debugf("deleting service %s", role)
|
||||
|
||||
service, ok := c.Services[role]
|
||||
if !ok {
|
||||
if c.Services[role] == nil {
|
||||
c.logger.Debugf("No service for %s role was found, nothing to delete", role)
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := c.KubeClient.Services(service.Namespace).Delete(context.TODO(), service.Name, c.deleteOptions); err != nil {
|
||||
return err
|
||||
if err := c.KubeClient.Services(c.Services[role].Namespace).Delete(context.TODO(), c.Services[role].Name, c.deleteOptions); err != nil {
|
||||
if k8sutil.ResourceNotFound(err) {
|
||||
c.logger.Debugf("Service was already deleted")
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
c.logger.Infof("%s service %q has been deleted", role, util.NameFromMeta(service.ObjectMeta))
|
||||
c.Services[role] = nil
|
||||
c.logger.Infof("%s service %q has been deleted", role, util.NameFromMeta(c.Services[role].ObjectMeta))
|
||||
delete(c.Services, role)
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -448,9 +454,12 @@ func (c *Cluster) deletePodDisruptionBudget() error {
|
||||
err := c.KubeClient.
|
||||
PodDisruptionBudgets(c.PodDisruptionBudget.Namespace).
|
||||
Delete(context.TODO(), c.PodDisruptionBudget.Name, c.deleteOptions)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not delete pod disruption budget: %v", err)
|
||||
if k8sutil.ResourceNotFound(err) {
|
||||
c.logger.Debugf("PodDisruptionBudget was already deleted")
|
||||
} else if err != nil {
|
||||
return fmt.Errorf("could not delete PodDisruptionBudget: %v", err)
|
||||
}
|
||||
|
||||
c.logger.Infof("pod disruption budget %q has been deleted", util.NameFromMeta(c.PodDisruptionBudget.ObjectMeta))
|
||||
c.PodDisruptionBudget = nil
|
||||
|
||||
@@ -479,14 +488,16 @@ func (c *Cluster) deleteEndpoint(role PostgresRole) error {
|
||||
return fmt.Errorf("there is no %s endpoint in the cluster", role)
|
||||
}
|
||||
|
||||
if err := c.KubeClient.Endpoints(c.Endpoints[role].Namespace).Delete(
|
||||
context.TODO(), c.Endpoints[role].Name, c.deleteOptions); err != nil {
|
||||
return fmt.Errorf("could not delete endpoint: %v", err)
|
||||
if err := c.KubeClient.Endpoints(c.Endpoints[role].Namespace).Delete(context.TODO(), c.Endpoints[role].Name, c.deleteOptions); err != nil {
|
||||
if k8sutil.ResourceNotFound(err) {
|
||||
c.logger.Debugf("Endpoint was already deleted")
|
||||
} else if err != nil {
|
||||
return fmt.Errorf("could not delete endpoint: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
c.logger.Infof("endpoint %q has been deleted", util.NameFromMeta(c.Endpoints[role].ObjectMeta))
|
||||
|
||||
c.Endpoints[role] = nil
|
||||
delete(c.Endpoints, role)
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -514,7 +525,9 @@ func (c *Cluster) deleteSecret(uid types.UID, secret v1.Secret) error {
|
||||
secretName := util.NameFromMeta(secret.ObjectMeta)
|
||||
c.logger.Debugf("deleting secret %q", secretName)
|
||||
err := c.KubeClient.Secrets(secret.Namespace).Delete(context.TODO(), secret.Name, c.deleteOptions)
|
||||
if err != nil {
|
||||
if k8sutil.ResourceNotFound(err) {
|
||||
c.logger.Debugf("Secret was already deleted")
|
||||
} else if err != nil {
|
||||
return fmt.Errorf("could not delete secret %q: %v", secretName, err)
|
||||
}
|
||||
c.logger.Infof("secret %q has been deleted", secretName)
|
||||
@@ -573,7 +586,14 @@ func (c *Cluster) deleteLogicalBackupJob() error {
|
||||
|
||||
c.logger.Info("removing the logical backup job")
|
||||
|
||||
return c.KubeClient.CronJobsGetter.CronJobs(c.Namespace).Delete(context.TODO(), c.getLogicalBackupJobName(), c.deleteOptions)
|
||||
err := c.KubeClient.CronJobsGetter.CronJobs(c.Namespace).Delete(context.TODO(), c.getLogicalBackupJobName(), c.deleteOptions)
|
||||
if k8sutil.ResourceNotFound(err) {
|
||||
c.logger.Debugf("LogicalBackup CronJob was already deleted")
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetServiceMaster returns cluster's kubernetes master Service
|
||||
|
||||
Reference in New Issue
Block a user