@@ -2,6 +2,7 @@ package operator
2
2
3
3
import (
4
4
"fmt"
5
+ "slices"
5
6
6
7
// kube
7
8
"k8s.io/klog/v2"
@@ -25,62 +26,91 @@ func (co *consoleOperator) SyncCustomLogos(operatorConfig *operatorv1.Console) (
25
26
aggregatedError error
26
27
err error
27
28
reason string
29
+ newSyncedLogos []string
28
30
)
29
31
for _ , logo := range operatorConfig .Spec .Customization .Logos {
30
32
for _ , theme := range logo .Themes {
31
33
logoToSync := theme .Source .ConfigMap
32
- err , reason = co .updateCustomLogoSyncSource (logoToSync )
33
- if err != nil {
34
+ if err , reason = co .validateCustomLogo (logoToSync ); err != nil {
34
35
if aggregatedError == nil {
35
- aggregatedError = fmt .Errorf ("One or more errors were encountered while syncing custom logos:\n - %v, %s" , logoToSync , err .Error ())
36
+ aggregatedError = fmt .Errorf ("error syncing custom logos: - Invalid config: %v, %s" , logoToSync , err .Error ())
36
37
} else {
37
- aggregatedError = fmt .Errorf ("%s\n - %v, %s" , aggregatedError .Error (), logoToSync , err .Error ())
38
+ aggregatedError = fmt .Errorf ("%s - %v, %s" , aggregatedError .Error (), logoToSync , err .Error ())
38
39
}
40
+ } else {
41
+ newSyncedLogos = append (newSyncedLogos , logoToSync .Name )
39
42
}
40
43
}
41
44
}
42
45
if aggregatedError != nil {
43
46
return aggregatedError , reason
44
47
}
45
- return nil , ""
48
+ slices .Sort (newSyncedLogos )
49
+ return co .updateCustomLogoSyncSources (newSyncedLogos )
46
50
}
47
51
48
52
// TODO remove deprecated CustomLogoFile API
49
53
func (co * consoleOperator ) SyncCustomLogoConfigMap (operatorConfig * operatorv1.Console ) (error , string ) {
50
54
var customLogoRef = operatorv1 .ConfigMapFileReference (operatorConfig .Spec .Customization .CustomLogoFile )
51
- return co .updateCustomLogoSyncSource (& customLogoRef )
55
+ klog .V (4 ).Infof ("syncing customLogoFile, Name: %s, Key: %s" , customLogoRef .Name , customLogoRef .Key )
56
+ err , reason := co .validateCustomLogo (& customLogoRef )
57
+ if err != nil {
58
+ klog .V (4 ).Infof ("failed to sync customLogoFile, %v" , err )
59
+ return err , reason
60
+ }
61
+ return co .updateCustomLogoSyncSources ([]string {customLogoRef .Name })
52
62
}
53
63
54
64
// on each pass of the operator sync loop, we need to check the
55
- // operator config for a custom logo . If this has been set, then
56
- // we notify the resourceSyncer that it needs to start watching this
57
- // configmap in its own sync loop. Note that the resourceSyncer's actual
65
+ // operator config for custom logos . If this has been set, then
66
+ // we notify the resourceSyncer that it needs to start watching the associated
67
+ // configmaps in its own sync loop. Note that the resourceSyncer's actual
58
68
// sync loop will run later. Our operator is waiting to receive
59
- // the copied configmap into the console namespace for a future
69
+ // the copied configmaps into the console namespace for a future
60
70
// sync loop to mount into the console deployment.
61
- func (c * consoleOperator ) updateCustomLogoSyncSource (cmRef * operatorv1.ConfigMapFileReference ) (error , string ) {
62
- // validate first, to avoid a broken volume mount & a crashlooping console
63
- err , reason := c .validateCustomLogo (cmRef )
64
- if err != nil {
65
- return err , reason
71
+ func (co * consoleOperator ) updateCustomLogoSyncSources (configMapNames []string ) (error , string ) {
72
+ klog .V (4 ).Info ("syncing custom logo configmap resources" )
73
+ klog .V (4 ).Infof ("%#v" , configMapNames )
74
+
75
+ errors := []string {}
76
+ if len (co .trackables .customLogoConfigMaps ) > 0 {
77
+ klog .V (4 ).Info ("unsyncing custom logo configmap resources from previous sync loop..." )
78
+ for _ , configMapName := range co .trackables .customLogoConfigMaps {
79
+ err := co .updateCustomLogoSyncSource (configMapName , true )
80
+ if err != nil {
81
+ errors = append (errors , err .Error ())
82
+ }
83
+ }
84
+
85
+ if len (errors ) > 0 {
86
+ msg := fmt .Sprintf ("error syncing custom logo configmap resources\n %v" , errors )
87
+ klog .V (4 ).Info (msg )
88
+ return fmt .Errorf (msg ), "FailedResourceSync"
89
+ }
66
90
}
67
91
68
- source := resourcesynccontroller.ResourceLocation {}
69
- logoConfigMapName := cmRef .Name
92
+ if len (configMapNames ) > 0 {
93
+ // If the new list of synced configmaps is different than the last sync, we need to update the
94
+ // resource syncer with the new list, and re
95
+ klog .V (4 ).Infof ("syncing new custom logo configmap resources..." )
96
+ for _ , configMapName := range configMapNames {
97
+ err := co .updateCustomLogoSyncSource (configMapName , false )
98
+ if err != nil {
99
+ errors = append (errors , err .Error ())
100
+ }
101
+ }
70
102
71
- if logoConfigMapName != "" {
72
- source .Name = logoConfigMapName
73
- source .Namespace = api .OpenShiftConfigNamespace
74
- }
75
- // if no custom logo provided, sync an empty source to delete
76
- err = c .resourceSyncer .SyncConfigMap (
77
- resourcesynccontroller.ResourceLocation {Namespace : api .OpenShiftConsoleNamespace , Name : cmRef .Name },
78
- source ,
79
- )
80
- if err != nil {
81
- return err , "FailedResourceSync"
103
+ if len (errors ) > 0 {
104
+ msg := fmt .Sprintf ("error syncing custom logo configmap resources:\n %v" , errors )
105
+ klog .V (4 ).Infof (msg )
106
+ return fmt .Errorf (msg ), "FailedResourceSync"
107
+ }
82
108
}
83
109
110
+ klog .V (4 ).Info ("saving synced custom logo configmap resources for next loop" )
111
+ co .trackables .customLogoConfigMaps = configMapNames
112
+
113
+ klog .V (4 ).Info ("done" )
84
114
return nil , ""
85
115
}
86
116
@@ -89,13 +119,13 @@ func (co *consoleOperator) validateCustomLogo(logoFileRef *operatorv1.ConfigMapF
89
119
logoImageKey := logoFileRef .Key
90
120
91
121
if (len (logoConfigMapName ) == 0 ) != (len (logoImageKey ) == 0 ) {
92
- klog .V (4 ).Infoln ("custom logo filename or key have not been set" )
122
+ klog .V (4 ).Info ("custom logo filename or key have not been set" )
93
123
return customerrors .NewCustomLogoError ("either custom logo filename or key have not been set" ), "KeyOrFilenameInvalid"
94
124
}
95
125
96
126
// fine if nothing set, but don't mount it
97
127
if len (logoConfigMapName ) == 0 {
98
- klog .V (4 ).Infoln ("no custom logo configured" )
128
+ klog .V (4 ).Info ("no custom logo configured" )
99
129
return nil , ""
100
130
}
101
131
@@ -111,10 +141,30 @@ func (co *consoleOperator) validateCustomLogo(logoFileRef *operatorv1.ConfigMapF
111
141
_ , imageDataFound = logoConfigMap .Data [logoImageKey ]
112
142
}
113
143
if ! imageDataFound {
114
- klog .V (4 ).Infoln ("custom logo file exists but no image provided" )
144
+ klog .V (4 ).Info ("custom logo file exists but no image provided" )
115
145
return customerrors .NewCustomLogoError ("custom logo file exists but no image provided" ), "NoImageProvided"
116
146
}
117
147
118
148
klog .V (4 ).Infof ("custom logo %s ok to mount" , logoConfigMapName )
119
149
return nil , ""
120
150
}
151
+
152
+ func (co * consoleOperator ) updateCustomLogoSyncSource (targetName string , unsync bool ) error {
153
+ source := resourcesynccontroller.ResourceLocation {}
154
+ if ! unsync {
155
+ source .Name = targetName
156
+ source .Namespace = api .OpenShiftConfigNamespace
157
+ }
158
+
159
+ target := resourcesynccontroller.ResourceLocation {
160
+ Namespace : api .OpenShiftConsoleNamespace ,
161
+ Name : targetName ,
162
+ }
163
+
164
+ if unsync {
165
+ klog .V (4 ).Infof ("unsyncing %s" , targetName )
166
+ } else {
167
+ klog .V (4 ).Infof ("syncing %s" , targetName )
168
+ }
169
+ return co .resourceSyncer .SyncConfigMap (target , source )
170
+ }
0 commit comments