Skip to content

Commit 42f2555

Browse files
author
Mikalai Radchuk
committed
Adds bundle data snapshotting for resolution
We now snapshot bundle data in the client for the duration of single resolution. This reduces reads (from network or cache) and unmarshalling since data in memory. And it also ensures that different variable sources involved in the resolution process have the same view of catalogs and bundles. Signed-off-by: Mikalai Radchuk <[email protected]>
1 parent 6808a50 commit 42f2555

File tree

4 files changed

+47
-11
lines changed

4 files changed

+47
-11
lines changed

cmd/manager/main.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,10 @@ func main() {
110110
catalogClient := catalogclient.New(cl, cache.NewFilesystemCache(cachePath, &http.Client{Timeout: 10 * time.Second}))
111111

112112
if err = (&controllers.OperatorReconciler{
113-
Client: cl,
114-
Scheme: mgr.GetScheme(),
115-
Resolver: solver.NewDeppySolver(
116-
controllers.NewVariableSource(cl, catalogClient),
117-
),
113+
Client: cl,
114+
Scheme: mgr.GetScheme(),
115+
CatalogClient: catalogClient,
116+
NewSolver: solver.NewDeppySolver,
118117
}).SetupWithManager(mgr); err != nil {
119118
setupLog.Error(err, "unable to create controller", "controller", "Operator")
120119
os.Exit(1)

internal/catalogmetadata/client/client.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,34 @@ func (c *Client) Bundles(ctx context.Context) ([]*catalogmetadata.Bundle, error)
100100
return allBundles, nil
101101
}
102102

103+
func NewSnapshotClient(catalogClient *Client) *SnapshotClient {
104+
return &SnapshotClient{
105+
Client: catalogClient,
106+
}
107+
}
108+
109+
// SnapshotClient fetches data from catalogs and caches them for the lifetime of the
110+
// SnapshotClient instance. Meaning that if new catalog or new bundles get created
111+
// in between calls to the same instance of the client they will not appear in the result.
112+
// This is convenient for bundle resolution process where we want all components
113+
// to have the same view of catalogs.
114+
type SnapshotClient struct {
115+
*Client
116+
bundlesSnapshot []*catalogmetadata.Bundle
117+
}
118+
119+
func (c *SnapshotClient) Bundles(ctx context.Context) ([]*catalogmetadata.Bundle, error) {
120+
if c.bundlesSnapshot == nil {
121+
allBundles, err := c.Client.Bundles(ctx)
122+
if err != nil {
123+
return nil, err
124+
}
125+
c.bundlesSnapshot = allBundles
126+
}
127+
128+
return c.bundlesSnapshot, nil
129+
}
130+
103131
func PopulateExtraFields(catalogName string, channels []*catalogmetadata.Channel, bundles []*catalogmetadata.Bundle) ([]*catalogmetadata.Bundle, error) {
104132
bundlesMap := map[string]*catalogmetadata.Bundle{}
105133
for i := range bundles {

internal/controllers/operator_controller.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"github.com/go-logr/logr"
2727
catalogd "github.com/operator-framework/catalogd/api/core/v1alpha1"
2828
"github.com/operator-framework/deppy/pkg/deppy"
29+
"github.com/operator-framework/deppy/pkg/deppy/input"
2930
"github.com/operator-framework/deppy/pkg/deppy/solver"
3031
rukpakv1alpha1 "github.com/operator-framework/rukpak/api/v1alpha1"
3132
"k8s.io/apimachinery/pkg/api/equality"
@@ -45,15 +46,17 @@ import (
4546

4647
operatorsv1alpha1 "github.com/operator-framework/operator-controller/api/v1alpha1"
4748
"github.com/operator-framework/operator-controller/internal/catalogmetadata"
49+
catalogclient "github.com/operator-framework/operator-controller/internal/catalogmetadata/client"
4850
"github.com/operator-framework/operator-controller/internal/controllers/validators"
4951
olmvariables "github.com/operator-framework/operator-controller/internal/resolution/variables"
5052
)
5153

5254
// OperatorReconciler reconciles a Operator object
5355
type OperatorReconciler struct {
5456
client.Client
55-
Scheme *runtime.Scheme
56-
Resolver *solver.DeppySolver
57+
Scheme *runtime.Scheme
58+
CatalogClient *catalogclient.Client
59+
NewSolver func(variableSource input.VariableSource) *solver.DeppySolver
5760
}
5861

5962
//+kubebuilder:rbac:groups=operators.operatorframework.io,resources=operators,verbs=get;list;watch
@@ -130,7 +133,8 @@ func (r *OperatorReconciler) reconcile(ctx context.Context, op *operatorsv1alpha
130133
return ctrl.Result{}, nil
131134
}
132135
// run resolution
133-
solution, err := r.Resolver.Solve(ctx)
136+
variableSource := NewVariableSource(r.Client, catalogclient.NewSnapshotClient(r.CatalogClient))
137+
solution, err := r.NewSolver(variableSource).Solve(ctx)
134138
if err != nil {
135139
op.Status.InstalledBundleResource = ""
136140
setInstalledStatusConditionUnknown(&op.Status.Conditions, "installation has not been attempted as resolution failed", op.GetGeneration())

internal/controllers/operator_controller_test.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77

88
. "github.com/onsi/ginkgo/v2"
99
. "github.com/onsi/gomega"
10+
"github.com/operator-framework/deppy/pkg/deppy/input"
1011
"github.com/operator-framework/deppy/pkg/deppy/solver"
1112
"github.com/operator-framework/operator-registry/alpha/declcfg"
1213
"github.com/operator-framework/operator-registry/alpha/property"
@@ -37,9 +38,13 @@ var _ = Describe("Operator Controller Test", func() {
3738
ctx = context.Background()
3839
fakeCatalogClient = testutil.NewFakeCatalogClient(testBundleList)
3940
reconciler = &controllers.OperatorReconciler{
40-
Client: cl,
41-
Scheme: sch,
42-
Resolver: solver.NewDeppySolver(controllers.NewVariableSource(cl, &fakeCatalogClient)),
41+
Client: cl,
42+
Scheme: sch,
43+
NewSolver: func(variableSource input.VariableSource) *solver.DeppySolver {
44+
return solver.NewDeppySolver(
45+
controllers.NewVariableSource(cl, &fakeCatalogClient),
46+
)
47+
},
4348
}
4449
})
4550
When("the operator does not exist", func() {

0 commit comments

Comments
 (0)