@@ -30,6 +30,7 @@ import (
30
30
"sigs.k8s.io/controller-runtime/pkg/log"
31
31
)
32
32
33
+ //+kubebuilder:rbac:groups="core",resources=namespaces,verbs=get;list;patch;watch
33
34
//+kubebuilder:rbac:groups="core",resources=nodes,verbs=get;watch
34
35
//+kubebuilder:rbac:groups=kmm.sigs.x-k8s.io,resources=nodemodulesconfigs,verbs=get;list;watch;patch;create;delete
35
36
@@ -47,6 +48,7 @@ type schedulingData struct {
47
48
48
49
type ModuleNMCReconciler struct {
49
50
filter * filter.Filter
51
+ nsHelper namespaceHelper
50
52
reconHelper moduleNMCReconcilerHelperAPI
51
53
}
52
54
@@ -59,6 +61,7 @@ func NewModuleNMCReconciler(client client.Client,
59
61
reconHelper := newModuleNMCReconcilerHelper (client , kernelAPI , registryAPI , nmcHelper , scheme )
60
62
return & ModuleNMCReconciler {
61
63
filter : filter ,
64
+ nsHelper : newNamespaceHelper (client ),
62
65
reconHelper : reconHelper ,
63
66
}
64
67
}
@@ -78,13 +81,21 @@ func (mnr *ModuleNMCReconciler) Reconcile(ctx context.Context, req ctrl.Request)
78
81
}
79
82
if mod .GetDeletionTimestamp () != nil {
80
83
//Module is being deleted
84
+ if err = mnr .nsHelper .tryRemovingLabel (ctx , mod .Namespace , mod .Name ); err != nil {
85
+ return ctrl.Result {}, fmt .Errorf ("error while trying to remove the label on namespace %s: %v" , mod .Namespace , err )
86
+ }
87
+
81
88
err = mnr .reconHelper .finalizeModule (ctx , mod )
82
89
if err != nil {
83
90
return ctrl.Result {}, fmt .Errorf ("failed to finalize %s Module: %v" , req .NamespacedName , err )
84
91
}
85
92
return ctrl.Result {}, nil
86
93
}
87
94
95
+ if err = mnr .nsHelper .setLabel (ctx , mod .Namespace ); err != nil {
96
+ return ctrl.Result {}, fmt .Errorf ("could not set label %q on namespace %s: %v" , constants .NamespaceLabelKey , mod .Namespace , err )
97
+ }
98
+
88
99
err = mnr .reconHelper .setFinalizerAndStatus (ctx , mod )
89
100
if err != nil {
90
101
return ctrl.Result {}, fmt .Errorf ("failed to set finalizer on %s Module: %v" , req .NamespacedName , err )
@@ -145,7 +156,7 @@ func (mnr *ModuleNMCReconciler) SetupWithManager(mgr ctrl.Manager) error {
145
156
Complete (mnr )
146
157
}
147
158
148
- //go:generate mockgen -source=module_nmc_reconciler.go -package=controllers -destination=mock_module_nmc_reconciler.go moduleNMCReconcilerHelperAPI
159
+ //go:generate mockgen -source=module_nmc_reconciler.go -package=controllers -destination=mock_module_nmc_reconciler.go moduleNMCReconcilerHelperAPI,
149
160
150
161
type moduleNMCReconcilerHelperAPI interface {
151
162
setFinalizerAndStatus (ctx context.Context , mod * kmmv1beta1.Module ) error
@@ -439,6 +450,82 @@ func (mnrh *moduleNMCReconcilerHelper) moduleUpdateWorkerPodsStatus(ctx context.
439
450
return mnrh .client .Status ().Patch (ctx , mod , client .MergeFrom (unmodifiedMod ))
440
451
}
441
452
453
+ type namespaceHelper interface {
454
+ setLabel (ctx context.Context , name string ) error
455
+ tryRemovingLabel (ctx context.Context , name , moduleName string ) error
456
+ }
457
+
458
+ type namespaceHelperImpl struct {
459
+ client client.Client
460
+ }
461
+
462
+ func newNamespaceHelper (client client.Client ) namespaceHelper {
463
+ return & namespaceHelperImpl {client : client }
464
+ }
465
+
466
+ func (h * namespaceHelperImpl ) setLabel (ctx context.Context , name string ) error {
467
+ logger := log .FromContext (ctx )
468
+
469
+ ns := v1.Namespace {}
470
+
471
+ if err := h .client .Get (ctx , types.NamespacedName {Name : name }, & ns ); err != nil {
472
+ return fmt .Errorf ("could not get namespace %s: %v" , name , err )
473
+ }
474
+
475
+ if ! meta .HasLabel (& ns , constants .NamespaceLabelKey ) {
476
+ nsCopy := ns .DeepCopy ()
477
+
478
+ logger .Info ("Setting namespace label" )
479
+ meta .SetLabel (& ns , constants .NamespaceLabelKey , "" )
480
+
481
+ return h .client .Patch (ctx , & ns , client .MergeFrom (nsCopy ))
482
+ }
483
+
484
+ return nil
485
+ }
486
+
487
+ func (h * namespaceHelperImpl ) tryRemovingLabel (ctx context.Context , name , moduleName string ) error {
488
+ logger := log .FromContext (ctx )
489
+
490
+ modList := kmmv1beta1.ModuleList {}
491
+
492
+ opt := client .InNamespace (name )
493
+
494
+ if err := h .client .List (ctx , & modList , opt ); err != nil {
495
+ return fmt .Errorf ("could not list modules in namespace %s: %v" , name , err )
496
+ }
497
+
498
+ modNames := sets .New [string ]()
499
+
500
+ for _ , m := range modList .Items {
501
+ modNames .Insert (m .Name )
502
+ }
503
+
504
+ modNames .Delete (moduleName )
505
+
506
+ if count := modNames .Len (); count != 0 {
507
+ logger .Info ("Namespace still contains modules; not removing the label" )
508
+
509
+ if verboseLogger := logger .V (1 ); verboseLogger .Enabled () {
510
+ verboseLogger .Info ("Remaining modules" , "names" , modNames .UnsortedList ())
511
+ }
512
+
513
+ return nil
514
+ }
515
+
516
+ ns := & v1.Namespace {}
517
+
518
+ if err := h .client .Get (ctx , types.NamespacedName {Name : name }, ns ); err != nil {
519
+ return fmt .Errorf ("could not get namespace %s: %v" , name , err )
520
+ }
521
+
522
+ nsCopy := ns .DeepCopy ()
523
+
524
+ meta .RemoveLabel (ns , constants .NamespaceLabelKey )
525
+
526
+ return h .client .Patch (ctx , ns , client .MergeFrom (nsCopy ))
527
+ }
528
+
442
529
func prepareNodeSchedulingData (node v1.Node , mld * api.ModuleLoaderData , currentNMCs sets.Set [string ]) schedulingData {
443
530
versionLabel := ""
444
531
present := false
0 commit comments