Skip to content

Commit cedf6d4

Browse files
committed
OCPBUGS-74872: Sort plugin list to make them deterministic
1 parent 562a178 commit cedf6d4

2 files changed

Lines changed: 24 additions & 1 deletion

File tree

pkg/console/operator/sync_v400.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"net/url"
77
"os"
88
"slices"
9+
"sort"
910
"strings"
1011

1112
// kube
@@ -17,6 +18,7 @@ import (
1718
"k8s.io/apimachinery/pkg/labels"
1819
"k8s.io/apimachinery/pkg/runtime/schema"
1920
"k8s.io/apimachinery/pkg/util/sets"
21+
"k8s.io/client-go/util/retry"
2022
"k8s.io/klog/v2"
2123

2224
// openshift
@@ -405,7 +407,15 @@ func (co *consoleOperator) SyncConfigMap(
405407
if err != nil {
406408
return nil, "FailedConsoleConfigBuilder", err
407409
}
408-
cm, cmChanged, cmErr := resourceapply.ApplyConfigMap(ctx, co.configMapClient, recorder, defaultConfigmap)
410+
var cm *corev1.ConfigMap
411+
var cmChanged bool
412+
var cmErr error
413+
414+
// Retry on conflicts to handle concurrent ConfigMap updates
415+
cmErr = retry.RetryOnConflict(retry.DefaultBackoff, func() error {
416+
cm, cmChanged, cmErr = resourceapply.ApplyConfigMap(ctx, co.configMapClient, recorder, defaultConfigmap)
417+
return cmErr
418+
})
409419
if cmErr != nil {
410420
return nil, "FailedApply", cmErr
411421
}
@@ -731,6 +741,10 @@ func (co *consoleOperator) GetAvailablePlugins(enabledPluginsNames []string) []*
731741
}
732742
availablePlugins = append(availablePlugins, plugin)
733743
}
744+
// Sort plugins by name to ensure deterministic processing order
745+
sort.Slice(availablePlugins, func(i, j int) bool {
746+
return availablePlugins[i].Name < availablePlugins[j].Name
747+
})
734748
return availablePlugins
735749
}
736750

pkg/console/subresource/configmap/configmap.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,8 @@ func pluginsWithI18nNamespace(availablePlugins []*v1.ConsolePlugin) []string {
179179
i18nNamespaces = append(i18nNamespaces, fmt.Sprintf("plugin__%s", plugin.Name))
180180
}
181181
}
182+
// Sort to ensure deterministic YAML output
183+
sort.Strings(i18nNamespaces)
182184
return i18nNamespaces
183185
}
184186

@@ -192,6 +194,9 @@ func getPluginsEndpointMap(availablePlugins []*v1.ConsolePlugin) map[string]stri
192194
klog.Errorf("unknown backend type for %q plugin: %q. Currently only %q backend type is supported.", plugin.Name, plugin.Spec.Backend.Type, v1.Service)
193195
}
194196
}
197+
// Note: Here the YAML output is deterministic because:
198+
// - availablePlugins are sorted by name in GetAvailablePlugins()
199+
// - sigs.k8s.io/yaml uses json.Marshal which sorts map keys
195200
return pluginsEndpointMap
196201
}
197202

@@ -214,6 +219,10 @@ func getPluginsProxyServices(availablePlugins []*v1.ConsolePlugin) []consoleserv
214219
}
215220
}
216221
}
222+
// Sort by ConsoleAPIPath to ensure deterministic YAML output
223+
sort.Slice(proxyServices, func(i, j int) bool {
224+
return proxyServices[i].ConsoleAPIPath < proxyServices[j].ConsoleAPIPath
225+
})
217226
return proxyServices
218227
}
219228

0 commit comments

Comments
 (0)