@@ -131,7 +131,7 @@ type KubernetesMachineReconciler struct {
131131// +kubebuilder:rbac:groups=infrastructure.dippynark.co.uk,resources=kubernetesmachines,verbs=get;list;watch;create;update;patch;delete
132132// +kubebuilder:rbac:groups=infrastructure.dippynark.co.uk,resources=kubernetesmachines/status,verbs=get;update;patch
133133// +kubebuilder:rbac:groups=cluster.x-k8s.io,resources=machines,verbs=get;list;watch
134- // +kubebuilder:rbac:groups=core,resources=pods,verbs=get;list;watch;create
134+ // +kubebuilder:rbac:groups=core,resources=pods,verbs=get;list;watch;create;delete
135135// +kubebuilder:rbac:groups=core,resources=pods/exec,verbs=create
136136// +kubebuilder:rbac:groups=core,resources=secrets,verbs=get;list;watch;create
137137// +kubebuilder:rbac:groups=core,resources=persistentvolumeclaims,verbs=get;list;watch;create
@@ -215,7 +215,7 @@ func (r *KubernetesMachineReconciler) Reconcile(req ctrl.Request) (_ ctrl.Result
215215
216216 // Handle deleted machines
217217 if ! kubernetesMachine .ObjectMeta .DeletionTimestamp .IsZero () {
218- return r .reconcileDelete (ctx , machine , kubernetesMachine )
218+ return r .reconcileDelete (ctx , machine , kubernetesMachine , cluster )
219219 }
220220
221221 // Make sure infrastructure is ready
@@ -511,6 +511,13 @@ func (r *KubernetesMachineReconciler) reconcileNormal(ctx context.Context, clust
511511 return ctrl.Result {}, nil
512512 }
513513 if kindContainerStatus .State .Terminated != nil {
514+
515+ if kubernetesMachine .Spec .AllowRecreation {
516+ // Delete Pod to allow it to be recreated
517+ log .Info ("Deleting Pod due to terminated kind container" )
518+ return ctrl.Result {}, r .Delete (ctx , machinePod )
519+ }
520+
514521 kubernetesMachine .Status .SetFailureReason (capierrors .UnsupportedChangeMachineError )
515522 kubernetesMachine .Status .SetFailureMessage (errors .Errorf ("kind container has terminated: %s" , kindContainerStatus .State .Terminated .Reason ))
516523
@@ -552,11 +559,11 @@ func (r *KubernetesMachineReconciler) reconcileNormal(ctx context.Context, clust
552559 return ctrl.Result {}, nil
553560}
554561
555- func (r * KubernetesMachineReconciler ) reconcileDelete (ctx context.Context , machine * clusterv1.Machine , kubernetesMachine * capkv1.KubernetesMachine ) (ctrl.Result , error ) {
556- // If the deleted machine is a control- plane node, exec kubeadm reset so the
557- // etcd member hosted on the machine gets removed in a controlled way
558-
559- if util .IsControlPlaneMachine (machine ) {
562+ func (r * KubernetesMachineReconciler ) reconcileDelete (ctx context.Context , machine * clusterv1.Machine , kubernetesMachine * capkv1.KubernetesMachine , cluster * clusterv1. Cluster ) (ctrl.Result , error ) {
563+ // If the deleted machine is a control plane node, exec kubeadm reset so the etcd member hosted on
564+ // the machine gets removed in a controlled way. If the cluster has been deleted then we skip this
565+ // step to stop it hanging forever in the case of control plane failure
566+ if cluster . ObjectMeta . DeletionTimestamp . IsZero () && util .IsControlPlaneMachine (machine ) {
560567 // Check if machine pod exists
561568 machinePod := & corev1.Pod {}
562569 err := r .Client .Get (ctx , types.NamespacedName {
0 commit comments