Skip to content

Commit

Permalink
Split variables and variable sources
Browse files Browse the repository at this point in the history
Signed-off-by: Mikalai Radchuk <mradchuk@redhat.com>
  • Loading branch information
m1kola committed Jun 26, 2023
1 parent 5f27a87 commit dcac67e
Show file tree
Hide file tree
Showing 13 changed files with 281 additions and 209 deletions.
4 changes: 2 additions & 2 deletions internal/controllers/operator_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ import (
operatorsv1alpha1 "github.com/operator-framework/operator-controller/api/v1alpha1"
"github.com/operator-framework/operator-controller/internal/controllers/validators"
"github.com/operator-framework/operator-controller/internal/resolution/entities"
"github.com/operator-framework/operator-controller/internal/resolution/variablesources"
"github.com/operator-framework/operator-controller/internal/resolution/variables"
)

// OperatorReconciler reconciles a Operator object
Expand Down Expand Up @@ -247,7 +247,7 @@ func mapBDStatusToInstalledCondition(existingTypedBundleDeployment *rukpakv1alph
func (r *OperatorReconciler) getBundleEntityFromSolution(solution *solver.Solution, packageName string) (*entities.BundleEntity, error) {
for _, variable := range solution.SelectedVariables() {
switch v := variable.(type) {
case *variablesources.BundleVariable:
case *variables.BundleVariable:
entityPkgName, err := v.BundleEntity().PackageName()
if err != nil {
return nil, err
Expand Down
58 changes: 58 additions & 0 deletions internal/resolution/variables/bundle.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package variables

import (
"github.com/operator-framework/deppy/pkg/deppy"
"github.com/operator-framework/deppy/pkg/deppy/constraint"
"github.com/operator-framework/deppy/pkg/deppy/input"

olmentity "github.com/operator-framework/operator-controller/internal/resolution/entities"
)

var _ deppy.Variable = &BundleVariable{}

type BundleVariable struct {
*input.SimpleVariable
bundleEntity *olmentity.BundleEntity
dependencies []*olmentity.BundleEntity
}

func (b *BundleVariable) BundleEntity() *olmentity.BundleEntity {
return b.bundleEntity
}

func (b *BundleVariable) Dependencies() []*olmentity.BundleEntity {
return b.dependencies
}

func NewBundleVariable(bundleEntity *olmentity.BundleEntity, dependencyBundleEntities []*olmentity.BundleEntity) *BundleVariable {
dependencyIDs := make([]deppy.Identifier, 0, len(dependencyBundleEntities))
for _, bundle := range dependencyBundleEntities {
dependencyIDs = append(dependencyIDs, bundle.ID)
}
var constraints []deppy.Constraint
if len(dependencyIDs) > 0 {
constraints = append(constraints, constraint.Dependency(dependencyIDs...))
}
return &BundleVariable{
SimpleVariable: input.NewSimpleVariable(bundleEntity.ID, constraints...),
bundleEntity: bundleEntity,
dependencies: dependencyBundleEntities,
}
}

var _ deppy.Variable = &BundleUniquenessVariable{}

type BundleUniquenessVariable struct {
*input.SimpleVariable
}

// NewBundleUniquenessVariable creates a new variable that instructs the resolver to choose at most a single bundle
// from the input 'atMostID'. Examples:
// 1. restrict the solution to at most a single bundle per package
// 2. restrict the solution to at most a single bundler per provided gvk
// this guarantees that no two operators provide the same gvk and no two version of the same operator are running at the same time
func NewBundleUniquenessVariable(id deppy.Identifier, atMostIDs ...deppy.Identifier) *BundleUniquenessVariable {
return &BundleUniquenessVariable{
SimpleVariable: input.NewSimpleVariable(id, constraint.AtMost(1, atMostIDs...)),
}
}
70 changes: 70 additions & 0 deletions internal/resolution/variables/bundle_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package variables_test

import (
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"

"github.com/operator-framework/deppy/pkg/deppy"
"github.com/operator-framework/deppy/pkg/deppy/constraint"
"github.com/operator-framework/deppy/pkg/deppy/input"
"github.com/operator-framework/operator-registry/alpha/property"

olmentity "github.com/operator-framework/operator-controller/internal/resolution/entities"
"github.com/operator-framework/operator-controller/internal/resolution/variables"
)

var _ = Describe("BundleVariable", func() {
var (
bv *variables.BundleVariable
bundleEntity *olmentity.BundleEntity
dependencies []*olmentity.BundleEntity
)

BeforeEach(func() {
bundleEntity = olmentity.NewBundleEntity(input.NewEntity("bundle-1", map[string]string{
property.TypePackage: `{"packageName": "test-package", "version": "1.0.0"}`,
property.TypeChannel: `{"channelName":"stable","priority":0}`,
}))
dependencies = []*olmentity.BundleEntity{
olmentity.NewBundleEntity(input.NewEntity("bundle-2", map[string]string{
property.TypePackage: `{"packageName": "test-package-2", "version": "2.0.0"}`,
property.TypeChannel: `{"channelName":"stable","priority":0}`,
})),
olmentity.NewBundleEntity(input.NewEntity("bundle-3", map[string]string{
property.TypePackage: `{"packageName": "test-package-3", "version": "2.0.0"}`,
property.TypeChannel: `{"channelName":"stable","priority":0}`,
})),
}
bv = variables.NewBundleVariable(bundleEntity, dependencies)
})

It("should return the correct bundle entity", func() {
Expect(bv.BundleEntity()).To(Equal(bundleEntity))
})

It("should return the correct dependencies", func() {
Expect(bv.Dependencies()).To(Equal(dependencies))
})
})

var _ = Describe("BundleUniquenessVariable", func() {
var (
id deppy.Identifier
atMostIDs []deppy.Identifier
globalConstraintVariable *variables.BundleUniquenessVariable
)

BeforeEach(func() {
id = deppy.IdentifierFromString("test-id")
atMostIDs = []deppy.Identifier{
deppy.IdentifierFromString("test-at-most-id-1"),
deppy.IdentifierFromString("test-at-most-id-2"),
}
globalConstraintVariable = variables.NewBundleUniquenessVariable(id, atMostIDs...)
})

It("should initialize a new global constraint variable", func() {
Expect(globalConstraintVariable.Identifier()).To(Equal(id))
Expect(globalConstraintVariable.Constraints()).To(Equal([]deppy.Constraint{constraint.AtMost(1, atMostIDs...)}))
})
})
34 changes: 34 additions & 0 deletions internal/resolution/variables/required_package.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package variables

import (
"fmt"

"github.com/operator-framework/deppy/pkg/deppy"
"github.com/operator-framework/deppy/pkg/deppy/constraint"
"github.com/operator-framework/deppy/pkg/deppy/input"

olmentity "github.com/operator-framework/operator-controller/internal/resolution/entities"
)

var _ deppy.Variable = &RequiredPackageVariable{}

type RequiredPackageVariable struct {
*input.SimpleVariable
bundleEntities []*olmentity.BundleEntity
}

func (r *RequiredPackageVariable) BundleEntities() []*olmentity.BundleEntity {
return r.bundleEntities
}

func NewRequiredPackageVariable(packageName string, bundleEntities []*olmentity.BundleEntity) *RequiredPackageVariable {
id := deppy.IdentifierFromString(fmt.Sprintf("required package %s", packageName))
entityIDs := make([]deppy.Identifier, 0, len(bundleEntities))
for _, bundle := range bundleEntities {
entityIDs = append(entityIDs, bundle.ID)
}
return &RequiredPackageVariable{
SimpleVariable: input.NewSimpleVariable(id, constraint.Mandatory(), constraint.Dependency(entityIDs...)),
bundleEntities: bundleEntities,
}
}
55 changes: 55 additions & 0 deletions internal/resolution/variables/required_package_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package variables_test

import (
"fmt"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"

"github.com/operator-framework/deppy/pkg/deppy"
"github.com/operator-framework/deppy/pkg/deppy/input"
"github.com/operator-framework/operator-registry/alpha/property"

olmentity "github.com/operator-framework/operator-controller/internal/resolution/entities"
olmvariables "github.com/operator-framework/operator-controller/internal/resolution/variables"
)

var _ = Describe("RequiredPackageVariable", func() {
var (
rpv *olmvariables.RequiredPackageVariable
packageName string
bundleEntities []*olmentity.BundleEntity
)

BeforeEach(func() {
packageName = "test-package"
bundleEntities = []*olmentity.BundleEntity{
olmentity.NewBundleEntity(input.NewEntity("bundle-1", map[string]string{
property.TypePackage: `{"packageName": "test-package", "version": "1.0.0"}`,
property.TypeChannel: `{"channelName":"stable","priority":0}`,
})),
olmentity.NewBundleEntity(input.NewEntity("bundle-2", map[string]string{
property.TypePackage: `{"packageName": "test-package", "version": "2.0.0"}`,
property.TypeChannel: `{"channelName":"stable","priority":0}`,
})),
olmentity.NewBundleEntity(input.NewEntity("bundle-3", map[string]string{
property.TypePackage: `{"packageName": "test-package", "version": "3.0.0"}`,
property.TypeChannel: `{"channelName":"stable","priority":0}`,
})),
}
rpv = olmvariables.NewRequiredPackageVariable(packageName, bundleEntities)
})

It("should return the correct package name", func() {
Expect(rpv.Identifier()).To(Equal(deppy.IdentifierFromString(fmt.Sprintf("required package %s", packageName))))
})

It("should return the correct bundle entities", func() {
Expect(rpv.BundleEntities()).To(Equal(bundleEntities))
})

It("should contain both mandatory and dependency constraints", func() {
// TODO: add this test once https://github.com/operator-framework/deppy/pull/85 gets merged
// then we'll be able to inspect constraint types
})
})
13 changes: 13 additions & 0 deletions internal/resolution/variables/variables_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package variables_test

import (
"testing"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

func TestVariableSources(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Variables Suite")
}
36 changes: 3 additions & 33 deletions internal/resolution/variablesources/bundles_and_dependencies.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,44 +7,14 @@ import (

"github.com/blang/semver/v4"
"github.com/operator-framework/deppy/pkg/deppy"
"github.com/operator-framework/deppy/pkg/deppy/constraint"
"github.com/operator-framework/deppy/pkg/deppy/input"

olmentity "github.com/operator-framework/operator-controller/internal/resolution/entities"
"github.com/operator-framework/operator-controller/internal/resolution/util/predicates"
entitysort "github.com/operator-framework/operator-controller/internal/resolution/util/sort"
olmvariables "github.com/operator-framework/operator-controller/internal/resolution/variables"
)

type BundleVariable struct {
*input.SimpleVariable
bundleEntity *olmentity.BundleEntity
dependencies []*olmentity.BundleEntity
}

func (b *BundleVariable) BundleEntity() *olmentity.BundleEntity {
return b.bundleEntity
}

func (b *BundleVariable) Dependencies() []*olmentity.BundleEntity {
return b.dependencies
}

func NewBundleVariable(bundleEntity *olmentity.BundleEntity, dependencyBundleEntities []*olmentity.BundleEntity) *BundleVariable {
dependencyIDs := make([]deppy.Identifier, 0, len(dependencyBundleEntities))
for _, bundle := range dependencyBundleEntities {
dependencyIDs = append(dependencyIDs, bundle.ID)
}
var constraints []deppy.Constraint
if len(dependencyIDs) > 0 {
constraints = append(constraints, constraint.Dependency(dependencyIDs...))
}
return &BundleVariable{
SimpleVariable: input.NewSimpleVariable(bundleEntity.ID, constraints...),
bundleEntity: bundleEntity,
dependencies: dependencyBundleEntities,
}
}

var _ input.VariableSource = &BundlesAndDepsVariableSource{}

type BundlesAndDepsVariableSource struct {
Expand Down Expand Up @@ -73,7 +43,7 @@ func (b *BundlesAndDepsVariableSource) GetVariables(ctx context.Context, entityS
var bundleEntityQueue []*olmentity.BundleEntity
for _, variable := range variables {
switch v := variable.(type) {
case *RequiredPackageVariable:
case *olmvariables.RequiredPackageVariable:
bundleEntityQueue = append(bundleEntityQueue, v.BundleEntities()...)
}
}
Expand Down Expand Up @@ -101,7 +71,7 @@ func (b *BundlesAndDepsVariableSource) GetVariables(ctx context.Context, entityS
bundleEntityQueue = append(bundleEntityQueue, dependencyEntityBundles...)

// create variable
variables = append(variables, NewBundleVariable(head, dependencyEntityBundles))
variables = append(variables, olmvariables.NewBundleVariable(head, dependencyEntityBundles))
}

return variables, nil
Expand Down
Loading

0 comments on commit dcac67e

Please sign in to comment.