4343 enablev1alpha1API = flag .Bool ("enablev1alpha1API" , false , "Enable v1alpha1 APIs (default false)" )
4444 enablev1beta1API = flag .Bool ("enablev1beta1API" , false , "Enable v1beta1 APIs (default false)" )
4545 mode = flag .String ("mode" , "" , "Mode to run in: 'hub' or 'member' (required)" )
46- waitForSuccess = flag .Bool ("wait" , true , "Wait for CRDs to be established before returning" )
47- timeout = flag .Int ("timeout" , 60 , "Timeout in seconds for waiting for CRDs to be established" )
4846
4947 v1beta1HubCRDs = map [string ]bool {
5048 "cluster.kubernetes-fleet.io_memberclusters.yaml" : true ,
@@ -122,54 +120,19 @@ func main() {
122120
123121 // Install CRDs from the fixed location.
124122 const crdPath = "/workspace/config/crd/bases"
125- if err := installCRDs (ctx , client , crdPath , * mode , * waitForSuccess , * timeout ); err != nil {
123+ if err := installCRDs (ctx , client , crdPath , * mode ); err != nil {
126124 klog .Fatalf ("Failed to install CRDs: %v" , err )
127125 }
128126
129127 klog .Infof ("Successfully installed %s CRDs" , * mode )
130128}
131129
132130// installCRDs installs the CRDs from the specified directory based on the mode.
133- func installCRDs (ctx context.Context , client client.Client , crdPath , mode string , wait bool , _ int ) error {
131+ func installCRDs (ctx context.Context , client client.Client , crdPath , mode string ) error {
134132 // Set of CRD filenames to install based on mode.
135- crdFilesToInstall := make (map [string ]bool )
136-
137- // Walk through the CRD directory and collect filenames.
138- if err := filepath .WalkDir (crdPath , func (path string , d fs.DirEntry , err error ) error {
139- // Handle errors from WalkDir.
140- if err != nil {
141- return err
142- }
143-
144- // Skip directories.
145- if d .IsDir () {
146- return nil
147- }
148-
149- // Only process yaml files.
150- if filepath .Ext (path ) != ".yaml" && filepath .Ext (path ) != ".yml" {
151- return nil
152- }
153-
154- // Process based on mode.
155- filename := filepath .Base (path )
156- isHubCRD := isHubCRD (filename )
157- isMemberCRD := isMemberCRD (filename )
158-
159- switch mode {
160- case "hub" :
161- if isHubCRD {
162- crdFilesToInstall [path ] = true
163- }
164- case "member" :
165- if isMemberCRD {
166- crdFilesToInstall [path ] = true
167- }
168- }
169-
170- return nil
171- }); err != nil {
172- return fmt .Errorf ("failed to walk CRD directory: %w" , err )
133+ crdFilesToInstall , err := collectCRDFileNames (crdPath , mode )
134+ if err != nil {
135+ return err
173136 }
174137
175138 if len (crdFilesToInstall ) == 0 {
@@ -204,23 +167,15 @@ func installCRDs(ctx context.Context, client client.Client, crdPath, mode string
204167 return fmt .Errorf ("unexpected type from %s, expected CustomResourceDefinition but got %s" , path , gvk )
205168 }
206169
207- var existingCRD apiextensionsv1.CustomResourceDefinition
208- if err := client .Get (ctx , types.NamespacedName {Name : crd .Name }, & existingCRD ); err != nil {
209- if ! errors .IsNotFound (err ) {
210- return fmt .Errorf ("failed to get existing CRD %s: %w" , crd .Name , err )
211- }
170+ isManagedByAddonManager , err := isCRDManagedByAddonManager (ctx , client , crd .Name )
171+ if err != nil {
172+ return err
212173 }
213-
214- labels := existingCRD .GetLabels ()
215- if labels != nil {
216- if _ , exists := labels ["addonmanager.kubernetes.io/mode" ]; exists {
217- klog .Infof ("CRD %s is still managed by the addon manager, skipping installation" , crd .Name )
218- continue
219- }
174+ if isManagedByAddonManager {
175+ continue
220176 }
221177
222- // Reset existing CRD to create or update it.
223- existingCRD = apiextensionsv1.CustomResourceDefinition {
178+ existingCRD := apiextensionsv1.CustomResourceDefinition {
224179 ObjectMeta : metav1.ObjectMeta {
225180 Name : crd .Name ,
226181 },
@@ -229,15 +184,16 @@ func installCRDs(ctx context.Context, client client.Client, crdPath, mode string
229184 createOrUpdateRes , err := controllerutil .CreateOrUpdate (ctx , client , & existingCRD , func () error {
230185 // Copy spec from our decoded CRD to the object we're creating/updating.
231186 existingCRD .Spec = crd .Spec
232- existingCRD .SetLabels (crd .Labels )
233-
187+
234188 // Add an additional ownership label to indicate this CRD is managed by the installer.
235189 if existingCRD .Labels == nil {
236190 existingCRD .Labels = make (map [string ]string )
237191 }
238- existingCRD .Labels ["crd-installer.kubernetes-fleet.io/managed" ] = "true"
239-
240- existingCRD .SetAnnotations (crd .Annotations )
192+ // Ensure the label for management by the installer is set.
193+ _ , ok := existingCRD .Labels ["crd-installer.kubernetes-fleet.io/managed" ]
194+ if ! ok {
195+ existingCRD .Labels ["crd-installer.kubernetes-fleet.io/managed" ] = "true"
196+ }
241197 return nil
242198 })
243199
@@ -249,12 +205,27 @@ func installCRDs(ctx context.Context, client client.Client, crdPath, mode string
249205 klog .Infof ("Successfully created/updated CRD %s" , crd .Name )
250206 }
251207
252- if wait {
253- // TODO: Implement wait logic for CRDs to be established.
254- klog .Info ("Waiting for CRDs to be established is not implemented yet" )
208+ return nil
209+ }
210+
211+ func isCRDManagedByAddonManager (ctx context.Context , client client.Client , crdName string ) (bool , error ) {
212+ var crd apiextensionsv1.CustomResourceDefinition
213+ if err := client .Get (ctx , types.NamespacedName {Name : crdName }, & crd ); err != nil {
214+ if errors .IsNotFound (err ) {
215+ return false , fmt .Errorf ("CRD %s doesn't exist: %w" , crdName , err )
216+ } else {
217+ return false , fmt .Errorf ("failed to get CRD %s: %w" , crdName , err )
218+ }
255219 }
256220
257- return nil
221+ labels := crd .GetLabels ()
222+ if labels != nil {
223+ if _ , exists := labels ["addonmanager.kubernetes.io/mode" ]; exists {
224+ klog .Infof ("CRD %s is still managed by the addon manager, skipping installation" , crd .Name )
225+ return true , nil
226+ }
227+ }
228+ return false , nil
258229}
259230
260231// isHubCRD determines if a CRD should be installed on the hub cluster.
@@ -280,3 +251,48 @@ func isMemberCRD(filename string) bool {
280251
281252 return memberCRDs [filename ]
282253}
254+
255+ func collectCRDFileNames (crdPath , mode string ) (map [string ]bool , error ) {
256+ // Set of CRD filenames to install based on mode.
257+ crdFilesToInstall := make (map [string ]bool )
258+
259+ // Walk through the CRD directory and collect filenames.
260+ if err := filepath .WalkDir (crdPath , func (path string , d fs.DirEntry , err error ) error {
261+ // Handle errors from WalkDir.
262+ if err != nil {
263+ return err
264+ }
265+
266+ // Skip directories.
267+ if d .IsDir () {
268+ return nil
269+ }
270+
271+ // Only process yaml files.
272+ if filepath .Ext (path ) != ".yaml" && filepath .Ext (path ) != ".yml" {
273+ return nil
274+ }
275+
276+ // Process based on mode.
277+ filename := filepath .Base (path )
278+ isHubCRD := isHubCRD (filename )
279+ isMemberCRD := isMemberCRD (filename )
280+
281+ switch mode {
282+ case "hub" :
283+ if isHubCRD {
284+ crdFilesToInstall [path ] = true
285+ }
286+ case "member" :
287+ if isMemberCRD {
288+ crdFilesToInstall [path ] = true
289+ }
290+ }
291+
292+ return nil
293+ }); err != nil {
294+ return nil , fmt .Errorf ("failed to walk CRD directory: %w" , err )
295+ }
296+
297+ return crdFilesToInstall , nil
298+ }
0 commit comments