@@ -5,13 +5,15 @@ import (
5
5
"fmt"
6
6
"sort"
7
7
8
+ mmsemver "github.com/Masterminds/semver/v3"
8
9
"github.com/operator-framework/deppy/pkg/deppy"
9
10
"github.com/operator-framework/deppy/pkg/deppy/input"
10
11
11
12
"github.com/operator-framework/operator-controller/internal/catalogmetadata"
12
13
catalogfilter "github.com/operator-framework/operator-controller/internal/catalogmetadata/filter"
13
14
catalogsort "github.com/operator-framework/operator-controller/internal/catalogmetadata/sort"
14
15
"github.com/operator-framework/operator-controller/internal/resolution/variables"
16
+ "github.com/operator-framework/operator-controller/pkg/features"
15
17
)
16
18
17
19
var _ input.VariableSource = & InstalledPackageVariableSource {}
@@ -59,10 +61,15 @@ func (r *InstalledPackageVariableSource) notFoundError() error {
59
61
}
60
62
61
63
func NewInstalledPackageVariableSource (catalogClient BundleProvider , bundleImage string ) (* InstalledPackageVariableSource , error ) {
64
+ successors := legacySemanticsSuccessors
65
+ if features .OperatorControllerFeatureGate .Enabled (features .ForceSemverUpgradeConstraints ) {
66
+ successors = semverSuccessors
67
+ }
68
+
62
69
return & InstalledPackageVariableSource {
63
70
catalogClient : catalogClient ,
64
71
bundleImage : bundleImage ,
65
- successors : legacySemanticsSuccessors ,
72
+ successors : successors ,
66
73
}, nil
67
74
}
68
75
@@ -83,3 +90,28 @@ func legacySemanticsSuccessors(allBundles []*catalogmetadata.Bundle, installedBu
83
90
84
91
return upgradeEdges , nil
85
92
}
93
+
94
+ // semverSuccessors returns successors based on Semver.
95
+ // Successors will not include versions outside the major version of the
96
+ // installed bundle as major version is intended to indicate breaking changes.
97
+ func semverSuccessors (allBundles []* catalogmetadata.Bundle , installedBundle * catalogmetadata.Bundle ) ([]* catalogmetadata.Bundle , error ) {
98
+ currentVersion , err := installedBundle .Version ()
99
+ if err != nil {
100
+ return nil , err
101
+ }
102
+
103
+ // Based on current version create a caret range comparison constraint
104
+ // to allow only major and patch version as successors and exclude current version.
105
+ constraintStr := fmt .Sprintf ("^%s, != %s" , currentVersion .String (), currentVersion .String ())
106
+ wantedVersionRangeConstraint , err := mmsemver .NewConstraint (constraintStr )
107
+ if err != nil {
108
+ return nil , err
109
+ }
110
+
111
+ upgradeEdges := catalogfilter .Filter (allBundles , catalogfilter .InMastermindsSemverRange (wantedVersionRangeConstraint ))
112
+ sort .SliceStable (upgradeEdges , func (i , j int ) bool {
113
+ return catalogsort .ByVersion (upgradeEdges [i ], upgradeEdges [j ])
114
+ })
115
+
116
+ return upgradeEdges , nil
117
+ }
0 commit comments