diff --git a/pkg/controller/operators/catalog/operator_test.go b/pkg/controller/operators/catalog/operator_test.go index 0bc9056018..5518bf1d3d 100644 --- a/pkg/controller/operators/catalog/operator_test.go +++ b/pkg/controller/operators/catalog/operator_test.go @@ -1189,8 +1189,8 @@ func TestSyncResolvingNamespace(t *testing.T) { }, resolveErr: solver.NotSatisfiable{ { - Installable: resolver.NewSubscriptionInstallable("a", nil), - Constraint: resolver.PrettyConstraint(solver.Mandatory(), "something"), + Variable: resolver.NewSubscriptionVariable("a", nil), + Constraint: resolver.PrettyConstraint(solver.Mandatory(), "something"), }, }, }, diff --git a/pkg/controller/registry/resolver/resolver.go b/pkg/controller/registry/resolver/resolver.go index 1f1b8a5590..5419a930e2 100644 --- a/pkg/controller/registry/resolver/resolver.go +++ b/pkg/controller/registry/resolver/resolver.go @@ -55,8 +55,8 @@ func (w *debugWriter) Write(b []byte) (int, error) { func (r *SatResolver) SolveOperators(namespaces []string, csvs []*v1alpha1.ClusterServiceVersion, subs []*v1alpha1.Subscription) (cache.OperatorSet, error) { var errs []error - installables := make(map[solver.Identifier]solver.Installable) - visited := make(map[*cache.Entry]*BundleInstallable) + variables := make(map[solver.Identifier]solver.Variable) + visited := make(map[*cache.Entry]*BundleVariable) // TODO: better abstraction startingCSVs := make(map[string]struct{}) @@ -68,12 +68,12 @@ func (r *SatResolver) SolveOperators(namespaces []string, csvs []*v1alpha1.Clust } namespacedCache := r.cache.Namespaced(namespaces...).WithExistingOperators(existingSnapshot, namespaces[0]) - _, existingInstallables, err := r.getBundleInstallables(namespaces[0], cache.Filter(existingSnapshot.Entries, cache.True()), namespacedCache, visited) + _, existingVariables, err := r.getBundleVariables(namespaces[0], cache.Filter(existingSnapshot.Entries, cache.True()), namespacedCache, visited) if err != nil { return nil, err } - for _, i := range existingInstallables { - installables[i.Identifier()] = i + for _, i := range existingVariables { + variables[i.Identifier()] = i } // build constraints for each Subscription @@ -96,25 +96,25 @@ func (r *SatResolver) SolveOperators(namespaces []string, csvs []*v1alpha1.Clust } // find operators, in channel order, that can skip from the current version or list the current in "replaces" - subInstallables, err := r.getSubscriptionInstallables(sub, current, namespacedCache, visited) + subVariables, err := r.getSubscriptionVariables(sub, current, namespacedCache, visited) if err != nil { errs = append(errs, err) continue } - for _, i := range subInstallables { - installables[i.Identifier()] = i + for _, i := range subVariables { + variables[i.Identifier()] = i } } - r.addInvariants(namespacedCache, installables) + r.addInvariants(namespacedCache, variables) if err := namespacedCache.Error(); err != nil { return nil, err } - input := make([]solver.Installable, 0) - for _, i := range installables { + input := make([]solver.Variable, 0) + for _, i := range variables { input = append(input, i) } @@ -125,16 +125,16 @@ func (r *SatResolver) SolveOperators(namespaces []string, csvs []*v1alpha1.Clust if err != nil { return nil, err } - solvedInstallables, err := s.Solve(context.TODO()) + solvedVariables, err := s.Solve(context.TODO()) if err != nil { return nil, err } - // get the set of bundle installables from the result solved installables - operatorInstallables := make([]BundleInstallable, 0) - for _, installable := range solvedInstallables { - if bundleInstallable, ok := installable.(*BundleInstallable); ok { - _, _, catalog, err := bundleInstallable.BundleSourceInfo() + // get the set of bundle variables from the result solved variables + operatorVariables := make([]BundleVariable, 0) + for _, variable := range solvedVariables { + if bundleVariable, ok := variable.(*BundleVariable); ok { + _, _, catalog, err := bundleVariable.BundleSourceInfo() if err != nil { return nil, fmt.Errorf("error determining origin of operator: %w", err) } @@ -142,13 +142,13 @@ func (r *SatResolver) SolveOperators(namespaces []string, csvs []*v1alpha1.Clust // Result is expected to contain only new things. continue } - operatorInstallables = append(operatorInstallables, *bundleInstallable) + operatorVariables = append(operatorVariables, *bundleVariable) } } operators := make(map[string]*cache.Entry) - for _, installableOperator := range operatorInstallables { - csvName, channel, catalog, err := installableOperator.BundleSourceInfo() + for _, variableOperator := range operatorVariables { + csvName, channel, catalog, err := variableOperator.BundleSourceInfo() if err != nil { errs = append(errs, err) continue @@ -181,11 +181,11 @@ func (r *SatResolver) SolveOperators(namespaces []string, csvs []*v1alpha1.Clust BundlePath: op.BundlePath, Bundle: op.Bundle, } - if len(installableOperator.Replaces) > 0 { - op.Replaces = installableOperator.Replaces + if len(variableOperator.Replaces) > 0 { + op.Replaces = variableOperator.Replaces } - // lookup if this installable came from a starting CSV + // lookup if this variable came from a starting CSV if _, ok := startingCSVs[csvName]; ok { op.SourceInfo.StartingCSV = csvName } @@ -200,10 +200,10 @@ func (r *SatResolver) SolveOperators(namespaces []string, csvs []*v1alpha1.Clust return operators, nil } -// newBundleInstallableFromEntry converts an entry into a bundle installable with +// newBundleVariableFromEntry converts an entry into a bundle variable with // system constraints applied, if they are defined for the entry -func (r *SatResolver) newBundleInstallableFromEntry(entry *cache.Entry) (*BundleInstallable, error) { - bundleInstalleble, err := NewBundleInstallableFromOperator(entry) +func (r *SatResolver) newBundleVariableFromEntry(entry *cache.Entry) (*BundleVariable, error) { + bundleInstalleble, err := NewBundleVariableFromOperator(entry) if err != nil { return nil, err } @@ -219,9 +219,9 @@ func (r *SatResolver) newBundleInstallableFromEntry(entry *cache.Entry) (*Bundle return &bundleInstalleble, nil } -func (r *SatResolver) getSubscriptionInstallables(sub *v1alpha1.Subscription, current *cache.Entry, namespacedCache cache.MultiCatalogOperatorFinder, visited map[*cache.Entry]*BundleInstallable) (map[solver.Identifier]solver.Installable, error) { +func (r *SatResolver) getSubscriptionVariables(sub *v1alpha1.Subscription, current *cache.Entry, namespacedCache cache.MultiCatalogOperatorFinder, visited map[*cache.Entry]*BundleVariable) (map[solver.Identifier]solver.Variable, error) { var cachePredicates, channelPredicates []cache.Predicate - installables := make(map[solver.Identifier]solver.Installable) + variables := make(map[solver.Identifier]solver.Variable) catalog := cache.SourceKey{ Name: sub.Spec.CatalogSource, @@ -249,21 +249,21 @@ func (r *SatResolver) getSubscriptionInstallables(sub *v1alpha1.Subscription, cu )) entries = namespacedCache.Catalog(catalog).Find(cachePredicates...) - var si solver.Installable + var si solver.Variable switch { case nall == 0: - si = NewInvalidSubscriptionInstallable(sub.GetName(), fmt.Sprintf("no operators found from catalog %s in namespace %s referenced by subscription %s", sub.Spec.CatalogSource, sub.Spec.CatalogSourceNamespace, sub.GetName())) + si = NewInvalidSubscriptionVariable(sub.GetName(), fmt.Sprintf("no operators found from catalog %s in namespace %s referenced by subscription %s", sub.Spec.CatalogSource, sub.Spec.CatalogSourceNamespace, sub.GetName())) case npkg == 0: - si = NewInvalidSubscriptionInstallable(sub.GetName(), fmt.Sprintf("no operators found in package %s in the catalog referenced by subscription %s", sub.Spec.Package, sub.GetName())) + si = NewInvalidSubscriptionVariable(sub.GetName(), fmt.Sprintf("no operators found in package %s in the catalog referenced by subscription %s", sub.Spec.Package, sub.GetName())) case nch == 0: - si = NewInvalidSubscriptionInstallable(sub.GetName(), fmt.Sprintf("no operators found in channel %s of package %s in the catalog referenced by subscription %s", sub.Spec.Channel, sub.Spec.Package, sub.GetName())) + si = NewInvalidSubscriptionVariable(sub.GetName(), fmt.Sprintf("no operators found in channel %s of package %s in the catalog referenced by subscription %s", sub.Spec.Channel, sub.Spec.Package, sub.GetName())) case ncsv == 0: - si = NewInvalidSubscriptionInstallable(sub.GetName(), fmt.Sprintf("no operators found with name %s in channel %s of package %s in the catalog referenced by subscription %s", sub.Spec.StartingCSV, sub.Spec.Channel, sub.Spec.Package, sub.GetName())) + si = NewInvalidSubscriptionVariable(sub.GetName(), fmt.Sprintf("no operators found with name %s in channel %s of package %s in the catalog referenced by subscription %s", sub.Spec.StartingCSV, sub.Spec.Channel, sub.Spec.Package, sub.GetName())) } if si != nil { - installables[si.Identifier()] = si - return installables, nil + variables[si.Identifier()] = si + return variables, nil } } @@ -305,11 +305,11 @@ func (r *SatResolver) getSubscriptionInstallables(sub *v1alpha1.Subscription, cu } } - candidates := make([]*BundleInstallable, 0) + candidates := make([]*BundleVariable, 0) for _, o := range cache.Filter(sortedBundles, channelPredicates...) { predicates := append(cachePredicates, cache.CSVNamePredicate(o.Name)) stack := namespacedCache.Catalog(catalog).Find(predicates...) - id, installable, err := r.getBundleInstallables(sub.Namespace, stack, namespacedCache, visited) + id, variable, err := r.getBundleVariables(sub.Namespace, stack, namespacedCache, visited) if err != nil { return nil, err } @@ -317,11 +317,11 @@ func (r *SatResolver) getSubscriptionInstallables(sub *v1alpha1.Subscription, cu return nil, fmt.Errorf("could not find any potential bundles for subscription: %s", sub.Spec.Package) } - for _, i := range installable { + for _, i := range variable { if _, ok := id[i.Identifier()]; ok { candidates = append(candidates, i) } - installables[i.Identifier()] = i + variables[i.Identifier()] = i } } @@ -347,17 +347,17 @@ func (r *SatResolver) getSubscriptionInstallables(sub *v1alpha1.Subscription, cu } // all candidates added as options for this constraint - subInstallable := NewSubscriptionInstallable(sub.GetName(), depIds) - installables[subInstallable.Identifier()] = subInstallable + subVariable := NewSubscriptionVariable(sub.GetName(), depIds) + variables[subVariable.Identifier()] = subVariable - return installables, nil + return variables, nil } -func (r *SatResolver) getBundleInstallables(preferredNamespace string, bundleStack []*cache.Entry, namespacedCache cache.MultiCatalogOperatorFinder, visited map[*cache.Entry]*BundleInstallable) (map[solver.Identifier]struct{}, map[solver.Identifier]*BundleInstallable, error) { +func (r *SatResolver) getBundleVariables(preferredNamespace string, bundleStack []*cache.Entry, namespacedCache cache.MultiCatalogOperatorFinder, visited map[*cache.Entry]*BundleVariable) (map[solver.Identifier]struct{}, map[solver.Identifier]*BundleVariable, error) { errs := make([]error, 0) - installables := make(map[solver.Identifier]*BundleInstallable) // all installables, including dependencies + variables := make(map[solver.Identifier]*BundleVariable) // all variables, including dependencies - // track the first layer of installable ids + // track the first layer of variable ids var initial = make(map[*cache.Entry]struct{}) for _, o := range bundleStack { initial[o] = struct{}{} @@ -372,17 +372,17 @@ func (r *SatResolver) getBundleInstallables(preferredNamespace string, bundleSta bundleStack = bundleStack[:len(bundleStack)-1] if b, ok := visited[bundle]; ok { - installables[b.identifier] = b + variables[b.identifier] = b continue } - bundleInstallable, err := r.newBundleInstallableFromEntry(bundle) + bundleVariable, err := r.newBundleVariableFromEntry(bundle) if err != nil { errs = append(errs, err) continue } - visited[bundle] = bundleInstallable + visited[bundle] = bundleVariable dependencyPredicates, err := r.pc.convertDependencyProperties(bundle.Properties) if err != nil { @@ -431,34 +431,34 @@ func (r *SatResolver) getBundleInstallables(preferredNamespace string, bundleSta // (after sorting) to remove all bundles that // don't satisfy the dependency. for _, b := range cache.Filter(sortedBundles, d) { - i, err := r.newBundleInstallableFromEntry(b) + i, err := r.newBundleVariableFromEntry(b) if err != nil { errs = append(errs, err) continue } - installables[i.Identifier()] = i + variables[i.Identifier()] = i bundleDependencies = append(bundleDependencies, i.Identifier()) bundleStack = append(bundleStack, b) } - bundleInstallable.AddConstraint(PrettyConstraint( + bundleVariable.AddConstraint(PrettyConstraint( solver.Dependency(bundleDependencies...), fmt.Sprintf("bundle %s requires an operator %s", bundle.Name, d.String()), )) } - installables[bundleInstallable.Identifier()] = bundleInstallable + variables[bundleVariable.Identifier()] = bundleVariable } if len(errs) > 0 { return nil, nil, utilerrors.NewAggregate(errs) } - ids := make(map[solver.Identifier]struct{}) // immediate installables found via predicates + ids := make(map[solver.Identifier]struct{}) // immediate variables found via predicates for o := range initial { ids[visited[o].Identifier()] = struct{}{} } - return ids, installables, nil + return ids, variables, nil } func (r *SatResolver) inferProperties(csv *v1alpha1.ClusterServiceVersion, subs []*v1alpha1.Subscription) ([]*api.Property, error) { @@ -571,16 +571,16 @@ func (r *SatResolver) newSnapshotForNamespace(namespace string, subs []*v1alpha1 return &cache.Snapshot{Entries: standaloneOperators}, nil } -func (r *SatResolver) addInvariants(namespacedCache cache.MultiCatalogOperatorFinder, installables map[solver.Identifier]solver.Installable) { +func (r *SatResolver) addInvariants(namespacedCache cache.MultiCatalogOperatorFinder, variables map[solver.Identifier]solver.Variable) { // no two operators may provide the same GVK or Package in a namespace - gvkConflictToInstallable := make(map[opregistry.GVKProperty][]solver.Identifier) - packageConflictToInstallable := make(map[string][]solver.Identifier) - for _, installable := range installables { - bundleInstallable, ok := installable.(*BundleInstallable) + gvkConflictToVariable := make(map[opregistry.GVKProperty][]solver.Identifier) + packageConflictToVariable := make(map[string][]solver.Identifier) + for _, variable := range variables { + bundleVariable, ok := variable.(*BundleVariable) if !ok { continue } - csvName, channel, catalog, err := bundleInstallable.BundleSourceInfo() + csvName, channel, catalog, err := bundleVariable.BundleSourceInfo() if err != nil { continue } @@ -600,7 +600,7 @@ func (r *SatResolver) addInvariants(namespacedCache cache.MultiCatalogOperatorFi if err != nil { continue } - gvkConflictToInstallable[prop] = append(gvkConflictToInstallable[prop], installable.Identifier()) + gvkConflictToVariable[prop] = append(gvkConflictToVariable[prop], variable.Identifier()) } // cannot have the same package @@ -613,18 +613,18 @@ func (r *SatResolver) addInvariants(namespacedCache cache.MultiCatalogOperatorFi if err != nil { continue } - packageConflictToInstallable[prop.PackageName] = append(packageConflictToInstallable[prop.PackageName], installable.Identifier()) + packageConflictToVariable[prop.PackageName] = append(packageConflictToVariable[prop.PackageName], variable.Identifier()) } } - for gvk, is := range gvkConflictToInstallable { - s := NewSingleAPIProviderInstallable(gvk.Group, gvk.Version, gvk.Kind, is) - installables[s.Identifier()] = s + for gvk, is := range gvkConflictToVariable { + s := NewSingleAPIProviderVariable(gvk.Group, gvk.Version, gvk.Kind, is) + variables[s.Identifier()] = s } - for pkg, is := range packageConflictToInstallable { - s := NewSinglePackageInstanceInstallable(pkg, is) - installables[s.Identifier()] = s + for pkg, is := range packageConflictToVariable { + s := NewSinglePackageInstanceVariable(pkg, is) + variables[s.Identifier()] = s } } diff --git a/pkg/controller/registry/resolver/solver/bench_test.go b/pkg/controller/registry/resolver/solver/bench_test.go index 72f586e1e0..0296b85f10 100644 --- a/pkg/controller/registry/resolver/solver/bench_test.go +++ b/pkg/controller/registry/resolver/solver/bench_test.go @@ -7,7 +7,7 @@ import ( "testing" ) -var BenchmarkInput = func() []Installable { +var BenchmarkInput = func() []Variable { const ( length = 256 seed = 9 @@ -22,7 +22,7 @@ var BenchmarkInput = func() []Installable { return Identifier(strconv.Itoa(i)) } - installable := func(i int) TestInstallable { + variable := func(i int) TestVariable { var c []Constraint if rand.Float64() < pMandatory { c = append(c, Mandatory()) @@ -49,16 +49,16 @@ var BenchmarkInput = func() []Installable { c = append(c, Conflict(id(y))) } } - return TestInstallable{ + return TestVariable{ identifier: id(i), constraints: c, } } rand.Seed(seed) - result := make([]Installable, length) + result := make([]Variable, length) for i := range result { - result[i] = installable(i) + result[i] = variable(i) } return result }() diff --git a/pkg/controller/registry/resolver/solver/constraints.go b/pkg/controller/registry/resolver/solver/constraints.go index 785ee409fd..b2b0b7792a 100644 --- a/pkg/controller/registry/resolver/solver/constraints.go +++ b/pkg/controller/registry/resolver/solver/constraints.go @@ -9,7 +9,7 @@ import ( ) // Constraint implementations limit the circumstances under which a -// particular Installable can appear in a solution. +// particular Variable can appear in a solution. type Constraint interface { String(subject Identifier) string apply(c *logic.C, lm *litMapping, subject Identifier) z.Lit @@ -39,16 +39,16 @@ func (zeroConstraint) anchor() bool { } // AppliedConstraint values compose a single Constraint with the -// Installable it applies to. +// Variable it applies to. type AppliedConstraint struct { - Installable Installable - Constraint Constraint + Variable Variable + Constraint Constraint } // String implements fmt.Stringer and returns a human-readable message // representing the receiver. func (a AppliedConstraint) String() string { - return a.Constraint.String(a.Installable.Identifier()) + return a.Constraint.String(a.Variable.Identifier()) } type mandatory struct{} @@ -70,7 +70,7 @@ func (constraint mandatory) anchor() bool { } // Mandatory returns a Constraint that will permit only solutions that -// contain a particular Installable. +// contain a particular Variable. func Mandatory() Constraint { return mandatory{} } @@ -94,8 +94,8 @@ func (constraint prohibited) anchor() bool { } // Prohibited returns a Constraint that will reject any solution that -// contains a particular Installable. Callers may also decide to omit -// an Installable from input to Solve rather than apply such a +// contains a particular Variable. Callers may also decide to omit +// an Variable from input to Solve rather than apply such a // Constraint. func Prohibited() Constraint { return prohibited{} @@ -131,8 +131,8 @@ func (constraint dependency) anchor() bool { } // Dependency returns a Constraint that will only permit solutions -// containing a given Installable on the condition that at least one -// of the Installables identified by the given Identifiers also +// containing a given Variable on the condition that at least one +// of the Variables identified by the given Identifiers also // appears in the solution. Identifiers appearing earlier in the // argument list have higher preference than those appearing later. func Dependency(ids ...Identifier) Constraint { @@ -158,7 +158,7 @@ func (constraint conflict) anchor() bool { } // Conflict returns a Constraint that will permit solutions containing -// either the constrained Installable, the Installable identified by +// either the constrained Variable, the Variable identified by // the given Identifier, or neither, but not both. func Conflict(id Identifier) Constraint { return conflict(id) @@ -194,7 +194,7 @@ func (constraint leq) anchor() bool { } // AtMost returns a Constraint that forbids solutions that contain -// more than n of the Installables identified by the given +// more than n of the Variables identified by the given // Identifiers. func AtMost(n int, ids ...Identifier) Constraint { return leq{ diff --git a/pkg/controller/registry/resolver/solver/doc.go b/pkg/controller/registry/resolver/solver/doc.go new file mode 100644 index 0000000000..12f274546c --- /dev/null +++ b/pkg/controller/registry/resolver/solver/doc.go @@ -0,0 +1,3 @@ +// Package solver implements a general-purpose solver for boolean +// constraint satisfiability problems. +package solver diff --git a/pkg/controller/registry/resolver/solver/lit_mapping.go b/pkg/controller/registry/resolver/solver/lit_mapping.go index ff15346832..eb7a739aca 100644 --- a/pkg/controller/registry/resolver/solver/lit_mapping.go +++ b/pkg/controller/registry/resolver/solver/lit_mapping.go @@ -22,43 +22,43 @@ func (inconsistentLitMapping) Error() string { } // litMapping performs translation between the input and output types of -// Solve (Constraints, Installables, etc.) and the variables that +// Solve (Constraints, Variables, etc.) and the variables that // appear in the SAT formula. type litMapping struct { - inorder []Installable - installables map[z.Lit]Installable - lits map[Identifier]z.Lit - constraints map[z.Lit]AppliedConstraint - c *logic.C - errs inconsistentLitMapping + inorder []Variable + variables map[z.Lit]Variable + lits map[Identifier]z.Lit + constraints map[z.Lit]AppliedConstraint + c *logic.C + errs inconsistentLitMapping } // newLitMapping returns a new litMapping with its state initialized based on -// the provided slice of Installables. This includes construction of -// the translation tables between Installables/Constraints and the +// the provided slice of Variables. This includes construction of +// the translation tables between Variables/Constraints and the // inputs to the underlying solver. -func newLitMapping(installables []Installable) (*litMapping, error) { +func newLitMapping(variables []Variable) (*litMapping, error) { d := litMapping{ - inorder: installables, - installables: make(map[z.Lit]Installable, len(installables)), - lits: make(map[Identifier]z.Lit, len(installables)), - constraints: make(map[z.Lit]AppliedConstraint), - c: logic.NewCCap(len(installables)), + inorder: variables, + variables: make(map[z.Lit]Variable, len(variables)), + lits: make(map[Identifier]z.Lit, len(variables)), + constraints: make(map[z.Lit]AppliedConstraint), + c: logic.NewCCap(len(variables)), } // First pass to assign lits: - for _, installable := range installables { + for _, variable := range variables { im := d.c.Lit() - if _, ok := d.lits[installable.Identifier()]; ok { - return nil, DuplicateIdentifier(installable.Identifier()) + if _, ok := d.lits[variable.Identifier()]; ok { + return nil, DuplicateIdentifier(variable.Identifier()) } - d.lits[installable.Identifier()] = im - d.installables[im] = installable + d.lits[variable.Identifier()] = im + d.variables[im] = variable } - for _, installable := range installables { - for _, constraint := range installable.Constraints() { - m := constraint.apply(d.c, &d, installable.Identifier()) + for _, variable := range variables { + for _, constraint := range variable.Constraints() { + m := constraint.apply(d.c, &d, variable.Identifier()) if m == z.LitNull { // This constraint doesn't have a // useful representation in the SAT @@ -67,8 +67,8 @@ func newLitMapping(installables []Installable) (*litMapping, error) { } d.constraints[m] = AppliedConstraint{ - Installable: installable, - Constraint: constraint, + Variable: variable, + Constraint: constraint, } } } @@ -76,26 +76,26 @@ func newLitMapping(installables []Installable) (*litMapping, error) { return &d, nil } -// LitOf returns the positive literal corresponding to the Installable +// LitOf returns the positive literal corresponding to the Variable // with the given Identifier. func (d *litMapping) LitOf(id Identifier) z.Lit { m, ok := d.lits[id] if ok { return m } - d.errs = append(d.errs, fmt.Errorf("installable %q referenced but not provided", id)) + d.errs = append(d.errs, fmt.Errorf("variable %q referenced but not provided", id)) return z.LitNull } -// InstallableOf returns the Installable corresponding to the provided -// literal, or a zeroInstallable if no such Installable exists. -func (d *litMapping) InstallableOf(m z.Lit) Installable { - i, ok := d.installables[m] +// VariableOf returns the Variable corresponding to the provided +// literal, or a zeroVariable if no such Variable exists. +func (d *litMapping) VariableOf(m z.Lit) Variable { + i, ok := d.variables[m] if ok { return i } - d.errs = append(d.errs, fmt.Errorf("no installable corresponding to %s", m)) - return zeroInstallable{} + d.errs = append(d.errs, fmt.Errorf("no variable corresponding to %s", m)) + return zeroVariable{} } // ConstraintOf returns the constraint application corresponding to @@ -107,8 +107,8 @@ func (d *litMapping) ConstraintOf(m z.Lit) AppliedConstraint { } d.errs = append(d.errs, fmt.Errorf("no constraint corresponding to %s", m)) return AppliedConstraint{ - Installable: zeroInstallable{}, - Constraint: zeroConstraint{}, + Variable: zeroVariable{}, + Constraint: zeroConstraint{}, } } @@ -158,14 +158,14 @@ func (d *litMapping) CardinalityConstrainer(g inter.Adder, ms []z.Lit) *logic.Ca } // AnchorIdentifiers returns a slice containing the Identifiers of -// every Installable with at least one "anchor" constraint, in the +// every Variable with at least one "anchor" constraint, in the // order they appear in the input. func (d *litMapping) AnchorIdentifiers() []Identifier { var ids []Identifier - for _, installable := range d.inorder { - for _, constraint := range installable.Constraints() { + for _, variable := range d.inorder { + for _, constraint := range variable.Constraints() { if constraint.anchor() { - ids = append(ids, installable.Identifier()) + ids = append(ids, variable.Identifier()) break } } @@ -173,8 +173,8 @@ func (d *litMapping) AnchorIdentifiers() []Identifier { return ids } -func (d *litMapping) Installables(g inter.S) []Installable { - var result []Installable +func (d *litMapping) Variables(g inter.S) []Variable { + var result []Variable for _, i := range d.inorder { if g.Value(d.LitOf(i.Identifier())) { result = append(result, i) diff --git a/pkg/controller/registry/resolver/solver/search.go b/pkg/controller/registry/resolver/solver/search.go index 363595eca0..523b311a76 100644 --- a/pkg/controller/registry/resolver/solver/search.go +++ b/pkg/controller/registry/resolver/solver/search.go @@ -56,8 +56,8 @@ func (h *search) PushGuess() { return } - installable := h.lits.InstallableOf(g.m) - for _, constraint := range installable.Constraints() { + variable := h.lits.VariableOf(g.m) + for _, constraint := range variable.Constraints() { var ms []z.Lit for _, dependency := range constraint.order() { ms = append(ms, h.lits.LitOf(dependency)) @@ -202,11 +202,11 @@ func (h *search) Do(ctx context.Context, anchors []z.Lit) (int, []z.Lit, map[z.L return result, lits, set } -func (h *search) Installables() []Installable { - result := make([]Installable, 0, len(h.guesses)) +func (h *search) Variables() []Variable { + result := make([]Variable, 0, len(h.guesses)) for _, g := range h.guesses { if g.m != z.LitNull { - result = append(result, h.lits.InstallableOf(g.candidates[g.index])) + result = append(result, h.lits.VariableOf(g.candidates[g.index])) } } return result diff --git a/pkg/controller/registry/resolver/solver/search_test.go b/pkg/controller/registry/resolver/solver/search_test.go index 5b00bcfd2c..fd9221a6f7 100644 --- a/pkg/controller/registry/resolver/solver/search_test.go +++ b/pkg/controller/registry/resolver/solver/search_test.go @@ -31,7 +31,7 @@ func (c *TestScopeCounter) Untest() (result int) { func TestSearch(t *testing.T) { type tc struct { Name string - Installables []Installable + Variables []Variable TestReturns []int UntestReturns []int Result int @@ -41,10 +41,10 @@ func TestSearch(t *testing.T) { for _, tt := range []tc{ { Name: "children popped from back of deque when guess popped", - Installables: []Installable{ - installable("a", Mandatory(), Dependency("c")), - installable("b", Mandatory()), - installable("c"), + Variables: []Variable{ + variable("a", Mandatory(), Dependency("c")), + variable("b", Mandatory()), + variable("c"), }, TestReturns: []int{0, -1}, UntestReturns: []int{-1, -1}, @@ -53,11 +53,11 @@ func TestSearch(t *testing.T) { }, { Name: "candidates exhausted", - Installables: []Installable{ - installable("a", Mandatory(), Dependency("x")), - installable("b", Mandatory(), Dependency("y")), - installable("x"), - installable("y"), + Variables: []Variable{ + variable("a", Mandatory(), Dependency("x")), + variable("b", Mandatory(), Dependency("y")), + variable("x"), + variable("y"), }, TestReturns: []int{0, 0, -1, 1}, UntestReturns: []int{0}, @@ -79,7 +79,7 @@ func TestSearch(t *testing.T) { var depth int counter := &TestScopeCounter{depth: &depth, S: &s} - lits, err := newLitMapping(tt.Installables) + lits, err := newLitMapping(tt.Variables) assert.NoError(err) h := search{ s: counter, @@ -97,7 +97,7 @@ func TestSearch(t *testing.T) { assert.Equal(tt.Result, result) var ids []Identifier for _, m := range ms { - ids = append(ids, lits.InstallableOf(m).Identifier()) + ids = append(ids, lits.VariableOf(m).Identifier()) } assert.Equal(tt.Assumptions, ids) assert.Equal(0, depth) diff --git a/pkg/controller/registry/resolver/solver/solve.go b/pkg/controller/registry/resolver/solver/solve.go index 873f17697f..a323f4551b 100644 --- a/pkg/controller/registry/resolver/solver/solve.go +++ b/pkg/controller/registry/resolver/solver/solve.go @@ -30,7 +30,7 @@ func (e NotSatisfiable) Error() string { } type Solver interface { - Solve(context.Context) ([]Installable, error) + Solve(context.Context) ([]Variable, error) } type solver struct { @@ -46,11 +46,11 @@ const ( unknown = 0 ) -// Solve takes a slice containing all Installables and returns a slice -// containing only those Installables that were selected for +// Solve takes a slice containing all Variables and returns a slice +// containing only those Variables that were selected for // installation. If no solution is possible, or if the provided // Context times out or is cancelled, an error is returned. -func (s *solver) Solve(ctx context.Context) (result []Installable, err error) { +func (s *solver) Solve(ctx context.Context) (result []Variable, err error) { defer func() { // This likely indicates a bug, so discard whatever // return values were produced. @@ -63,7 +63,7 @@ func (s *solver) Solve(ctx context.Context) (result []Installable, err error) { // teach all constraints to the solver s.litMap.AddConstraints(s.g) - // collect literals of all mandatory installables to assume as a baseline + // collect literals of all mandatory variables to assume as a baseline var assumptions []z.Lit for _, anchor := range s.litMap.AnchorIdentifiers() { assumptions = append(assumptions, s.litMap.LitOf(anchor)) @@ -104,7 +104,7 @@ func (s *solver) Solve(ctx context.Context) (result []Installable, err error) { for w := 0; w <= cs.N(); w++ { s.g.Assume(cs.Leq(w)) if s.g.Solve() == satisfiable { - return s.litMap.Installables(s.g), nil + return s.litMap.Variables(s.g), nil } } // Something is wrong if we can't find a model anymore @@ -129,7 +129,7 @@ func New(options ...Option) (Solver, error) { type Option func(s *solver) error -func WithInput(input []Installable) Option { +func WithInput(input []Variable) Option { return func(s *solver) error { var err error s.litMap, err = newLitMapping(input) diff --git a/pkg/controller/registry/resolver/solver/solve_test.go b/pkg/controller/registry/resolver/solver/solve_test.go index f274518be0..4e836fea2c 100644 --- a/pkg/controller/registry/resolver/solver/solve_test.go +++ b/pkg/controller/registry/resolver/solver/solve_test.go @@ -11,25 +11,25 @@ import ( "github.com/stretchr/testify/assert" ) -type TestInstallable struct { +type TestVariable struct { identifier Identifier constraints []Constraint } -func (i TestInstallable) Identifier() Identifier { +func (i TestVariable) Identifier() Identifier { return i.identifier } -func (i TestInstallable) Constraints() []Constraint { +func (i TestVariable) Constraints() []Constraint { return i.constraints } -func (i TestInstallable) GoString() string { +func (i TestVariable) GoString() string { return fmt.Sprintf("%q", i.Identifier()) } -func installable(id Identifier, constraints ...Constraint) Installable { - return TestInstallable{ +func variable(id Identifier, constraints ...Constraint) Variable { + return TestVariable{ identifier: id, constraints: constraints, } @@ -56,8 +56,8 @@ func TestNotSatisfiableError(t *testing.T) { Name: "single failure", Error: NotSatisfiable{ AppliedConstraint{ - Installable: installable("a", Mandatory()), - Constraint: Mandatory(), + Variable: variable("a", Mandatory()), + Constraint: Mandatory(), }, }, String: fmt.Sprintf("constraints not satisfiable: %s", @@ -67,12 +67,12 @@ func TestNotSatisfiableError(t *testing.T) { Name: "multiple failures", Error: NotSatisfiable{ AppliedConstraint{ - Installable: installable("a", Mandatory()), - Constraint: Mandatory(), + Variable: variable("a", Mandatory()), + Constraint: Mandatory(), }, AppliedConstraint{ - Installable: installable("b", Prohibited()), - Constraint: Prohibited(), + Variable: variable("b", Prohibited()), + Constraint: Prohibited(), }, }, String: fmt.Sprintf("constraints not satisfiable: %s, %s", @@ -87,210 +87,210 @@ func TestNotSatisfiableError(t *testing.T) { func TestSolve(t *testing.T) { type tc struct { - Name string - Installables []Installable - Installed []Identifier - Error error + Name string + Variables []Variable + Installed []Identifier + Error error } for _, tt := range []tc{ { - Name: "no installables", + Name: "no variables", }, { - Name: "unnecessary installable is not installed", - Installables: []Installable{installable("a")}, + Name: "unnecessary variable is not installed", + Variables: []Variable{variable("a")}, }, { - Name: "single mandatory installable is installed", - Installables: []Installable{installable("a", Mandatory())}, - Installed: []Identifier{"a"}, + Name: "single mandatory variable is installed", + Variables: []Variable{variable("a", Mandatory())}, + Installed: []Identifier{"a"}, }, { - Name: "both mandatory and prohibited produce error", - Installables: []Installable{installable("a", Mandatory(), Prohibited())}, + Name: "both mandatory and prohibited produce error", + Variables: []Variable{variable("a", Mandatory(), Prohibited())}, Error: NotSatisfiable{ { - Installable: installable("a", Mandatory(), Prohibited()), - Constraint: Mandatory(), + Variable: variable("a", Mandatory(), Prohibited()), + Constraint: Mandatory(), }, { - Installable: installable("a", Mandatory(), Prohibited()), - Constraint: Prohibited(), + Variable: variable("a", Mandatory(), Prohibited()), + Constraint: Prohibited(), }, }, }, { Name: "dependency is installed", - Installables: []Installable{ - installable("a"), - installable("b", Mandatory(), Dependency("a")), + Variables: []Variable{ + variable("a"), + variable("b", Mandatory(), Dependency("a")), }, Installed: []Identifier{"a", "b"}, }, { Name: "transitive dependency is installed", - Installables: []Installable{ - installable("a"), - installable("b", Dependency("a")), - installable("c", Mandatory(), Dependency("b")), + Variables: []Variable{ + variable("a"), + variable("b", Dependency("a")), + variable("c", Mandatory(), Dependency("b")), }, Installed: []Identifier{"a", "b", "c"}, }, { Name: "both dependencies are installed", - Installables: []Installable{ - installable("a"), - installable("b"), - installable("c", Mandatory(), Dependency("a"), Dependency("b")), + Variables: []Variable{ + variable("a"), + variable("b"), + variable("c", Mandatory(), Dependency("a"), Dependency("b")), }, Installed: []Identifier{"a", "b", "c"}, }, { Name: "solution with first dependency is selected", - Installables: []Installable{ - installable("a"), - installable("b", Conflict("a")), - installable("c", Mandatory(), Dependency("a", "b")), + Variables: []Variable{ + variable("a"), + variable("b", Conflict("a")), + variable("c", Mandatory(), Dependency("a", "b")), }, Installed: []Identifier{"a", "c"}, }, { Name: "solution with only first dependency is selected", - Installables: []Installable{ - installable("a"), - installable("b"), - installable("c", Mandatory(), Dependency("a", "b")), + Variables: []Variable{ + variable("a"), + variable("b"), + variable("c", Mandatory(), Dependency("a", "b")), }, Installed: []Identifier{"a", "c"}, }, { Name: "solution with first dependency is selected (reverse)", - Installables: []Installable{ - installable("a"), - installable("b", Conflict("a")), - installable("c", Mandatory(), Dependency("b", "a")), + Variables: []Variable{ + variable("a"), + variable("b", Conflict("a")), + variable("c", Mandatory(), Dependency("b", "a")), }, Installed: []Identifier{"b", "c"}, }, { Name: "two mandatory but conflicting packages", - Installables: []Installable{ - installable("a", Mandatory()), - installable("b", Mandatory(), Conflict("a")), + Variables: []Variable{ + variable("a", Mandatory()), + variable("b", Mandatory(), Conflict("a")), }, Error: NotSatisfiable{ { - Installable: installable("a", Mandatory()), - Constraint: Mandatory(), + Variable: variable("a", Mandatory()), + Constraint: Mandatory(), }, { - Installable: installable("b", Mandatory(), Conflict("a")), - Constraint: Mandatory(), + Variable: variable("b", Mandatory(), Conflict("a")), + Constraint: Mandatory(), }, { - Installable: installable("b", Mandatory(), Conflict("a")), - Constraint: Conflict("a"), + Variable: variable("b", Mandatory(), Conflict("a")), + Constraint: Conflict("a"), }, }, }, { Name: "irrelevant dependencies don't influence search order", - Installables: []Installable{ - installable("a", Dependency("x", "y")), - installable("b", Mandatory(), Dependency("y", "x")), - installable("x"), - installable("y"), + Variables: []Variable{ + variable("a", Dependency("x", "y")), + variable("b", Mandatory(), Dependency("y", "x")), + variable("x"), + variable("y"), }, Installed: []Identifier{"b", "y"}, }, { Name: "cardinality constraint prevents resolution", - Installables: []Installable{ - installable("a", Mandatory(), Dependency("x", "y"), AtMost(1, "x", "y")), - installable("x", Mandatory()), - installable("y", Mandatory()), + Variables: []Variable{ + variable("a", Mandatory(), Dependency("x", "y"), AtMost(1, "x", "y")), + variable("x", Mandatory()), + variable("y", Mandatory()), }, Error: NotSatisfiable{ { - Installable: installable("a", Mandatory(), Dependency("x", "y"), AtMost(1, "x", "y")), - Constraint: AtMost(1, "x", "y"), + Variable: variable("a", Mandatory(), Dependency("x", "y"), AtMost(1, "x", "y")), + Constraint: AtMost(1, "x", "y"), }, { - Installable: installable("x", Mandatory()), - Constraint: Mandatory(), + Variable: variable("x", Mandatory()), + Constraint: Mandatory(), }, { - Installable: installable("y", Mandatory()), - Constraint: Mandatory(), + Variable: variable("y", Mandatory()), + Constraint: Mandatory(), }, }, }, { Name: "cardinality constraint forces alternative", - Installables: []Installable{ - installable("a", Mandatory(), Dependency("x", "y"), AtMost(1, "x", "y")), - installable("b", Mandatory(), Dependency("y")), - installable("x"), - installable("y"), + Variables: []Variable{ + variable("a", Mandatory(), Dependency("x", "y"), AtMost(1, "x", "y")), + variable("b", Mandatory(), Dependency("y")), + variable("x"), + variable("y"), }, Installed: []Identifier{"a", "b", "y"}, }, { - Name: "two dependencies satisfied by one installable", - Installables: []Installable{ - installable("a", Mandatory(), Dependency("y")), - installable("b", Mandatory(), Dependency("x", "y")), - installable("x"), - installable("y"), + Name: "two dependencies satisfied by one variable", + Variables: []Variable{ + variable("a", Mandatory(), Dependency("y")), + variable("b", Mandatory(), Dependency("x", "y")), + variable("x"), + variable("y"), }, Installed: []Identifier{"a", "b", "y"}, }, { - Name: "foo two dependencies satisfied by one installable", - Installables: []Installable{ - installable("a", Mandatory(), Dependency("y", "z", "m")), - installable("b", Mandatory(), Dependency("x", "y")), - installable("x"), - installable("y"), - installable("z"), - installable("m"), + Name: "foo two dependencies satisfied by one variable", + Variables: []Variable{ + variable("a", Mandatory(), Dependency("y", "z", "m")), + variable("b", Mandatory(), Dependency("x", "y")), + variable("x"), + variable("y"), + variable("z"), + variable("m"), }, Installed: []Identifier{"a", "b", "y"}, }, { Name: "result size larger than minimum due to preference", - Installables: []Installable{ - installable("a", Mandatory(), Dependency("x", "y")), - installable("b", Mandatory(), Dependency("y")), - installable("x"), - installable("y"), + Variables: []Variable{ + variable("a", Mandatory(), Dependency("x", "y")), + variable("b", Mandatory(), Dependency("y")), + variable("x"), + variable("y"), }, Installed: []Identifier{"a", "b", "x", "y"}, }, { Name: "only the least preferable choice is acceptable", - Installables: []Installable{ - installable("a", Mandatory(), Dependency("a1", "a2")), - installable("a1", Conflict("c1"), Conflict("c2")), - installable("a2", Conflict("c1")), - installable("b", Mandatory(), Dependency("b1", "b2")), - installable("b1", Conflict("c1"), Conflict("c2")), - installable("b2", Conflict("c1")), - installable("c", Mandatory(), Dependency("c1", "c2")), - installable("c1"), - installable("c2"), + Variables: []Variable{ + variable("a", Mandatory(), Dependency("a1", "a2")), + variable("a1", Conflict("c1"), Conflict("c2")), + variable("a2", Conflict("c1")), + variable("b", Mandatory(), Dependency("b1", "b2")), + variable("b1", Conflict("c1"), Conflict("c2")), + variable("b2", Conflict("c1")), + variable("c", Mandatory(), Dependency("c1", "c2")), + variable("c1"), + variable("c2"), }, Installed: []Identifier{"a", "a2", "b", "b2", "c", "c2"}, }, { - Name: "preferences respected with multiple dependencies per installable", - Installables: []Installable{ - installable("a", Mandatory(), Dependency("x1", "x2"), Dependency("y1", "y2")), - installable("x1"), - installable("x2"), - installable("y1"), - installable("y2"), + Name: "preferences respected with multiple dependencies per variable", + Variables: []Variable{ + variable("a", Mandatory(), Dependency("x1", "x2"), Dependency("y1", "y2")), + variable("x1"), + variable("x2"), + variable("y1"), + variable("y2"), }, Installed: []Identifier{"a", "x1", "y1"}, }, @@ -299,7 +299,7 @@ func TestSolve(t *testing.T) { assert := assert.New(t) var traces bytes.Buffer - s, err := New(WithInput(tt.Installables), WithTracer(LoggingTracer{Writer: &traces})) + s, err := New(WithInput(tt.Variables), WithTracer(LoggingTracer{Writer: &traces})) if err != nil { t.Fatalf("failed to initialize solver: %s", err) } @@ -314,23 +314,23 @@ func TestSolve(t *testing.T) { // Failed constraints are sorted in lexically // increasing order of the identifier of the - // constraint's installable, with ties broken + // constraint's variable, with ties broken // in favor of the constraint that appears - // earliest in the installable's list of + // earliest in the variable's list of // constraints. if ns, ok := err.(NotSatisfiable); ok { sort.SliceStable(ns, func(i, j int) bool { - if ns[i].Installable.Identifier() != ns[j].Installable.Identifier() { - return ns[i].Installable.Identifier() < ns[j].Installable.Identifier() + if ns[i].Variable.Identifier() != ns[j].Variable.Identifier() { + return ns[i].Variable.Identifier() < ns[j].Variable.Identifier() } var x, y int - for ii, c := range ns[i].Installable.Constraints() { + for ii, c := range ns[i].Variable.Constraints() { if reflect.DeepEqual(c, ns[i].Constraint) { x = ii break } } - for ij, c := range ns[j].Installable.Constraints() { + for ij, c := range ns[j].Variable.Constraints() { if reflect.DeepEqual(c, ns[j].Constraint) { y = ij break @@ -341,8 +341,8 @@ func TestSolve(t *testing.T) { } var ids []Identifier - for _, installable := range installed { - ids = append(ids, installable.Identifier()) + for _, variable := range installed { + ids = append(ids, variable.Identifier()) } assert.Equal(tt.Installed, ids) assert.Equal(tt.Error, err) @@ -355,9 +355,9 @@ func TestSolve(t *testing.T) { } func TestDuplicateIdentifier(t *testing.T) { - _, err := New(WithInput([]Installable{ - installable("a"), - installable("a"), + _, err := New(WithInput([]Variable{ + variable("a"), + variable("a"), })) assert.Equal(t, DuplicateIdentifier("a"), err) } diff --git a/pkg/controller/registry/resolver/solver/tracer.go b/pkg/controller/registry/resolver/solver/tracer.go index 37f2c3f4fc..b103536add 100644 --- a/pkg/controller/registry/resolver/solver/tracer.go +++ b/pkg/controller/registry/resolver/solver/tracer.go @@ -6,7 +6,7 @@ import ( ) type SearchPosition interface { - Installables() []Installable + Variables() []Variable Conflicts() []AppliedConstraint } @@ -25,7 +25,7 @@ type LoggingTracer struct { func (t LoggingTracer) Trace(p SearchPosition) { fmt.Fprintf(t.Writer, "---\nAssumptions:\n") - for _, i := range p.Installables() { + for _, i := range p.Variables() { fmt.Fprintf(t.Writer, "- %s\n", i.Identifier()) } fmt.Fprintf(t.Writer, "Conflicts:\n") diff --git a/pkg/controller/registry/resolver/solver/installable.go b/pkg/controller/registry/resolver/solver/variable.go similarity index 53% rename from pkg/controller/registry/resolver/solver/installable.go rename to pkg/controller/registry/resolver/solver/variable.go index 8382ca0733..32afab7592 100644 --- a/pkg/controller/registry/resolver/solver/installable.go +++ b/pkg/controller/registry/resolver/solver/variable.go @@ -1,6 +1,6 @@ package solver -// Identifier values uniquely identify particular Installables within +// Identifier values uniquely identify particular Variables within // the input to a single call to Solve. type Identifier string @@ -14,27 +14,27 @@ func IdentifierFromString(s string) Identifier { return Identifier(s) } -// Installable values are the basic unit of problems and solutions +// Variable values are the basic unit of problems and solutions // understood by this package. -type Installable interface { +type Variable interface { // Identifier returns the Identifier that uniquely identifies - // this Installable among all other Installables in a given + // this Variable among all other Variables in a given // problem. Identifier() Identifier // Constraints returns the set of constraints that apply to - // this Installable. + // this Variable. Constraints() []Constraint } -// zeroInstallable is returned by InstallableOf in error cases. -type zeroInstallable struct{} +// zeroVariable is returned by VariableOf in error cases. +type zeroVariable struct{} -var _ Installable = zeroInstallable{} +var _ Variable = zeroVariable{} -func (zeroInstallable) Identifier() Identifier { +func (zeroVariable) Identifier() Identifier { return "" } -func (zeroInstallable) Constraints() []Constraint { +func (zeroVariable) Constraints() []Constraint { return nil } diff --git a/pkg/controller/registry/resolver/step_resolver_test.go b/pkg/controller/registry/resolver/step_resolver_test.go index 3a66f273f2..528d085d30 100644 --- a/pkg/controller/registry/resolver/step_resolver_test.go +++ b/pkg/controller/registry/resolver/step_resolver_test.go @@ -125,12 +125,12 @@ func TestResolver(t *testing.T) { out: resolverTestOut{ solverError: solver.NotSatisfiable{ { - Installable: NewSubscriptionInstallable("a", nil), - Constraint: PrettyConstraint(solver.Mandatory(), "subscription a-alpha exists"), + Variable: NewSubscriptionVariable("a", nil), + Constraint: PrettyConstraint(solver.Mandatory(), "subscription a-alpha exists"), }, { - Installable: NewSubscriptionInstallable("a", nil), - Constraint: PrettyConstraint(solver.Dependency(), "no operators found from catalog catsrc in namespace catsrc-namespace referenced by subscription a-alpha"), + Variable: NewSubscriptionVariable("a", nil), + Constraint: PrettyConstraint(solver.Dependency(), "no operators found from catalog catsrc in namespace catsrc-namespace referenced by subscription a-alpha"), }, }, }, @@ -148,12 +148,12 @@ func TestResolver(t *testing.T) { out: resolverTestOut{ solverError: solver.NotSatisfiable{ { - Installable: NewSubscriptionInstallable("a", nil), - Constraint: PrettyConstraint(solver.Mandatory(), "subscription a-alpha exists"), + Variable: NewSubscriptionVariable("a", nil), + Constraint: PrettyConstraint(solver.Mandatory(), "subscription a-alpha exists"), }, { - Installable: NewSubscriptionInstallable("a", nil), - Constraint: PrettyConstraint(solver.Dependency(), "no operators found in package a in the catalog referenced by subscription a-alpha"), + Variable: NewSubscriptionVariable("a", nil), + Constraint: PrettyConstraint(solver.Dependency(), "no operators found in package a in the catalog referenced by subscription a-alpha"), }, }, }, @@ -171,12 +171,12 @@ func TestResolver(t *testing.T) { out: resolverTestOut{ solverError: solver.NotSatisfiable{ { - Installable: NewSubscriptionInstallable("a", nil), - Constraint: PrettyConstraint(solver.Mandatory(), "subscription a-alpha exists"), + Variable: NewSubscriptionVariable("a", nil), + Constraint: PrettyConstraint(solver.Mandatory(), "subscription a-alpha exists"), }, { - Installable: NewSubscriptionInstallable("a", nil), - Constraint: PrettyConstraint(solver.Dependency(), "no operators found in channel alpha of package a in the catalog referenced by subscription a-alpha"), + Variable: NewSubscriptionVariable("a", nil), + Constraint: PrettyConstraint(solver.Dependency(), "no operators found in channel alpha of package a in the catalog referenced by subscription a-alpha"), }, }, }, @@ -194,12 +194,12 @@ func TestResolver(t *testing.T) { out: resolverTestOut{ solverError: solver.NotSatisfiable{ { - Installable: NewSubscriptionInstallable("a", nil), - Constraint: PrettyConstraint(solver.Mandatory(), "subscription a-alpha exists"), + Variable: NewSubscriptionVariable("a", nil), + Constraint: PrettyConstraint(solver.Mandatory(), "subscription a-alpha exists"), }, { - Installable: NewSubscriptionInstallable("a", nil), - Constraint: PrettyConstraint(solver.Dependency(), "no operators found with name notfound in channel alpha of package a in the catalog referenced by subscription a-alpha"), + Variable: NewSubscriptionVariable("a", nil), + Constraint: PrettyConstraint(solver.Dependency(), "no operators found with name notfound in channel alpha of package a in the catalog referenced by subscription a-alpha"), }, }, }, @@ -351,19 +351,19 @@ func TestResolver(t *testing.T) { subs: []*v1alpha1.Subscription{}, solverError: solver.NotSatisfiable([]solver.AppliedConstraint{ { - Installable: NewSubscriptionInstallable("a", []solver.Identifier{"catsrc/catsrc-namespace/alpha/a.v1"}), - Constraint: PrettyConstraint(solver.Dependency("catsrc/catsrc-namespace/alpha/a.v1"), "subscription a-alpha requires catsrc/catsrc-namespace/alpha/a.v1"), + Variable: NewSubscriptionVariable("a", []solver.Identifier{"catsrc/catsrc-namespace/alpha/a.v1"}), + Constraint: PrettyConstraint(solver.Dependency("catsrc/catsrc-namespace/alpha/a.v1"), "subscription a-alpha requires catsrc/catsrc-namespace/alpha/a.v1"), }, { - Installable: &BundleInstallable{ + Variable: &BundleVariable{ identifier: "catsrc/catsrc-namespace/alpha/a.v1", constraints: []solver.Constraint{solver.Dependency()}, }, Constraint: PrettyConstraint(solver.Dependency(), "bundle a.v1 requires an operator providing an API with group: g, version: v, kind: k"), }, { - Installable: NewSubscriptionInstallable("a", []solver.Identifier{"catsrc/catsrc-namespace/alpha/a.v1"}), - Constraint: PrettyConstraint(solver.Mandatory(), "subscription a-alpha exists"), + Variable: NewSubscriptionVariable("a", []solver.Identifier{"catsrc/catsrc-namespace/alpha/a.v1"}), + Constraint: PrettyConstraint(solver.Mandatory(), "subscription a-alpha exists"), }, }), }, diff --git a/pkg/controller/registry/resolver/installabletypes.go b/pkg/controller/registry/resolver/variable_types.go similarity index 78% rename from pkg/controller/registry/resolver/installabletypes.go rename to pkg/controller/registry/resolver/variable_types.go index 1abd16ed71..108a0de84f 100644 --- a/pkg/controller/registry/resolver/installabletypes.go +++ b/pkg/controller/registry/resolver/variable_types.go @@ -9,34 +9,34 @@ import ( operatorregistry "github.com/operator-framework/operator-registry/pkg/registry" ) -type BundleInstallable struct { +type BundleVariable struct { identifier solver.Identifier constraints []solver.Constraint Replaces string } -func (i BundleInstallable) Identifier() solver.Identifier { +func (i BundleVariable) Identifier() solver.Identifier { return i.identifier } -func (i BundleInstallable) Constraints() []solver.Constraint { +func (i BundleVariable) Constraints() []solver.Constraint { return i.constraints } -func (i *BundleInstallable) MakeProhibited() { +func (i *BundleVariable) MakeProhibited() { i.constraints = append(i.constraints, solver.Prohibited()) } -func (i *BundleInstallable) AddConflict(id solver.Identifier) { +func (i *BundleVariable) AddConflict(id solver.Identifier) { i.constraints = append(i.constraints, solver.Conflict(id)) } -func (i *BundleInstallable) AddConstraint(c solver.Constraint) { +func (i *BundleVariable) AddConstraint(c solver.Constraint) { i.constraints = append(i.constraints, c) } -func (i *BundleInstallable) BundleSourceInfo() (string, string, cache.SourceKey, error) { +func (i *BundleVariable) BundleSourceInfo() (string, string, cache.SourceKey, error) { info := strings.Split(i.identifier.String(), "/") // This should be enforced by Kube naming constraints if len(info) != 4 { @@ -55,9 +55,9 @@ func bundleID(bundle, channel string, catalog cache.SourceKey) solver.Identifier return solver.IdentifierFromString(fmt.Sprintf("%s/%s/%s", catalog.String(), channel, bundle)) } -func NewBundleInstallableFromOperator(o *cache.Entry) (BundleInstallable, error) { +func NewBundleVariableFromOperator(o *cache.Entry) (BundleVariable, error) { if o.SourceInfo == nil { - return BundleInstallable{}, fmt.Errorf("unable to resolve the source of bundle %s", o.Name) + return BundleVariable{}, fmt.Errorf("unable to resolve the source of bundle %s", o.Name) } id := bundleID(o.Name, o.Channel(), o.SourceInfo.Catalog) var constraints []solver.Constraint @@ -79,27 +79,27 @@ func NewBundleInstallableFromOperator(o *cache.Entry) (BundleInstallable, error) break } } - return BundleInstallable{ + return BundleVariable{ identifier: id, constraints: constraints, }, nil } -type GenericInstallable struct { +type GenericVariable struct { identifier solver.Identifier constraints []solver.Constraint } -func (i GenericInstallable) Identifier() solver.Identifier { +func (i GenericVariable) Identifier() solver.Identifier { return i.identifier } -func (i GenericInstallable) Constraints() []solver.Constraint { +func (i GenericVariable) Constraints() []solver.Constraint { return i.constraints } -func NewInvalidSubscriptionInstallable(name string, reason string) solver.Installable { - return GenericInstallable{ +func NewInvalidSubscriptionVariable(name string, reason string) solver.Variable { + return GenericVariable{ identifier: solver.IdentifierFromString(fmt.Sprintf("subscription:%s", name)), constraints: []solver.Constraint{ PrettyConstraint(solver.Mandatory(), fmt.Sprintf("subscription %s exists", name)), @@ -108,8 +108,8 @@ func NewInvalidSubscriptionInstallable(name string, reason string) solver.Instal } } -func NewSubscriptionInstallable(name string, dependencies []solver.Identifier) solver.Installable { - result := GenericInstallable{ +func NewSubscriptionVariable(name string, dependencies []solver.Identifier) solver.Variable { + result := GenericVariable{ identifier: solver.IdentifierFromString(fmt.Sprintf("subscription:%s", name)), constraints: []solver.Constraint{ PrettyConstraint(solver.Mandatory(), fmt.Sprintf("subscription %s exists", name)), @@ -136,9 +136,9 @@ func NewSubscriptionInstallable(name string, dependencies []solver.Identifier) s return result } -func NewSingleAPIProviderInstallable(group, version, kind string, providers []solver.Identifier) solver.Installable { +func NewSingleAPIProviderVariable(group, version, kind string, providers []solver.Identifier) solver.Variable { gvk := fmt.Sprintf("%s (%s/%s)", kind, group, version) - result := GenericInstallable{ + result := GenericVariable{ identifier: solver.IdentifierFromString(gvk), } if len(providers) <= 1 { @@ -157,8 +157,8 @@ func NewSingleAPIProviderInstallable(group, version, kind string, providers []so return result } -func NewSinglePackageInstanceInstallable(pkg string, providers []solver.Identifier) solver.Installable { - result := GenericInstallable{ +func NewSinglePackageInstanceVariable(pkg string, providers []solver.Identifier) solver.Variable { + result := GenericVariable{ identifier: solver.IdentifierFromString(pkg), } if len(providers) <= 1 {