Skip to content

Commit

Permalink
Implement deletion lifecycle hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelgugino committed Jul 6, 2020
1 parent 3ac7114 commit d5646a9
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 0 deletions.
12 changes: 12 additions & 0 deletions api/v1alpha3/machine_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,18 @@ const (

// MachineDeploymentLabelName is the label set on machines if they're controlled by MachineDeployment
MachineDeploymentLabelName = "cluster.x-k8s.io/deployment-name"

// PreDrainDeleteHookAnnotationPrefix annotation specifies the prefix we
// search each annotation for during the pre-drain.delete lifecycle hook
// to pause reconciliation of deletion. These hooks will prevent removal of
// draining the associated node until all are removed.
PreDrainDeleteHookAnnotationPrefix = "pre-drain.delete.hook.machine.cluster.x-k8s.io"

// PreTerminateDeleteHookAnnotationPrefix annotation specifies the prefix we
// search each annotation for during the pre-terminate.delete lifecycle hook
// to pause reconciliation of deletion. These hooks will prevent removal of
// an instance from an infrastructure provider until all are removed.
PreTerminateDeleteHookAnnotationPrefix = "pre-terminate.delete.hook.machine.cluster.x-k8s.io"
)

// ANCHOR: MachineSpec
Expand Down
21 changes: 21 additions & 0 deletions controllers/machine_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package controllers
import (
"context"
"fmt"
"strings"
"time"

"github.com/go-logr/logr"
Expand Down Expand Up @@ -290,6 +291,11 @@ func (r *MachineReconciler) reconcileDelete(ctx context.Context, cluster *cluste
}

if isDeleteNodeAllowed {
// pre-drain.delete lifecycle hook
// Return early without error, will requeue if/when the Hook is removed.
if waitForHook(clusterv1.PreDrainDeleteHookAnnotationPrefix, m.ObjectMeta.Annotations) {
return ctrl.Result{}, nil
}
// Drain node before deletion.
if _, exists := m.ObjectMeta.Annotations[clusterv1.ExcludeNodeDrainingAnnotation]; !exists {
logger.Info("Draining node", "node", m.Status.NodeRef.Name)
Expand All @@ -301,6 +307,12 @@ func (r *MachineReconciler) reconcileDelete(ctx context.Context, cluster *cluste
}
}

// pre-term.delete lifecycle hook
// Return early without error, will requeue if/when the Hook is removed.
if waitForHook(clusterv1.PreTerminateDeleteHookAnnotationPrefix, m.ObjectMeta.Annotations) {
return ctrl.Result{}, nil
}

if ok, err := r.reconcileDeleteExternal(ctx, m); !ok || err != nil {
// Return early and don't remove the finalizer if we got an error or
// the external reconciliation deletion isn't ready.
Expand Down Expand Up @@ -491,6 +503,15 @@ func (r *MachineReconciler) shouldAdopt(m *clusterv1.Machine) bool {
return metav1.GetControllerOf(m) == nil && !util.HasOwner(m.OwnerReferences, clusterv1.GroupVersion.String(), []string{"Cluster"})
}

func waitForHook(hookName string, annotations map[string]string) bool {
for key := range annotations {
if strings.HasPrefix(key, hookName) {
return true
}
}
return false
}

// writer implements io.Writer interface as a pass-through for klog.
type writer struct {
logFunc func(args ...interface{})
Expand Down

0 comments on commit d5646a9

Please sign in to comment.