@@ -5,9 +5,11 @@ import (
55 "fmt"
66 "os"
77 "path/filepath"
8+ "strconv"
89 "strings"
910 "time"
1011
12+ "github.com/blang/semver/v4"
1113 "github.com/openshift/api/features"
1214
1315 "github.com/davecgh/go-spew/spew"
@@ -244,6 +246,11 @@ func (o *OperatorOptions) getFeatureGateMappingFromDisk(ctx context.Context, con
244246 clusterProfileAnnotation = "include.release.openshift.io/self-managed-high-availability"
245247 }
246248
249+ operatorVersion , err := semver .ParseTolerant (o .OperatorVersion )
250+ if err != nil {
251+ return nil , fmt .Errorf ("unable to parse operator version: %w" , err )
252+ }
253+
247254 ret := map [configv1.FeatureSet ]* features.FeatureGateEnabledDisabled {}
248255
249256 err = filepath .Walk (o .AuthoritativeFeatureGateDir ,
@@ -274,6 +281,11 @@ func (o *OperatorOptions) getFeatureGateMappingFromDisk(ctx context.Context, con
274281 }
275282 }
276283
284+ if excludesOperatorVersion (featureGate .Annotations , operatorVersion .Major ) {
285+ // This manifest includes a range of versions it applies to, but it does not apply to our current version.
286+ return nil
287+ }
288+
277289 featureGateValues := & features.FeatureGateEnabledDisabled {}
278290 for _ , possibleGates := range featureGate .Status .FeatureGates {
279291 if possibleGates .Version != o .OperatorVersion {
@@ -352,3 +364,43 @@ func extractOperatorStatus(obj *unstructured.Unstructured, fieldManager string)
352364 }
353365 return & ret .Status .OperatorStatusApplyConfiguration , nil
354366}
367+
368+ func excludesOperatorVersion (annotations map [string ]string , operatorVersion uint64 ) bool {
369+ var versionsRaw string
370+
371+ for k , v := range annotations {
372+ if k == "release.openshift.io/major-version" {
373+ versionsRaw = v
374+ break
375+ }
376+ }
377+
378+ if versionsRaw == "" {
379+ return false
380+ }
381+
382+ versions := strings .Split (versionsRaw , "," )
383+
384+ hasOperatorVersion , err := includesDesiredVersion (versions , operatorVersion )
385+ if err != nil {
386+ // Malformed annotation so should be excluded.
387+ return true
388+ }
389+
390+ return ! hasOperatorVersion
391+ }
392+
393+ func includesDesiredVersion (versions []string , operatorVersion uint64 ) (bool , error ) {
394+ for _ , version := range versions {
395+ version , err := strconv .ParseUint (version , 10 , 64 )
396+ if err != nil {
397+ // Malformed annotation so should be excluded
398+ return false , fmt .Errorf ("malformed annotation: %s" , version )
399+ }
400+ if version == operatorVersion {
401+ return true , nil
402+ }
403+ }
404+
405+ return false , nil
406+ }
0 commit comments