Skip to content

Commit f2574c3

Browse files
committed
poc(ocpbugs-30080): read OCP version from payload metadada
1 parent 5cb146d commit f2574c3

File tree

5 files changed

+150
-158
lines changed

5 files changed

+150
-158
lines changed

pkg/cvo/cvo.go

+15-15
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ type Operator struct {
175175
exclude string
176176

177177
enabledFeatureGates featuregates.CvoGateChecker
178+
requiredFeatureSet configv1.FeatureSet
178179

179180
clusterProfile string
180181
uid types.UID
@@ -210,6 +211,8 @@ func New(
210211
injectClusterIdIntoPromQL bool,
211212
updateService string,
212213
alwaysEnableCapabilities []configv1.ClusterVersionCapability,
214+
startingFeatureSet configv1.FeatureSet,
215+
cvoGates featuregates.CvoGateChecker,
213216
) (*Operator, error) {
214217
eventBroadcaster := record.NewBroadcaster()
215218
eventBroadcaster.StartLogging(klog.Infof)
@@ -246,7 +249,9 @@ func New(
246249
// Because of OCPBUGS-30080, we can only detect the enabled feature gates after Operator loads the initial payload
247250
// from disk via LoadInitialPayload. We must not have any gate-checking code until that happens, so we initialize
248251
// this field with a checker that panics when used.
249-
enabledFeatureGates: featuregates.PanicOnUsageBeforeInitialization,
252+
enabledFeatureGates: cvoGates,
253+
requiredFeatureSet: startingFeatureSet,
254+
250255
alwaysEnableCapabilities: alwaysEnableCapabilities,
251256
}
252257

@@ -283,7 +288,7 @@ func New(
283288

284289
// LoadInitialPayload waits until a ClusterVersion object exists. It then retrieves the payload contents, verifies the
285290
// initial state and returns it. If the payload is invalid, an error is returned.
286-
func (optr *Operator) LoadInitialPayload(ctx context.Context, startingRequiredFeatureSet configv1.FeatureSet, restConfig *rest.Config) (*payload.Update, error) {
291+
func (optr *Operator) LoadInitialPayload(ctx context.Context, restConfig, burstRestConfig *rest.Config) error {
287292

288293
// wait until cluster version object exists
289294
if err := wait.PollUntilContextCancel(ctx, 3*time.Second, true, func(ctx context.Context) (bool, error) {
@@ -300,19 +305,19 @@ func (optr *Operator) LoadInitialPayload(ctx context.Context, startingRequiredFe
300305
}
301306
return true, nil
302307
}); err != nil {
303-
return nil, fmt.Errorf("Error when attempting to get cluster version object: %w", err)
308+
return fmt.Errorf("Error when attempting to get cluster version object: %w", err)
304309
}
305310

306-
update, err := payload.LoadUpdate(optr.defaultPayloadDir(), optr.release.Image, optr.exclude, string(startingRequiredFeatureSet),
311+
update, err := payload.LoadUpdate(optr.defaultPayloadDir(), optr.release.Image, optr.exclude, string(optr.requiredFeatureSet),
307312
optr.clusterProfile, configv1.KnownClusterVersionCapabilities)
308313

309314
if err != nil {
310-
return nil, fmt.Errorf("the local release contents are invalid - no current version can be determined from disk: %v", err)
315+
return fmt.Errorf("the local release contents are invalid - no current version can be determined from disk: %v", err)
311316
}
312317
httpClientConstructor := sigstore.NewCachedHTTPClientConstructor(optr.HTTPClient, nil)
313318
configClient, err := coreclientsetv1.NewForConfig(restConfig)
314319
if err != nil {
315-
return nil, fmt.Errorf("unable to create a configuration client: %v", err)
320+
return fmt.Errorf("unable to create a configuration client: %v", err)
316321
}
317322

318323
customSignatureStore := &customsignaturestore.Store{
@@ -324,7 +329,7 @@ func (optr *Operator) LoadInitialPayload(ctx context.Context, startingRequiredFe
324329
// attempt to load a verifier as defined in the payload
325330
verifier, signatureStore, err := loadConfigMapVerifierDataFromUpdate(update, httpClientConstructor.HTTPClient, configClient, customSignatureStore)
326331
if err != nil {
327-
return nil, err
332+
return err
328333
}
329334
if verifier != nil {
330335
klog.Infof("Verifying release authenticity: %v", verifier)
@@ -334,13 +339,6 @@ func (optr *Operator) LoadInitialPayload(ctx context.Context, startingRequiredFe
334339
}
335340
optr.verifier = verifier
336341
optr.signatureStore = signatureStore
337-
return update, nil
338-
}
339-
340-
// InitializeFromPayload configures the controller that loads and applies content to the cluster given an initial payload
341-
// and feature gate data.
342-
func (optr *Operator) InitializeFromPayload(update *payload.Update, requiredFeatureSet configv1.FeatureSet, cvoFlags featuregates.CvoGateChecker, restConfig *rest.Config, burstRestConfig *rest.Config) {
343-
optr.enabledFeatureGates = cvoFlags
344342
optr.release = update.Release
345343
optr.releaseCreated = update.ImageRef.CreationTimestamp.Time
346344

@@ -358,11 +356,13 @@ func (optr *Operator) InitializeFromPayload(update *payload.Update, requiredFeat
358356
Cap: time.Second * 15,
359357
},
360358
optr.exclude,
361-
requiredFeatureSet,
359+
optr.requiredFeatureSet,
362360
optr.eventRecorder,
363361
optr.clusterProfile,
364362
optr.alwaysEnableCapabilities,
365363
)
364+
365+
return nil
366366
}
367367

368368
// ownerReferenceModifier sets the owner reference to the current CV resource if no other reference exists. It also resets

pkg/featuregates/featuregates.go

-30
Original file line numberDiff line numberDiff line change
@@ -35,36 +35,6 @@ type CvoGateChecker interface {
3535
CVOConfiguration() bool
3636
}
3737

38-
type panicOnUsageBeforeInitializationFunc func()
39-
40-
func panicOnUsageBeforeInitialization() {
41-
panic("CVO feature flags were used before they were initialized")
42-
}
43-
44-
// PanicOnUsageBeforeInitialization is a CvoGateChecker that panics if any of its methods are called. This checker should
45-
// be used before CVO feature gates are actually known and some code tries to check them.
46-
var PanicOnUsageBeforeInitialization = panicOnUsageBeforeInitializationFunc(panicOnUsageBeforeInitialization)
47-
48-
func (p panicOnUsageBeforeInitializationFunc) ReconciliationIssuesCondition() bool {
49-
p()
50-
return false
51-
}
52-
53-
func (p panicOnUsageBeforeInitializationFunc) StatusReleaseArchitecture() bool {
54-
p()
55-
return false
56-
}
57-
58-
func (p panicOnUsageBeforeInitializationFunc) UnknownVersion() bool {
59-
p()
60-
return false
61-
}
62-
63-
func (p panicOnUsageBeforeInitializationFunc) CVOConfiguration() bool {
64-
p()
65-
return false
66-
}
67-
6838
// CvoGates contains flags that control CVO functionality gated by product feature gates. The
6939
// names do not correspond to product feature gates, the booleans here are "smaller" (product-level
7040
// gate will enable multiple CVO behaviors).

pkg/payload/payload.go

+20-19
Original file line numberDiff line numberDiff line change
@@ -141,11 +141,23 @@ type metadata struct {
141141
func LoadUpdate(dir, releaseImage, excludeIdentifier string, requiredFeatureSet string, profile string,
142142
knownCapabilities []configv1.ClusterVersionCapability) (*Update, error) {
143143

144-
payload, tasks, err := loadUpdatePayloadMetadata(dir, releaseImage, profile)
144+
klog.V(2).Infof("Loading updatepayload from %q", dir)
145+
if err := ValidateDirectory(dir); err != nil {
146+
return nil, err
147+
}
148+
149+
var (
150+
releaseDir = filepath.Join(dir, ReleaseManifestDir)
151+
cvoDir = filepath.Join(dir, CVOManifestDir)
152+
)
153+
154+
payload, err := loadMetadata(releaseDir, releaseImage)
145155
if err != nil {
146156
return nil, err
147157
}
148158

159+
tasks := getPayloadTasks(releaseDir, cvoDir, releaseImage, profile)
160+
149161
var onlyKnownCaps *configv1.ClusterVersionCapabilitiesStatus
150162

151163
if knownCapabilities != nil {
@@ -299,38 +311,27 @@ type payloadTasks struct {
299311
skipFiles sets.Set[string]
300312
}
301313

302-
func loadUpdatePayloadMetadata(dir, releaseImage, clusterProfile string) (*Update, []payloadTasks, error) {
303-
klog.V(2).Infof("Loading updatepayload from %q", dir)
304-
if err := ValidateDirectory(dir); err != nil {
305-
return nil, nil, err
306-
}
307-
var (
308-
cvoDir = filepath.Join(dir, CVOManifestDir)
309-
releaseDir = filepath.Join(dir, ReleaseManifestDir)
310-
)
311-
312-
release, arch, err := loadReleaseFromMetadata(releaseDir)
314+
func loadMetadata(releaseDir, releaseImage string) (*Update, error) {
315+
release, arch, err := LoadReleaseFromMetadata(releaseDir)
313316
if err != nil {
314-
return nil, nil, err
317+
return nil, err
315318
}
316319
release.Image = releaseImage
317320

318321
imageRef, err := loadImageReferences(releaseDir)
319322
if err != nil {
320-
return nil, nil, err
323+
return nil, err
321324
}
322325

323326
if imageRef.Name != release.Version {
324-
return nil, nil, fmt.Errorf("Version from %s (%s) differs from %s (%s)", imageReferencesFile, imageRef.Name, cincinnatiJSONFile, release.Version)
327+
return nil, fmt.Errorf("Version from %s (%s) differs from %s (%s)", imageReferencesFile, imageRef.Name, cincinnatiJSONFile, release.Version)
325328
}
326329

327-
tasks := getPayloadTasks(releaseDir, cvoDir, releaseImage, clusterProfile)
328-
329330
return &Update{
330331
Release: release,
331332
ImageRef: imageRef,
332333
Architecture: arch,
333-
}, tasks, nil
334+
}, nil
334335
}
335336

336337
func getPayloadTasks(releaseDir, cvoDir, releaseImage, clusterProfile string) []payloadTasks {
@@ -353,7 +354,7 @@ func getPayloadTasks(releaseDir, cvoDir, releaseImage, clusterProfile string) []
353354
}}
354355
}
355356

356-
func loadReleaseFromMetadata(releaseDir string) (configv1.Release, string, error) {
357+
func LoadReleaseFromMetadata(releaseDir string) (configv1.Release, string, error) {
357358
var release configv1.Release
358359
path := filepath.Join(releaseDir, cincinnatiJSONFile)
359360
data, err := os.ReadFile(path)

0 commit comments

Comments
 (0)