@@ -49,6 +49,16 @@ func (r *NodeFeatureDiscoveryReconciler) finalizeNFDOperand(ctx context.Context,
4949 return ctrl.Result {RequeueAfter : 10 * time .Second }, nil
5050 }
5151
52+ if instance .Spec .PruneOnDelete {
53+ klog .Info ("Deleting NFD labels and NodeFeature CRs from cluster" )
54+ if err := deployPrune (ctx , r , instance ); err != nil {
55+ klog .Error (err , "Failed to delete NFD labels and NodeFeature CRs from cluster" )
56+ return ctrl.Result {}, err
57+ }
58+ } else {
59+ klog .Warning ("PruneOnDelete is disabled, NFD labels and NodeFeature CRs will not be deleted from cluster" )
60+ }
61+
5262 // If all components are deleted, then remove the finalizer
5363 klog .Info ("Secondary check passed. Removing finalizer if it exists." )
5464 if r .hasFinalizer (instance , finalizer ) {
@@ -363,6 +373,100 @@ func (r *NodeFeatureDiscoveryReconciler) doComponentsExist(ctx context.Context,
363373 return false
364374}
365375
376+ // deployPrune deploys nfd-master with --prune option
377+ // to remove labels and NodeFeature CRs
378+ func deployPrune (ctx context.Context , r * NodeFeatureDiscoveryReconciler , instance * nfdv1.NodeFeatureDiscovery ) error {
379+ res , ctrl := addResourcesControls ("/opt/nfd/prune" )
380+ n := NFD {
381+ rec : r ,
382+ ins : instance ,
383+ idx : 0 ,
384+ }
385+
386+ n .controls = append (n .controls , ctrl )
387+ n .resources = append (n .resources , res )
388+
389+ // Run through all control functions, return an error on any NotReady resource.
390+ for {
391+ err := n .step ()
392+ if err != nil {
393+ return err
394+ }
395+ if n .last () {
396+ break
397+ }
398+ }
399+
400+ // wait until job is finished and then delete it
401+ err := wait .Poll (RetryInterval , time .Minute * 3 , func () (done bool , err error ) {
402+ job , err := r .getJob (ctx , instance .ObjectMeta .Namespace , nfdPruneApp )
403+ if err != nil {
404+ return false , err
405+ }
406+ if job .Status .Succeeded > 0 {
407+ return true , nil
408+ }
409+ return false , nil
410+ })
411+ if err != nil {
412+ return err
413+ }
414+
415+ // delete job and RBAC objects
416+ // Attempt to delete the Job
417+ err = wait .Poll (RetryInterval , Timeout , func () (done bool , err error ) {
418+ err = r .deleteJob (ctx , instance .ObjectMeta .Namespace , nfdPruneApp )
419+ if err != nil {
420+ return false , interpretError (err , "Prune Job" )
421+ }
422+ klog .Info ("nfd-prune Job resource has been deleted." )
423+ return true , nil
424+ })
425+ if err != nil {
426+ return err
427+ }
428+ // Attempt to delete the ServiceAccount
429+ err = wait .Poll (RetryInterval , Timeout , func () (done bool , err error ) {
430+ err = r .deleteServiceAccount (ctx , instance .ObjectMeta .Namespace , nfdPruneApp )
431+ if err != nil {
432+ return false , interpretError (err , "Prune ServiceAccount" )
433+ }
434+ klog .Info ("nfd-prune ServiceAccount resource has been deleted." )
435+ return true , nil
436+ })
437+ if err != nil {
438+ return err
439+ }
440+
441+ // Attempt to delete the ClusterRole
442+ err = wait .Poll (RetryInterval , Timeout , func () (done bool , err error ) {
443+ err = r .deleteClusterRole (ctx , instance .ObjectMeta .Namespace , nfdPruneApp )
444+ if err != nil {
445+ return false , interpretError (err , "Prune ClusterRole" )
446+ }
447+ klog .Info ("nfd-prune ClusterRole resource has been deleted." )
448+ return true , nil
449+ })
450+ if err != nil {
451+ return err
452+ }
453+
454+ // Attempt to delete the ClusterRoleBinding
455+ err = wait .Poll (RetryInterval , Timeout , func () (done bool , err error ) {
456+ err = r .deleteClusterRoleBinding (ctx , instance .ObjectMeta .Namespace , nfdPruneApp )
457+ if err != nil {
458+ return false , interpretError (err , "Prune ClusterRoleBinding" )
459+ }
460+ klog .Info ("nfd-prune ClusterRoleBinding resource has been deleted." )
461+ return true , nil
462+ })
463+ if err != nil {
464+ return err
465+ }
466+
467+ return nil
468+ }
469+
366470// interpretError determines if a resource has already been
367471// (successfully) deleted
368472func interpretError (err error , resourceName string ) error {
0 commit comments