@@ -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"
@@ -255,6 +257,11 @@ func (o *OperatorOptions) getFeatureGateMappingFromDisk(ctx context.Context, con
255257 clusterProfileAnnotation = "include.release.openshift.io/self-managed-high-availability"
256258 }
257259
260+ operatorVersion , err := semver .ParseTolerant (o .OperatorVersion )
261+ if err != nil {
262+ return nil , fmt .Errorf ("unable to parse operator version: %w" , err )
263+ }
264+
258265 ret := map [configv1.FeatureSet ]* features.FeatureGateEnabledDisabled {}
259266
260267 err = filepath .Walk (o .AuthoritativeFeatureGateDir ,
@@ -285,6 +292,11 @@ func (o *OperatorOptions) getFeatureGateMappingFromDisk(ctx context.Context, con
285292 }
286293 }
287294
295+ if excludesOperatorVersion (featureGate .Annotations , operatorVersion .Major ) {
296+ // This manifest includes a range of versions it applies to, but it does not apply to our current version.
297+ return nil
298+ }
299+
288300 featureGateValues := & features.FeatureGateEnabledDisabled {}
289301 for _ , possibleGates := range featureGate .Status .FeatureGates {
290302 if possibleGates .Version != o .OperatorVersion {
@@ -363,3 +375,56 @@ func extractOperatorStatus(obj *unstructured.Unstructured, fieldManager string)
363375 }
364376 return & ret .Status .OperatorStatusApplyConfiguration , nil
365377}
378+
379+ func excludesOperatorVersion (annotations map [string ]string , operatorMajorVersion uint64 ) bool {
380+ var versionsRaw string
381+
382+ for k , v := range annotations {
383+ if k == "release.openshift.io/major-version" {
384+ versionsRaw = v
385+ break
386+ }
387+ }
388+
389+ if versionsRaw == "" {
390+ return false
391+ }
392+
393+ versions := strings .Split (versionsRaw , "," )
394+
395+ hasOperatorVersion , err := includesDesiredVersion (versions , operatorMajorVersion )
396+ if err != nil {
397+ // Malformed annotation so should be excluded.
398+ return true
399+ }
400+
401+ return ! hasOperatorVersion
402+ }
403+
404+ func includesDesiredVersion (versions []string , desiredVersion uint64 ) (bool , error ) {
405+ for _ , versionStr := range versions {
406+ versionStr = strings .TrimSpace (versionStr )
407+ if len (versionStr ) == 0 {
408+ continue
409+ }
410+
411+ // Skip excluded versions.
412+ if strings .HasPrefix (versionStr , "-" ) {
413+ // If the version starts with a '-', it means that the version is excluded.
414+ // Since we are only looking for positive matches we can skip processing
415+ // this version any further.
416+ continue
417+ }
418+
419+ version , err := strconv .ParseUint (versionStr , 10 , 64 )
420+ if err != nil {
421+ // Malformed annotation so should be excluded
422+ return false , fmt .Errorf ("malformed annotation: %s" , versionStr )
423+ }
424+ if version == desiredVersion {
425+ return true , nil
426+ }
427+ }
428+
429+ return false , nil
430+ }
0 commit comments