@@ -6,15 +6,20 @@ import (
66 "time"
77
88 apierrors "k8s.io/apimachinery/pkg/api/errors"
9+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
910 "k8s.io/client-go/tools/cache"
1011 "k8s.io/client-go/util/workqueue"
1112 "k8s.io/klog/v2"
1213
14+ operatorv1 "github.com/openshift/api/operator/v1"
1315 operatorv1alpha1 "github.com/openshift/api/operator/v1alpha1"
1416 operatorclientset "github.com/openshift/client-go/operator/clientset/versioned"
1517 cvoclientv1alpha1 "github.com/openshift/client-go/operator/clientset/versioned/typed/operator/v1alpha1"
1618 operatorexternalversions "github.com/openshift/client-go/operator/informers/externalversions"
1719 operatorlistersv1alpha1 "github.com/openshift/client-go/operator/listers/operator/v1alpha1"
20+ "github.com/openshift/library-go/pkg/operator/loglevel"
21+
22+ i "github.com/openshift/cluster-version-operator/pkg/internal"
1823)
1924
2025const ClusterVersionOperatorConfigurationName = "cluster"
@@ -31,6 +36,9 @@ type ClusterVersionOperatorConfiguration struct {
3136 factory operatorexternalversions.SharedInformerFactory
3237
3338 started bool
39+
40+ desiredLogLevel operatorv1.LogLevel
41+ lastObservedGeneration int64
3442}
3543
3644func (config * ClusterVersionOperatorConfiguration ) Queue () workqueue.TypedRateLimitingInterface [any ] {
@@ -43,26 +51,38 @@ func (config *ClusterVersionOperatorConfiguration) clusterVersionOperatorEventHa
4351 return cache.ResourceEventHandlerFuncs {
4452 AddFunc : func (_ interface {}) {
4553 config .queue .Add (config .queueKey )
54+ klog .V (i .Debug ).Infof ("ClusterVersionOperator resource was added; queuing a sync" )
4655 },
4756 UpdateFunc : func (_ , _ interface {}) {
4857 config .queue .Add (config .queueKey )
58+ klog .V (i .Debug ).Infof ("ClusterVersionOperator resource was modified or resync period has passed; queuing a sync" )
4959 },
5060 DeleteFunc : func (_ interface {}) {
5161 config .queue .Add (config .queueKey )
62+ klog .V (i .Debug ).Infof ("ClusterVersionOperator resource was deleted; queuing a sync" )
5263 },
5364 }
5465}
5566
5667// NewClusterVersionOperatorConfiguration returns ClusterVersionOperatorConfiguration, which might be used
5768// to synchronize with the ClusterVersionOperator resource.
5869func NewClusterVersionOperatorConfiguration (client operatorclientset.Interface , factory operatorexternalversions.SharedInformerFactory ) * ClusterVersionOperatorConfiguration {
70+ var desiredLogLevel operatorv1.LogLevel
71+ if currentLogLevel , notFound := loglevel .GetLogLevel (); notFound {
72+ klog .Warningf ("The current log level could not be found; assuming the 'Normal' level is the currently desired" )
73+ desiredLogLevel = operatorv1 .Normal
74+ } else {
75+ desiredLogLevel = currentLogLevel
76+ }
77+
5978 return & ClusterVersionOperatorConfiguration {
6079 queueKey : fmt .Sprintf ("ClusterVersionOperator/%s" , ClusterVersionOperatorConfigurationName ),
6180 queue : workqueue .NewTypedRateLimitingQueueWithConfig [any ](
6281 workqueue .DefaultTypedControllerRateLimiter [any ](),
6382 workqueue.TypedRateLimitingQueueConfig [any ]{Name : "configuration" }),
64- client : client .OperatorV1alpha1 ().ClusterVersionOperators (),
65- factory : factory ,
83+ client : client .OperatorV1alpha1 ().ClusterVersionOperators (),
84+ factory : factory ,
85+ desiredLogLevel : desiredLogLevel ,
6686 }
6787}
6888
@@ -92,9 +112,9 @@ func (config *ClusterVersionOperatorConfiguration) Sync(ctx context.Context, key
92112 panic ("ClusterVersionOperatorConfiguration instance was not properly started before its synchronization." )
93113 }
94114 startTime := time .Now ()
95- klog .V (2 ).Infof ("Started syncing CVO configuration %q" , key )
115+ klog .V (i . Normal ).Infof ("Started syncing CVO configuration %q" , key )
96116 defer func () {
97- klog .V (2 ).Infof ("Finished syncing CVO configuration (%v)" , time .Since (startTime ))
117+ klog .V (i . Normal ).Infof ("Finished syncing CVO configuration (%v)" , time .Since (startTime ))
98118 }()
99119
100120 desiredConfig , err := config .lister .Get (ClusterVersionOperatorConfigurationName )
@@ -108,7 +128,51 @@ func (config *ClusterVersionOperatorConfiguration) Sync(ctx context.Context, key
108128 return config .sync (ctx , desiredConfig )
109129}
110130
111- func (config * ClusterVersionOperatorConfiguration ) sync (_ context.Context , _ * operatorv1alpha1.ClusterVersionOperator ) error {
112- klog .Infof ("ClusterVersionOperator configuration has been synced" )
131+ // sync synchronizes the local configuration based on the desired configuration
132+ // and updates the status of the Kubernetes resource if needed.
133+ //
134+ // desiredConfig is a read-only representation of the desired configuration.
135+ func (config * ClusterVersionOperatorConfiguration ) sync (ctx context.Context , desiredConfig * operatorv1alpha1.ClusterVersionOperator ) error {
136+ if desiredConfig .Status .ObservedGeneration != desiredConfig .Generation {
137+ newConfig := desiredConfig .DeepCopy ()
138+ newConfig .Status .ObservedGeneration = desiredConfig .Generation
139+ _ , err := config .client .UpdateStatus (ctx , newConfig , metav1.UpdateOptions {})
140+ if err != nil {
141+ return fmt .Errorf ("failed to update the ClusterVersionOperator resource: %w" , err )
142+ }
143+ }
144+
145+ config .lastObservedGeneration = desiredConfig .Generation
146+ config .desiredLogLevel = desiredConfig .Spec .OperatorLogLevel
147+ if config .desiredLogLevel == "" {
148+ config .desiredLogLevel = operatorv1 .Normal
149+ }
150+
151+ currentLogLevel , notFound := loglevel .GetLogLevel ()
152+ if notFound {
153+ klog .Warningf ("The current log level could not be found; an attempt to set the log level to the desired level will be made" )
154+ }
155+
156+ if ! notFound && currentLogLevel == config .desiredLogLevel {
157+ klog .V (i .Debug ).Infof ("No need to update the current CVO log level '%s'; it is already set to the desired value" , currentLogLevel )
158+ } else {
159+ if err := loglevel .SetLogLevel (config .desiredLogLevel ); err != nil {
160+ return fmt .Errorf ("failed to set the log level to %q: %w" , config .desiredLogLevel , err )
161+ }
162+
163+ // E2E testing will be checking for existence or absence of these logs
164+ switch config .desiredLogLevel {
165+ case operatorv1 .Normal :
166+ klog .V (i .Normal ).Infof ("Successfully updated the log level from '%s' to 'Normal'" , currentLogLevel )
167+ case operatorv1 .Debug :
168+ klog .V (i .Debug ).Infof ("Successfully updated the log level from '%s' to 'Debug'" , currentLogLevel )
169+ case operatorv1 .Trace :
170+ klog .V (i .Trace ).Infof ("Successfully updated the log level from '%s' to 'Trace'" , currentLogLevel )
171+ case operatorv1 .TraceAll :
172+ klog .V (i .TraceAll ).Infof ("Successfully updated the log level from '%s' to 'TraceAll'" , currentLogLevel )
173+ default :
174+ klog .Errorf ("The CVO logging level has unexpected value '%s'" , config .desiredLogLevel )
175+ }
176+ }
113177 return nil
114178}
0 commit comments