@@ -18,6 +18,7 @@ package v1beta1
1818
1919import (
2020 "context"
21+ "reflect"
2122 "regexp"
2223
2324 condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition"
@@ -198,6 +199,9 @@ type OpenStackVersionStatus struct {
198199 // ServiceDefaults - struct that contains current defaults for OSP services
199200 ServiceDefaults ServiceDefaults `json:"serviceDefaults,omitempty"`
200201
202+ // TrackedCustomImages tracks CustomContainerImages used for each version to detect changes
203+ TrackedCustomImages map [string ]CustomContainerImages `json:"trackedCustomImages,omitempty"`
204+
201205 //ObservedGeneration - the most recent generation observed for this object.
202206 ObservedGeneration int64 `json:"observedGeneration,omitempty"`
203207}
@@ -288,3 +292,91 @@ func GetOpenStackVersions(namespace string, k8sClient client.Client) (*OpenStack
288292
289293 return versionList , nil
290294}
295+
296+ // isContainerTemplateEmpty checks if all fields in a ContainerTemplate are nil
297+ func isContainerTemplateEmpty (ct ContainerTemplate ) bool {
298+ v := reflect .ValueOf (ct )
299+ numFields := v .NumField ()
300+ for i := 0 ; i < numFields ; i ++ {
301+ field := v .Field (i )
302+ // Check if field is a pointer and not nil
303+ if field .Kind () == reflect .Ptr && ! field .IsNil () {
304+ return false
305+ }
306+ }
307+ return true
308+ }
309+
310+ // customContainerImagesModified compares two CustomContainerImages and returns true if they are different
311+ func customContainerImagesAllModified (a , b CustomContainerImages ) bool {
312+ if ! containerTemplateEqual (a .ContainerTemplate , b .ContainerTemplate ) {
313+ return true
314+ }
315+
316+ if ! stringMapEqual (a .CinderVolumeImages , b .CinderVolumeImages ) {
317+ return true
318+ }
319+
320+ if ! stringMapEqual (a .ManilaShareImages , b .ManilaShareImages ) {
321+ return true
322+ }
323+
324+ // If all fields are equal, return false (not modified)
325+ return false
326+ }
327+
328+ // containerTemplateEqual compares two ContainerTemplate structs for equality using reflection
329+ func containerTemplateEqual (a , b ContainerTemplate ) bool {
330+ va := reflect .ValueOf (a )
331+ vb := reflect .ValueOf (b )
332+
333+ numFields := va .NumField ()
334+ for i := 0 ; i < numFields ; i ++ {
335+ fieldA := va .Field (i )
336+ fieldB := vb .Field (i )
337+
338+ // Both fields should be *string type
339+ if fieldA .Kind () != reflect .Ptr || fieldB .Kind () != reflect .Ptr {
340+ continue
341+ }
342+
343+ if fieldA .IsNil () && fieldB .IsNil () {
344+ continue
345+ }
346+ if fieldA .IsNil () || fieldB .IsNil () {
347+ return false
348+ }
349+ if fieldA .Elem ().String () != fieldB .Elem ().String () {
350+ return false
351+ }
352+ }
353+
354+ return true
355+ }
356+
357+ // stringPtrEqual compares two string pointers for equality
358+ func stringPtrEqual (a , b * string ) bool {
359+ if a == nil && b == nil {
360+ return true
361+ }
362+ if a == nil || b == nil {
363+ return false
364+ }
365+ return * a == * b
366+ }
367+
368+ // stringMapEqual compares two string maps for equality
369+ func stringMapEqual (a , b map [string ]* string ) bool {
370+ if len (a ) != len (b ) {
371+ return false
372+ }
373+
374+ for key , valueA := range a {
375+ valueB , exists := b [key ]
376+ if ! exists || ! stringPtrEqual (valueA , valueB ) {
377+ return false
378+ }
379+ }
380+
381+ return true
382+ }
0 commit comments