@@ -17,38 +17,38 @@ limitations under the License.
17
17
package configmanager
18
18
19
19
import (
20
- "fmt "
20
+ "errors "
21
21
"sort"
22
22
"sync/atomic"
23
23
24
24
"k8s.io/apimachinery/pkg/labels"
25
25
"k8s.io/apimachinery/pkg/runtime/schema"
26
- utilruntime "k8s.io/apimachinery/pkg/util/runtime"
27
26
"k8s.io/client-go/tools/cache"
28
27
"k8s.io/klog/v2"
29
28
30
29
configv1alpha1 "github.com/karmada-io/karmada/pkg/apis/config/v1alpha1"
30
+ "github.com/karmada-io/karmada/pkg/util"
31
31
"github.com/karmada-io/karmada/pkg/util/fedinformer"
32
32
"github.com/karmada-io/karmada/pkg/util/fedinformer/genericmanager"
33
33
"github.com/karmada-io/karmada/pkg/util/helper"
34
34
)
35
35
36
- var resourceInterpreterCustomizationsGVR = schema.GroupVersionResource {
37
- Group : configv1alpha1 .GroupVersion .Group ,
38
- Version : configv1alpha1 .GroupVersion .Version ,
39
- Resource : "resourceinterpretercustomizations" ,
40
- }
41
-
42
36
// ConfigManager can list custom resource interpreter.
43
37
type ConfigManager interface {
44
38
CustomAccessors () map [schema.GroupVersionKind ]CustomAccessor
45
39
HasSynced () bool
40
+ // LoadConfig is used to load ResourceInterpreterCustomization into the cache,
41
+ // it requires the provided customizations to be a full list of objects.
42
+ // It is recommended to be called during startup. After called, HasSynced() will always
43
+ // return true, and CustomAccessors() will return a map of CustomAccessor containing
44
+ // all ResourceInterpreterCustomization configurations.
46
45
LoadConfig (customizations []* configv1alpha1.ResourceInterpreterCustomization )
47
46
}
48
47
49
48
// interpreterConfigManager collects the resource interpreter customization.
50
49
type interpreterConfigManager struct {
51
50
initialSynced atomic.Bool
51
+ informer genericmanager.SingleClusterInformerManager
52
52
lister cache.GenericLister
53
53
configuration atomic.Value
54
54
}
@@ -64,16 +64,12 @@ func (configManager *interpreterConfigManager) HasSynced() bool {
64
64
return true
65
65
}
66
66
67
- if configuration , err := configManager .lister .List (labels .Everything ()); err == nil && len (configuration ) == 0 {
68
- // the empty list we initially stored is valid to use.
69
- // Setting initialSynced to true, so subsequent checks
70
- // would be able to take the fast path on the atomic boolean in a
71
- // cluster without any customization configured.
72
- configManager .initialSynced .Store (true )
73
- // the informer has synced, and we don't have any items
74
- return true
67
+ err := configManager .updateConfiguration ()
68
+ if err != nil {
69
+ klog .ErrorS (err , "error updating configuration" )
70
+ return false
75
71
}
76
- return false
72
+ return true
77
73
}
78
74
79
75
// NewInterpreterConfigManager watches ResourceInterpreterCustomization and organizes
@@ -84,35 +80,48 @@ func NewInterpreterConfigManager(informer genericmanager.SingleClusterInformerMa
84
80
85
81
// In interpret command, rules are not loaded from server, so we don't start informer for it.
86
82
if informer != nil {
87
- manager .lister = informer .Lister (resourceInterpreterCustomizationsGVR )
83
+ manager .informer = informer
84
+ manager .lister = informer .Lister (util .ResourceInterpreterCustomizationsGVR )
88
85
configHandlers := fedinformer .NewHandlerOnEvents (
89
- func (_ interface {}) { manager .updateConfiguration () },
90
- func (_ , _ interface {}) { manager .updateConfiguration () },
91
- func (_ interface {}) { manager .updateConfiguration () })
92
- informer .ForResource (resourceInterpreterCustomizationsGVR , configHandlers )
86
+ func (_ interface {}) { _ = manager .updateConfiguration () },
87
+ func (_ , _ interface {}) { _ = manager .updateConfiguration () },
88
+ func (_ interface {}) { _ = manager .updateConfiguration () })
89
+ informer .ForResource (util . ResourceInterpreterCustomizationsGVR , configHandlers )
93
90
}
94
91
95
92
return manager
96
93
}
97
94
98
- func (configManager * interpreterConfigManager ) updateConfiguration () {
95
+ // updateConfiguration is used as the event handler for the ResourceInterpreterCustomization resource.
96
+ // Any changes (add, update, delete) to these resources will trigger this method, which loads all
97
+ // ResourceInterpreterCustomization resources and refreshes the internal cache accordingly.
98
+ // Note: During startup, some events may be missed if the informer has not yet synced. If all events
99
+ // are missed during startup, updateConfiguration will be called when HasSynced() is invoked for the
100
+ // first time, ensuring the cache is updated on first use.
101
+ func (configManager * interpreterConfigManager ) updateConfiguration () error {
102
+ if configManager .informer == nil {
103
+ return errors .New ("informer manager is not configured" )
104
+ }
105
+ if ! configManager .informer .IsInformerSynced (util .ResourceInterpreterCustomizationsGVR ) {
106
+ return errors .New ("informer of ResourceInterpreterCustomization not synced" )
107
+ }
108
+
99
109
configurations , err := configManager .lister .List (labels .Everything ())
100
110
if err != nil {
101
- utilruntime .HandleError (fmt .Errorf ("error updating configuration: %v" , err ))
102
- return
111
+ return err
103
112
}
104
113
105
114
configs := make ([]* configv1alpha1.ResourceInterpreterCustomization , len (configurations ))
106
115
for index , c := range configurations {
107
116
config := & configv1alpha1.ResourceInterpreterCustomization {}
108
117
if err = helper .ConvertToTypedObject (c , config ); err != nil {
109
- klog .Errorf ("Failed to transform ResourceInterpreterCustomization: %v" , err )
110
- return
118
+ return err
111
119
}
112
120
configs [index ] = config
113
121
}
114
122
115
123
configManager .LoadConfig (configs )
124
+ return nil
116
125
}
117
126
118
127
func (configManager * interpreterConfigManager ) LoadConfig (configs []* configv1alpha1.ResourceInterpreterCustomization ) {
0 commit comments