Skip to content

Commit 6a7747e

Browse files
committed
Add second implementation option
Signed-off-by: Per G. da Silva <[email protected]>
1 parent ca038a8 commit 6a7747e

File tree

4 files changed

+120
-8
lines changed

4 files changed

+120
-8
lines changed

pkg/controller/registry/reconciler/reconciler.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ func Pod(source *v1alpha1.CatalogSource, name string, image string, saName strin
122122
},
123123
Spec: v1.PodSpec{
124124
// TODO: Remove this before merging
125-
HostNetwork: true,
125+
// HostNetwork: true,
126126
Containers: []v1.Container{
127127
{
128128
Name: name,

pkg/controller/registry/resolver/installabletypes.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ func (i *BundleInstallable) AddConstraint(c solver.Constraint) {
3636
i.constraints = append(i.constraints, c)
3737
}
3838

39+
func (i *BundleInstallable) AddRuntimeConstraintFailure(message string) {
40+
msg := fmt.Sprintf("%s is violates a cluster runtime constraint: %s", i.identifier, message)
41+
i.AddConstraint(PrettyConstraint(solver.Prohibited(), msg))
42+
}
43+
3944
func (i *BundleInstallable) BundleSourceInfo() (string, string, cache.SourceKey, error) {
4045
info := strings.Split(i.identifier.String(), "/")
4146
// This should be enforced by Kube naming constraints

pkg/controller/registry/resolver/resolver.go

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,14 @@ package resolver
33
import (
44
"context"
55
"encoding/json"
6+
"errors"
67
"fmt"
8+
"os"
79
"sort"
810
"strings"
911

12+
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/runtime_constraints"
13+
1014
"github.com/blang/semver/v4"
1115
"github.com/sirupsen/logrus"
1216
utilerrors "k8s.io/apimachinery/pkg/util/errors"
@@ -20,25 +24,42 @@ import (
2024
opregistry "github.com/operator-framework/operator-registry/pkg/registry"
2125
)
2226

27+
const (
28+
runtimeConstraintsFilePath = "runtime_constraints.yaml"
29+
)
30+
2331
type OperatorResolver interface {
2432
SolveOperators(csvs []*v1alpha1.ClusterServiceVersion, subs []*v1alpha1.Subscription, add map[cache.OperatorSourceInfo]struct{}) (cache.OperatorSet, error)
2533
}
2634

2735
type SatResolver struct {
28-
cache cache.OperatorCacheProvider
29-
log logrus.FieldLogger
36+
cache cache.OperatorCacheProvider
37+
log logrus.FieldLogger
38+
runtimeConstraintsProvider *runtime_constraints.RuntimeConstraintsProvider
3039
}
3140

3241
func NewDefaultSatResolver(rcp cache.SourceProvider, catsrcLister v1alpha1listers.CatalogSourceLister, logger logrus.FieldLogger) *SatResolver {
33-
// Get runtime constraints somehow
34-
runtimeConstraints := []cache.Predicate{
35-
// Only etcd can be installed on this system!
36-
cache.PkgPredicate("etcd"),
42+
43+
runtimeConstraintProvider, err := runtime_constraints.NewFromFile(runtimeConstraintsFilePath)
44+
if err != nil && !errors.Is(err, os.ErrNotExist) {
45+
if errors.Is(err, os.ErrNotExist) {
46+
logger.Warning("No cluster runtime constraints file found")
47+
} else {
48+
logger.Errorf("Error creating runtime constraints from file: %s", err)
49+
panic(err)
50+
}
3751
}
3852

53+
// Two solutions:
54+
// #1: Global cache filters
55+
// globalFilters := cache.WithGlobalFilters(runtimeConstraintProvider.GetRuntimeConstraints()...)
56+
3957
return &SatResolver{
40-
cache: cache.New(rcp, cache.WithLogger(logger), cache.WithCatalogSourceLister(catsrcLister), cache.WithGlobalFilters(runtimeConstraints...)),
58+
cache: cache.New(rcp, cache.WithLogger(logger), cache.WithCatalogSourceLister(catsrcLister) /*, globalFilters*/),
4159
log: logger,
60+
// #2: apply constraints in addInvariants
61+
runtimeConstraintsProvider: runtimeConstraintProvider, // uncomment when using option #2
62+
// runtimeConstraintsProvider: nil // uncomment when using option #1
4263
}
4364
}
4465

@@ -574,6 +595,16 @@ func (r *SatResolver) addInvariants(namespacedCache cache.MultiCatalogOperatorFi
574595
}
575596
packageConflictToInstallable[prop.PackageName] = append(packageConflictToInstallable[prop.PackageName], installable.Identifier())
576597
}
598+
599+
// apply runtime constraints to packages that aren't already installed
600+
if !catalog.Virtual() && r.runtimeConstraintsProvider != nil {
601+
for _, predicate := range r.runtimeConstraintsProvider.GetRuntimeConstraints() {
602+
if !predicate.Test(op) {
603+
bundleInstallable.AddRuntimeConstraintFailure(predicate.String())
604+
break
605+
}
606+
}
607+
}
577608
}
578609

579610
for gvk, is := range gvkConflictToInstallable {
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package runtime_constraints
2+
3+
import (
4+
"encoding/json"
5+
"io/ioutil"
6+
7+
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/cache"
8+
"github.com/operator-framework/operator-registry/pkg/registry"
9+
"github.com/pkg/errors"
10+
)
11+
12+
const (
13+
maxRuntimeConstraints = 10
14+
)
15+
16+
type RuntimeConstraintsProvider struct {
17+
runtimeConstraints []cache.Predicate
18+
}
19+
20+
func (p *RuntimeConstraintsProvider) GetRuntimeConstraints() []cache.Predicate {
21+
return p.runtimeConstraints
22+
}
23+
24+
func NewFromFile(runtimeConstraintsFilePath string) (*RuntimeConstraintsProvider, error) {
25+
propertiesFile, err := readRuntimeConstraintsYaml(runtimeConstraintsFilePath)
26+
if err != nil {
27+
return nil, err
28+
}
29+
30+
// Using package type to test with
31+
// We may only want to allow the generic constraint types once they are readym
32+
var constraints = make([]cache.Predicate, 0)
33+
for _, property := range propertiesFile.Properties {
34+
rawMessage := []byte(property.Value)
35+
switch property.Type {
36+
case registry.PackageType:
37+
dep := registry.PackageDependency{}
38+
err := json.Unmarshal(rawMessage, &dep)
39+
if err != nil {
40+
return nil, err
41+
}
42+
constraints = append(constraints, cache.PkgPredicate(dep.PackageName))
43+
case registry.LabelType:
44+
dep := registry.LabelDependency{}
45+
err := json.Unmarshal(rawMessage, &dep)
46+
if err != nil {
47+
return nil, err
48+
}
49+
constraints = append(constraints, cache.LabelPredicate(dep.Label))
50+
}
51+
if len(constraints) >= maxRuntimeConstraints {
52+
return nil, errors.Errorf("Too many runtime constraints defined (%d/%d)", len(constraints), maxRuntimeConstraints)
53+
}
54+
}
55+
56+
return &RuntimeConstraintsProvider{
57+
runtimeConstraints: constraints,
58+
}, nil
59+
}
60+
61+
func readRuntimeConstraintsYaml(yamlPath string) (*registry.PropertiesFile, error) {
62+
// Read file
63+
yamlFile, err := ioutil.ReadFile(yamlPath)
64+
if err != nil {
65+
return nil, err
66+
}
67+
68+
// Parse yaml
69+
var propertiesFile = &registry.PropertiesFile{}
70+
err = json.Unmarshal(yamlFile, propertiesFile)
71+
if err != nil {
72+
return nil, err
73+
}
74+
75+
return propertiesFile, nil
76+
}

0 commit comments

Comments
 (0)