Skip to content

Commit 278bde1

Browse files
committed
OTA-1966: Init the Proposal Lifecycle Controller
1 parent e9c1c39 commit 278bde1

3 files changed

Lines changed: 99 additions & 0 deletions

File tree

pkg/cvo/availableupdates.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,8 @@ func (optr *Operator) syncAvailableUpdates(ctx context.Context, config *configv1
182182

183183
// queue optr.sync() to update ClusterVersion status
184184
optr.queue.Add(queueKey)
185+
// queue optr.proposalController.Sync() to manage proposals
186+
optr.proposalController.Queue().Add(optr.proposalController.QueueKey())
185187
return nil
186188
}
187189

pkg/cvo/cvo.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ import (
5353
"github.com/openshift/cluster-version-operator/pkg/payload"
5454
"github.com/openshift/cluster-version-operator/pkg/payload/precondition"
5555
preconditioncv "github.com/openshift/cluster-version-operator/pkg/payload/precondition/clusterversion"
56+
"github.com/openshift/cluster-version-operator/pkg/proposal"
5657
"github.com/openshift/cluster-version-operator/pkg/risk"
5758
"github.com/openshift/cluster-version-operator/pkg/risk/alert"
5859
)
@@ -213,6 +214,9 @@ type Operator struct {
213214
// risks holds update-risk source (in-cluster alerts, etc.)
214215
// that will be aggregated into conditional update risks.
215216
risks risk.Source
217+
218+
// proposalController, if enabled, watch available updates and manage proposals
219+
proposalController *proposal.Controller
216220
}
217221

218222
// New returns a new cluster version operator.
@@ -317,6 +321,13 @@ func New(
317321

318322
optr.configuration = configuration.NewClusterVersionOperatorConfiguration(operatorClient, operatorInformerFactory)
319323

324+
optr.proposalController = proposal.NewController(func() ([]configv1.Release, error) {
325+
if optr.availableUpdates == nil {
326+
return nil, nil
327+
}
328+
return optr.availableUpdates.Updates, nil
329+
})
330+
320331
return optr, nil
321332
}
322333

@@ -470,6 +481,7 @@ func (optr *Operator) Run(runContext context.Context, shutdownContext context.Co
470481
defer optr.availableUpdatesQueue.ShutDown()
471482
defer optr.upgradeableQueue.ShutDown()
472483
defer optr.configuration.Queue().ShutDown()
484+
defer optr.proposalController.Queue().ShutDown()
473485
stopCh := runContext.Done()
474486

475487
klog.Infof("Starting ClusterVersionOperator with minimum reconcile period %s", optr.minimumUpdateCheckInterval)
@@ -525,6 +537,19 @@ func (optr *Operator) Run(runContext context.Context, shutdownContext context.Co
525537
klog.Infof("The ClusterVersionOperatorConfiguration feature gate is disabled or HyperShift is detected; the configuration sync routine will not run.")
526538
}
527539

540+
if optr.shouldEnableProposalController() {
541+
resultChannelCount++
542+
go func() {
543+
defer utilruntime.HandleCrash()
544+
wait.UntilWithContext(runContext, func(runContext context.Context) {
545+
optr.worker(runContext, optr.proposalController.Queue(), optr.proposalController.Sync)
546+
}, time.Second)
547+
resultChannel <- asyncResult{name: "proposal controller"}
548+
}()
549+
} else {
550+
klog.Infof("The proposal controller is disabled.")
551+
}
552+
528553
resultChannelCount++
529554
go func() {
530555
defer utilruntime.HandleCrash()
@@ -595,6 +620,7 @@ func (optr *Operator) Run(runContext context.Context, shutdownContext context.Co
595620
optr.availableUpdatesQueue.ShutDown()
596621
optr.upgradeableQueue.ShutDown()
597622
optr.configuration.Queue().ShutDown()
623+
optr.proposalController.Queue().ShutDown()
598624
}
599625
}
600626

@@ -1191,3 +1217,9 @@ func (optr *Operator) shouldReconcileAcceptRisks() bool {
11911217
// HyperShift will be supported later if needed
11921218
return optr.enabledCVOFeatureGates.AcceptRisks() && !optr.hypershift
11931219
}
1220+
1221+
// shouldEnableProposalController returns whether the CVO should enable the proposal controller
1222+
func (optr *Operator) shouldEnableProposalController() bool {
1223+
// TODO: guarded by some feature gate?
1224+
return true
1225+
}

pkg/proposal/controller.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package proposal
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"time"
7+
8+
"k8s.io/client-go/util/workqueue"
9+
"k8s.io/klog/v2"
10+
11+
configv1 "github.com/openshift/api/config/v1"
12+
13+
i "github.com/openshift/cluster-version-operator/pkg/internal"
14+
)
15+
16+
type Controller struct {
17+
queueKey string
18+
// queue tracks checking for the CVO configuration.
19+
//
20+
// The type any is used to comply with the worker method of the cvo.Operator struct.
21+
queue workqueue.TypedRateLimitingInterface[any]
22+
23+
availableUpdatesGetterFunc AvailableUpdatesGetterFunc
24+
}
25+
26+
const controllerName = "proposal-lifecycle-controller"
27+
28+
type AvailableUpdatesGetterFunc func() ([]configv1.Release, error)
29+
30+
// NewController returns Controller to manage Proposals.
31+
func NewController(availableUpdatesGetterFunc AvailableUpdatesGetterFunc) *Controller {
32+
return &Controller{
33+
queueKey: fmt.Sprintf("ClusterVersionOperator/%s", controllerName),
34+
queue: workqueue.NewTypedRateLimitingQueueWithConfig[any](
35+
workqueue.DefaultTypedControllerRateLimiter[any](),
36+
workqueue.TypedRateLimitingQueueConfig[any]{Name: controllerName}),
37+
availableUpdatesGetterFunc: availableUpdatesGetterFunc,
38+
}
39+
}
40+
41+
func (c *Controller) Queue() workqueue.TypedRateLimitingInterface[any] {
42+
return c.queue
43+
}
44+
45+
func (c *Controller) QueueKey() string {
46+
return c.queueKey
47+
}
48+
49+
// Sync ensures:
50+
// TODO:
51+
func (c *Controller) Sync(_ context.Context, key string) error {
52+
startTime := time.Now()
53+
klog.V(i.Normal).Infof("Started syncing CVO configuration %q", key)
54+
defer func() {
55+
klog.V(i.Normal).Infof("Finished syncing CVO configuration (%v)", time.Since(startTime))
56+
}()
57+
58+
updates, err := c.availableUpdatesGetterFunc()
59+
if err != nil {
60+
klog.Errorf("Error getting available updates: %v", err)
61+
return err
62+
}
63+
klog.Infof("Got available updates: %#v", updates)
64+
return nil
65+
}

0 commit comments

Comments
 (0)