4
4
"context"
5
5
"fmt"
6
6
"slices"
7
+ "sort"
7
8
8
9
mmsemver "github.com/Masterminds/semver/v3"
9
10
bsemver "github.com/blang/semver/v4"
@@ -50,9 +51,14 @@ func (r *CatalogResolver) Resolve(ctx context.Context, ext *ocv1alpha1.ClusterEx
50
51
}
51
52
}
52
53
54
+ type foundBundle struct {
55
+ bundle * declcfg.Bundle
56
+ catalog string
57
+ priority int32
58
+ }
59
+
60
+ resolvedBundles := []foundBundle {}
53
61
var (
54
- resolvedBundles []* declcfg.Bundle
55
- matchedCatalogs []string
56
62
priorDeprecation * declcfg.Deprecation
57
63
)
58
64
@@ -114,33 +120,47 @@ func (r *CatalogResolver) Resolve(ctx context.Context, ext *ocv1alpha1.ClusterEx
114
120
if len (resolvedBundles ) != 0 {
115
121
// We've already found one or more package candidates
116
122
currentIsDeprecated := isDeprecated (thisBundle , thisDeprecation )
117
- priorIsDeprecated := isDeprecated (* resolvedBundles [len (resolvedBundles )- 1 ], priorDeprecation )
123
+ priorIsDeprecated := isDeprecated (* resolvedBundles [len (resolvedBundles )- 1 ]. bundle , priorDeprecation )
118
124
if currentIsDeprecated && ! priorIsDeprecated {
119
125
// Skip this deprecated package and retain the non-deprecated package(s)
120
126
return nil
121
127
} else if ! currentIsDeprecated && priorIsDeprecated {
122
128
// Our package candidates so far were deprecated and this one is not; clear the lists
123
- resolvedBundles = []* declcfg.Bundle {}
124
- matchedCatalogs = []string {}
129
+ resolvedBundles = []foundBundle {}
125
130
}
126
131
}
127
132
// The current bundle shares deprecation status with prior bundles or
128
133
// there are no prior bundles. Add it to the list.
129
- resolvedBundles = append (resolvedBundles , & thisBundle )
130
- matchedCatalogs = append (matchedCatalogs , cat .GetName ())
134
+ resolvedBundles = append (resolvedBundles , foundBundle {& thisBundle , cat .GetName (), cat .Spec .Priority })
131
135
priorDeprecation = thisDeprecation
132
136
return nil
133
137
}, listOptions ... ); err != nil {
134
138
return nil , nil , nil , fmt .Errorf ("error walking catalogs: %w" , err )
135
139
}
136
140
141
+ // Resolve for priority
142
+ if len (resolvedBundles ) > 1 {
143
+ // Want highest first (reverse sort)
144
+ sort .Slice (resolvedBundles , func (i , j int ) bool { return resolvedBundles [i ].priority > resolvedBundles [j ].priority })
145
+ // If the top two bundles do not have the same priority, then priority breaks the tie
146
+ // Reduce resolvedBundles to just the first item (highest priority)
147
+ if resolvedBundles [0 ].priority != resolvedBundles [1 ].priority {
148
+ resolvedBundles = []foundBundle {resolvedBundles [0 ]}
149
+ }
150
+ }
151
+
152
+ // Check for ambiguity
137
153
if len (resolvedBundles ) != 1 {
138
154
errPrefix := ""
139
155
if installedBundle != nil {
140
156
errPrefix = fmt .Sprintf ("error upgrading from currently installed version %q: " , installedBundle .Version )
141
157
}
142
158
switch {
143
159
case len (resolvedBundles ) > 1 :
160
+ matchedCatalogs := []string {}
161
+ for _ , r := range resolvedBundles {
162
+ matchedCatalogs = append (matchedCatalogs , r .catalog )
163
+ }
144
164
slices .Sort (matchedCatalogs ) // sort for consistent error message
145
165
return nil , nil , nil , fmt .Errorf ("%smatching packages found in multiple catalogs: %v" , errPrefix , matchedCatalogs )
146
166
case versionRange != "" && channelName != "" :
@@ -153,7 +173,7 @@ func (r *CatalogResolver) Resolve(ctx context.Context, ext *ocv1alpha1.ClusterEx
153
173
return nil , nil , nil , fmt .Errorf ("%sno package %q found" , errPrefix , packageName )
154
174
}
155
175
}
156
- resolvedBundle := resolvedBundles [0 ]
176
+ resolvedBundle := resolvedBundles [0 ]. bundle
157
177
resolvedBundleVersion , err := bundleutil .GetVersion (* resolvedBundle )
158
178
if err != nil {
159
179
return nil , nil , nil , fmt .Errorf ("error getting resolved bundle version for bundle %q: %w" , resolvedBundle .Name , err )
0 commit comments