@@ -198,6 +198,9 @@ type OpenStackVersionStatus struct {
198198 // ServiceDefaults - struct that contains current defaults for OSP services
199199 ServiceDefaults ServiceDefaults `json:"serviceDefaults,omitempty"`
200200
201+ // TrackedCustomImages tracks CustomContainerImages used for each version to detect changes
202+ TrackedCustomImages map [string ]CustomContainerImages `json:"trackedCustomImages,omitempty"`
203+
201204 //ObservedGeneration - the most recent generation observed for this object.
202205 ObservedGeneration int64 `json:"observedGeneration,omitempty"`
203206}
@@ -288,3 +291,146 @@ func GetOpenStackVersions(namespace string, k8sClient client.Client) (*OpenStack
288291
289292 return versionList , nil
290293}
294+
295+ // customContainerImagesEqual compares two CustomContainerImages for equality
296+ func customContainerImagesEqual (a , b CustomContainerImages ) bool {
297+ // Compare all ContainerTemplate fields
298+ if ! containerTemplateEqual (a .ContainerTemplate , b .ContainerTemplate ) {
299+ return false
300+ }
301+
302+ // Compare CinderVolumeImages maps
303+ if ! stringMapEqual (a .CinderVolumeImages , b .CinderVolumeImages ) {
304+ return false
305+ }
306+
307+ // Compare ManilaShareImages maps
308+ if ! stringMapEqual (a .ManilaShareImages , b .ManilaShareImages ) {
309+ return false
310+ }
311+
312+ return true
313+ }
314+
315+ // containerTemplateEqual compares two ContainerTemplate structs for equality
316+ func containerTemplateEqual (a , b ContainerTemplate ) bool {
317+ return stringPtrEqual (a .AgentImage , b .AgentImage ) &&
318+ stringPtrEqual (a .AnsibleeeImage , b .AnsibleeeImage ) &&
319+ stringPtrEqual (a .AodhAPIImage , b .AodhAPIImage ) &&
320+ stringPtrEqual (a .AodhEvaluatorImage , b .AodhEvaluatorImage ) &&
321+ stringPtrEqual (a .AodhListenerImage , b .AodhListenerImage ) &&
322+ stringPtrEqual (a .AodhNotifierImage , b .AodhNotifierImage ) &&
323+ stringPtrEqual (a .ApacheImage , b .ApacheImage ) &&
324+ stringPtrEqual (a .BarbicanAPIImage , b .BarbicanAPIImage ) &&
325+ stringPtrEqual (a .BarbicanKeystoneListenerImage , b .BarbicanKeystoneListenerImage ) &&
326+ stringPtrEqual (a .BarbicanWorkerImage , b .BarbicanWorkerImage ) &&
327+ stringPtrEqual (a .CeilometerCentralImage , b .CeilometerCentralImage ) &&
328+ stringPtrEqual (a .CeilometerComputeImage , b .CeilometerComputeImage ) &&
329+ stringPtrEqual (a .CeilometerIpmiImage , b .CeilometerIpmiImage ) &&
330+ stringPtrEqual (a .CeilometerNotificationImage , b .CeilometerNotificationImage ) &&
331+ stringPtrEqual (a .CeilometerSgcoreImage , b .CeilometerSgcoreImage ) &&
332+ stringPtrEqual (a .CeilometerMysqldExporterImage , b .CeilometerMysqldExporterImage ) &&
333+ stringPtrEqual (a .CinderAPIImage , b .CinderAPIImage ) &&
334+ stringPtrEqual (a .CinderBackupImage , b .CinderBackupImage ) &&
335+ stringPtrEqual (a .CinderSchedulerImage , b .CinderSchedulerImage ) &&
336+ stringPtrEqual (a .DesignateAPIImage , b .DesignateAPIImage ) &&
337+ stringPtrEqual (a .DesignateBackendbind9Image , b .DesignateBackendbind9Image ) &&
338+ stringPtrEqual (a .DesignateCentralImage , b .DesignateCentralImage ) &&
339+ stringPtrEqual (a .DesignateMdnsImage , b .DesignateMdnsImage ) &&
340+ stringPtrEqual (a .DesignateProducerImage , b .DesignateProducerImage ) &&
341+ stringPtrEqual (a .DesignateUnboundImage , b .DesignateUnboundImage ) &&
342+ stringPtrEqual (a .DesignateWorkerImage , b .DesignateWorkerImage ) &&
343+ stringPtrEqual (a .EdpmFrrImage , b .EdpmFrrImage ) &&
344+ stringPtrEqual (a .EdpmIscsidImage , b .EdpmIscsidImage ) &&
345+ stringPtrEqual (a .EdpmLogrotateCrondImage , b .EdpmLogrotateCrondImage ) &&
346+ stringPtrEqual (a .EdpmMultipathdImage , b .EdpmMultipathdImage ) &&
347+ stringPtrEqual (a .EdpmNeutronDhcpAgentImage , b .EdpmNeutronDhcpAgentImage ) &&
348+ stringPtrEqual (a .EdpmNeutronMetadataAgentImage , b .EdpmNeutronMetadataAgentImage ) &&
349+ stringPtrEqual (a .EdpmNeutronOvnAgentImage , b .EdpmNeutronOvnAgentImage ) &&
350+ stringPtrEqual (a .EdpmNeutronSriovAgentImage , b .EdpmNeutronSriovAgentImage ) &&
351+ stringPtrEqual (a .EdpmOvnBgpAgentImage , b .EdpmOvnBgpAgentImage ) &&
352+ stringPtrEqual (a .EdpmNodeExporterImage , b .EdpmNodeExporterImage ) &&
353+ stringPtrEqual (a .EdpmKeplerImage , b .EdpmKeplerImage ) &&
354+ stringPtrEqual (a .EdpmPodmanExporterImage , b .EdpmPodmanExporterImage ) &&
355+ stringPtrEqual (a .EdpmOpenstackNetworkExporterImage , b .EdpmOpenstackNetworkExporterImage ) &&
356+ stringPtrEqual (a .OpenstackNetworkExporterImage , b .OpenstackNetworkExporterImage ) &&
357+ stringPtrEqual (a .GlanceAPIImage , b .GlanceAPIImage ) &&
358+ stringPtrEqual (a .HeatAPIImage , b .HeatAPIImage ) &&
359+ stringPtrEqual (a .HeatCfnapiImage , b .HeatCfnapiImage ) &&
360+ stringPtrEqual (a .HeatEngineImage , b .HeatEngineImage ) &&
361+ stringPtrEqual (a .HorizonImage , b .HorizonImage ) &&
362+ stringPtrEqual (a .InfraDnsmasqImage , b .InfraDnsmasqImage ) &&
363+ stringPtrEqual (a .InfraMemcachedImage , b .InfraMemcachedImage ) &&
364+ stringPtrEqual (a .InfraRedisImage , b .InfraRedisImage ) &&
365+ stringPtrEqual (a .IronicAPIImage , b .IronicAPIImage ) &&
366+ stringPtrEqual (a .IronicConductorImage , b .IronicConductorImage ) &&
367+ stringPtrEqual (a .IronicInspectorImage , b .IronicInspectorImage ) &&
368+ stringPtrEqual (a .IronicNeutronAgentImage , b .IronicNeutronAgentImage ) &&
369+ stringPtrEqual (a .IronicPxeImage , b .IronicPxeImage ) &&
370+ stringPtrEqual (a .IronicPythonAgentImage , b .IronicPythonAgentImage ) &&
371+ stringPtrEqual (a .KeystoneAPIImage , b .KeystoneAPIImage ) &&
372+ stringPtrEqual (a .KsmImage , b .KsmImage ) &&
373+ stringPtrEqual (a .ManilaAPIImage , b .ManilaAPIImage ) &&
374+ stringPtrEqual (a .ManilaSchedulerImage , b .ManilaSchedulerImage ) &&
375+ stringPtrEqual (a .MariadbImage , b .MariadbImage ) &&
376+ stringPtrEqual (a .NetUtilsImage , b .NetUtilsImage ) &&
377+ stringPtrEqual (a .NeutronAPIImage , b .NeutronAPIImage ) &&
378+ stringPtrEqual (a .NovaAPIImage , b .NovaAPIImage ) &&
379+ stringPtrEqual (a .NovaComputeImage , b .NovaComputeImage ) &&
380+ stringPtrEqual (a .NovaConductorImage , b .NovaConductorImage ) &&
381+ stringPtrEqual (a .NovaNovncImage , b .NovaNovncImage ) &&
382+ stringPtrEqual (a .NovaSchedulerImage , b .NovaSchedulerImage ) &&
383+ stringPtrEqual (a .OctaviaAPIImage , b .OctaviaAPIImage ) &&
384+ stringPtrEqual (a .OctaviaHealthmanagerImage , b .OctaviaHealthmanagerImage ) &&
385+ stringPtrEqual (a .OctaviaHousekeepingImage , b .OctaviaHousekeepingImage ) &&
386+ stringPtrEqual (a .OctaviaWorkerImage , b .OctaviaWorkerImage ) &&
387+ stringPtrEqual (a .OctaviaRsyslogImage , b .OctaviaRsyslogImage ) &&
388+ stringPtrEqual (a .OpenstackClientImage , b .OpenstackClientImage ) &&
389+ stringPtrEqual (a .OsContainerImage , b .OsContainerImage ) &&
390+ stringPtrEqual (a .OvnControllerImage , b .OvnControllerImage ) &&
391+ stringPtrEqual (a .OvnControllerOvsImage , b .OvnControllerOvsImage ) &&
392+ stringPtrEqual (a .OvnNbDbclusterImage , b .OvnNbDbclusterImage ) &&
393+ stringPtrEqual (a .OvnNorthdImage , b .OvnNorthdImage ) &&
394+ stringPtrEqual (a .OvnSbDbclusterImage , b .OvnSbDbclusterImage ) &&
395+ stringPtrEqual (a .PlacementAPIImage , b .PlacementAPIImage ) &&
396+ stringPtrEqual (a .RabbitmqImage , b .RabbitmqImage ) &&
397+ stringPtrEqual (a .SwiftAccountImage , b .SwiftAccountImage ) &&
398+ stringPtrEqual (a .SwiftContainerImage , b .SwiftContainerImage ) &&
399+ stringPtrEqual (a .SwiftObjectImage , b .SwiftObjectImage ) &&
400+ stringPtrEqual (a .SwiftProxyImage , b .SwiftProxyImage ) &&
401+ stringPtrEqual (a .TelemetryNodeExporterImage , b .TelemetryNodeExporterImage ) &&
402+ stringPtrEqual (a .TestTempestImage , b .TestTempestImage ) &&
403+ stringPtrEqual (a .TestTobikoImage , b .TestTobikoImage ) &&
404+ stringPtrEqual (a .TestHorizontestImage , b .TestHorizontestImage ) &&
405+ stringPtrEqual (a .TestAnsibletestImage , b .TestAnsibletestImage ) &&
406+ stringPtrEqual (a .WatcherAPIImage , b .WatcherAPIImage ) &&
407+ stringPtrEqual (a .WatcherApplierImage , b .WatcherApplierImage ) &&
408+ stringPtrEqual (a .WatcherDecisionEngineImage , b .WatcherDecisionEngineImage )
409+ }
410+
411+ // stringPtrEqual compares two string pointers for equality
412+ func stringPtrEqual (a , b * string ) bool {
413+ if a == nil && b == nil {
414+ return true
415+ }
416+ if a == nil || b == nil {
417+ return false
418+ }
419+ return * a == * b
420+ }
421+
422+ // stringMapEqual compares two string maps for equality
423+ func stringMapEqual (a , b map [string ]* string ) bool {
424+ if len (a ) != len (b ) {
425+ return false
426+ }
427+
428+ for key , valueA := range a {
429+ valueB , exists := b [key ]
430+ if ! exists || ! stringPtrEqual (valueA , valueB ) {
431+ return false
432+ }
433+ }
434+
435+ return true
436+ }
0 commit comments