@@ -11,6 +11,7 @@ import (
11
11
"github.com/sirupsen/logrus"
12
12
utilerrors "k8s.io/apimachinery/pkg/util/errors"
13
13
14
+ "github.com/operator-framework/api/pkg/constraints"
14
15
"github.com/operator-framework/api/pkg/operators/v1alpha1"
15
16
v1alpha1listers "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1alpha1"
16
17
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/cache"
@@ -27,12 +28,14 @@ type OperatorResolver interface {
27
28
type SatResolver struct {
28
29
cache cache.OperatorCacheProvider
29
30
log logrus.FieldLogger
31
+ pc * predicateConverter
30
32
}
31
33
32
34
func NewDefaultSatResolver (rcp cache.SourceProvider , catsrcLister v1alpha1listers.CatalogSourceLister , logger logrus.FieldLogger ) * SatResolver {
33
35
return & SatResolver {
34
36
cache : cache .New (rcp , cache .WithLogger (logger ), cache .WithCatalogSourceLister (catsrcLister )),
35
37
log : logger ,
38
+ pc : & predicateConverter {},
36
39
}
37
40
}
38
41
@@ -337,7 +340,7 @@ func (r *SatResolver) getBundleInstallables(preferredNamespace string, bundleSta
337
340
338
341
visited [bundle ] = & bundleInstallable
339
342
340
- dependencyPredicates , err := DependencyPredicates (bundle .Properties )
343
+ dependencyPredicates , err := r . pc . convertDependencyProperties (bundle .Properties )
341
344
if err != nil {
342
345
errs = append (errs , err )
343
346
continue
@@ -733,10 +736,14 @@ func sortChannel(bundles []*cache.Entry) ([]*cache.Entry, error) {
733
736
return chains [0 ], nil
734
737
}
735
738
736
- func DependencyPredicates (properties []* api.Property ) ([]cache.Predicate , error ) {
739
+ // predicateConverter configures olm.constraint value -> predicate conversion for the resolver.
740
+ type predicateConverter struct {}
741
+
742
+ // convertDependencyProperties converts all known constraint properties to predicates.
743
+ func (pc * predicateConverter ) convertDependencyProperties (properties []* api.Property ) ([]cache.Predicate , error ) {
737
744
var predicates []cache.Predicate
738
745
for _ , property := range properties {
739
- predicate , err := predicateForProperty (property )
746
+ predicate , err := pc . predicateForProperty (property )
740
747
if err != nil {
741
748
return nil , err
742
749
}
@@ -748,18 +755,80 @@ func DependencyPredicates(properties []*api.Property) ([]cache.Predicate, error)
748
755
return predicates , nil
749
756
}
750
757
751
- func predicateForProperty (property * api.Property ) (cache.Predicate , error ) {
758
+ func ( pc * predicateConverter ) predicateForProperty (property * api.Property ) (cache.Predicate , error ) {
752
759
if property == nil {
753
760
return nil , nil
754
761
}
755
- p , ok := predicates [property .Type ]
762
+
763
+ // olm.constraint holds all constraint types except legacy types,
764
+ // so defer error handling to its parser.
765
+ if property .Type == constraints .OLMConstraintType {
766
+ return pc .predicateForConstraintProperty (property .Value )
767
+ }
768
+
769
+ // Legacy behavior dictates that unknown properties are ignored. See enhancement for details:
770
+ // https://github.com/operator-framework/enhancements/blob/master/enhancements/compound-bundle-constraints.md
771
+ p , ok := legacyPredicateParsers [property .Type ]
756
772
if ! ok {
757
773
return nil , nil
758
774
}
759
775
return p (property .Value )
760
776
}
761
777
762
- var predicates = map [string ]func (string ) (cache.Predicate , error ){
778
+ func (pc * predicateConverter ) predicateForConstraintProperty (value string ) (cache.Predicate , error ) {
779
+ constraint , err := constraints .Parse (json .RawMessage ([]byte (value )))
780
+ if err != nil {
781
+ return nil , fmt .Errorf ("parse olm.constraint: %v" , err )
782
+ }
783
+
784
+ preds , err := pc .convertConstraints (constraint )
785
+ if err != nil {
786
+ return nil , fmt .Errorf ("convert olm.constraint to resolver predicate: %v" , err )
787
+ }
788
+ return preds [0 ], nil
789
+ }
790
+
791
+ // convertConstraints creates predicates from each element of constraints, recursing on compound constraints.
792
+ // New constraint types added to the constraints package must be handled here.
793
+ func (pc * predicateConverter ) convertConstraints (constraints ... constraints.Constraint ) ([]cache.Predicate , error ) {
794
+
795
+ preds := make ([]cache.Predicate , len (constraints ))
796
+ for i , constraint := range constraints {
797
+
798
+ var err error
799
+ switch {
800
+ case constraint .GVK != nil :
801
+ preds [i ] = cache .ProvidingAPIPredicate (opregistry.APIKey {
802
+ Group : constraint .GVK .Group ,
803
+ Version : constraint .GVK .Version ,
804
+ Kind : constraint .GVK .Kind ,
805
+ })
806
+ case constraint .Package != nil :
807
+ preds [i ], err = newPackageRequiredPredicate (constraint .Package .PackageName , constraint .Package .VersionRange )
808
+ case constraint .All != nil :
809
+ subs , perr := pc .convertConstraints (constraint .All .Constraints ... )
810
+ preds [i ], err = cache .And (subs ... ), perr
811
+ case constraint .Any != nil :
812
+ subs , perr := pc .convertConstraints (constraint .Any .Constraints ... )
813
+ preds [i ], err = cache .Or (subs ... ), perr
814
+ case constraint .None != nil :
815
+ subs , perr := pc .convertConstraints (constraint .None .Constraints ... )
816
+ preds [i ], err = cache .Not (subs ... ), perr
817
+ default :
818
+ // Unknown constraint types are handled by constraints.Parse(),
819
+ // but parsed constraints may be empty.
820
+ return nil , fmt .Errorf ("constraint is empty" )
821
+ }
822
+ if err != nil {
823
+ return nil , err
824
+ }
825
+
826
+ }
827
+
828
+ return preds , nil
829
+ }
830
+
831
+ var legacyPredicateParsers = map [string ]func (string ) (cache.Predicate , error ){
763
832
"olm.gvk.required" : predicateForRequiredGVKProperty ,
764
833
"olm.package.required" : predicateForRequiredPackageProperty ,
765
834
"olm.label.required" : predicateForRequiredLabelProperty ,
@@ -789,11 +858,15 @@ func predicateForRequiredPackageProperty(value string) (cache.Predicate, error)
789
858
if err := json .Unmarshal ([]byte (value ), & pkg ); err != nil {
790
859
return nil , err
791
860
}
792
- ver , err := semver .ParseRange (pkg .VersionRange )
861
+ return newPackageRequiredPredicate (pkg .PackageName , pkg .VersionRange )
862
+ }
863
+
864
+ func newPackageRequiredPredicate (name , verRange string ) (cache.Predicate , error ) {
865
+ ver , err := semver .ParseRange (verRange )
793
866
if err != nil {
794
867
return nil , err
795
868
}
796
- return cache .And (cache .PkgPredicate (pkg . PackageName ), cache .VersionInRangePredicate (ver , pkg . VersionRange )), nil
869
+ return cache .And (cache .PkgPredicate (name ), cache .VersionInRangePredicate (ver , verRange )), nil
797
870
}
798
871
799
872
func predicateForRequiredLabelProperty (value string ) (cache.Predicate , error ) {
0 commit comments