Skip to content

Commit c425615

Browse files
author
Mikalai Radchuk
committed
Resolution CLI POC: offline input
Signed-off-by: Mikalai Radchuk <[email protected]>
1 parent bfbc24f commit c425615

File tree

3 files changed

+86
-8
lines changed

3 files changed

+86
-8
lines changed

cmd/resolutioncli/entity_source.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,12 @@ func (es *indexRefEntitySource) entities(ctx context.Context) (input.EntityList,
116116
return es.entitiesCache, nil
117117
}
118118

119+
// TODO: Reduce code duplication: share a function with catalogdEntitySource (see getEntities)
120+
// We don't want to maintain two functions performing conversion into input.EntityList.
121+
// For this we need some common format. So we need a package which will be able
122+
// to convert from declfcg structs into CRD structs directly or via model.Model.
123+
// One option would be to make this piece of code from catalogd reusable and exportable:
124+
// https://github.com/operator-framework/catalogd/blob/9fe45a628de2e74d9cd73c3650fa2582aaac5213/pkg/controllers/core/catalog_controller.go#L200-L360
119125
func modelToEntities(model model.Model) (input.EntityList, error) {
120126
entities := input.EntityList{}
121127

cmd/resolutioncli/input_manifests.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
Copyright 2022.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package main
18+
19+
import (
20+
"fmt"
21+
"os"
22+
"path/filepath"
23+
24+
"k8s.io/apimachinery/pkg/runtime"
25+
)
26+
27+
func readManifestFiles(directory string) ([]runtime.Object, error) {
28+
var objects []runtime.Object
29+
30+
err := filepath.Walk(directory, func(path string, info os.FileInfo, err error) error {
31+
if err != nil {
32+
return err
33+
}
34+
35+
if info.IsDir() {
36+
return nil
37+
}
38+
39+
fileContent, err := os.ReadFile(path)
40+
if err != nil {
41+
return fmt.Errorf("failed to read file %s: %w", path, err)
42+
}
43+
44+
decoder := codecs.UniversalDecoder(scheme.PrioritizedVersionsAllGroups()...)
45+
object, _, err := decoder.Decode(fileContent, nil, nil)
46+
if err != nil {
47+
return fmt.Errorf("failed to decode file %s: %w", path, err)
48+
}
49+
50+
objects = append(objects, object)
51+
52+
return nil
53+
})
54+
55+
if err != nil {
56+
return nil, fmt.Errorf("failed to read files: %w", err)
57+
}
58+
59+
return objects, nil
60+
}

cmd/resolutioncli/main.go

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ import (
2626
"github.com/operator-framework/deppy/pkg/deppy/solver"
2727
rukpakv1alpha1 "github.com/operator-framework/rukpak/api/v1alpha1"
2828
"k8s.io/apimachinery/pkg/runtime"
29+
"k8s.io/apimachinery/pkg/runtime/serializer"
2930
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
3031
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
3132
_ "k8s.io/client-go/plugin/pkg/client/auth"
32-
"sigs.k8s.io/controller-runtime/pkg/client"
33-
"sigs.k8s.io/controller-runtime/pkg/client/config"
33+
"sigs.k8s.io/controller-runtime/pkg/client/fake"
3434

3535
catalogd "github.com/operator-framework/catalogd/api/core/v1alpha1"
3636
operatorsv1alpha1 "github.com/operator-framework/operator-controller/api/v1alpha1"
@@ -49,10 +49,13 @@ const (
4949
flagNamePackageVersion = "package-version"
5050
flagNamePackageChannel = "package-channel"
5151
flagNameIndexRef = "index-ref"
52+
flagNameInputDir = "input-dir"
5253
)
5354

5455
var (
5556
scheme = runtime.NewScheme()
57+
58+
codecs = serializer.NewCodecFactory(scheme)
5659
)
5760

5861
func init() {
@@ -71,11 +74,13 @@ func main() {
7174
var packageVersion string
7275
var packageChannel string
7376
var indexRef string
77+
var inputDir string
7478
flag.StringVar(&packageName, flagNamePackageName, "", "Name of the package to resolve")
7579
flag.StringVar(&packageVersion, flagNamePackageVersion, "", "Version of the package")
7680
flag.StringVar(&packageChannel, flagNamePackageChannel, "", "Channel of the package")
7781
// TODO: Consider adding support of multiple refs
7882
flag.StringVar(&indexRef, flagNameIndexRef, "", "Index reference (FBC image or dir)")
83+
flag.StringVar(&inputDir, flagNameInputDir, "", "Directory containing Kubernetes manifests (such as Operator) to be used as an input for resolution")
7984
flag.Parse()
8085

8186
if err := validateFlags(packageName, indexRef); err != nil {
@@ -84,7 +89,7 @@ func main() {
8489
os.Exit(1)
8590
}
8691

87-
err := run(ctx, packageName, packageVersion, packageChannel, indexRef)
92+
err := run(ctx, packageName, packageVersion, packageChannel, indexRef, inputDir)
8893
if err != nil {
8994
fmt.Fprintln(os.Stderr, err)
9095
os.Exit(1)
@@ -103,18 +108,25 @@ func validateFlags(packageName, indexRef string) error {
103108
return nil
104109
}
105110

106-
func run(ctx context.Context, packageName, packageVersion, packageChannel, catalogRef string) error {
107-
client, err := client.New(config.GetConfigOrDie(), client.Options{Scheme: scheme})
108-
if err != nil {
109-
return fmt.Errorf("failed to create client: %w", err)
111+
func run(ctx context.Context, packageName, packageVersion, packageChannel, catalogRef, inputDir string) error {
112+
clientBuilder := fake.NewClientBuilder().WithScheme(scheme)
113+
114+
if inputDir != "" {
115+
objects, err := readManifestFiles(inputDir)
116+
if err != nil {
117+
return err
118+
}
119+
120+
clientBuilder.WithRuntimeObjects(objects...)
110121
}
111122

123+
cl := clientBuilder.Build()
112124
resolver := solver.NewDeppySolver(
113125
newIndexRefEntitySourceEntitySource(catalogRef),
114126
olm.NestedVariableSource{
115127
newPackageVariableSource(packageName, packageVersion, packageChannel),
116128
func(inputVariableSource input.VariableSource) (input.VariableSource, error) {
117-
return olm.NewOperatorVariableSource(client, inputVariableSource), nil
129+
return olm.NewOperatorVariableSource(cl, inputVariableSource), nil
118130
},
119131
func(inputVariableSource input.VariableSource) (input.VariableSource, error) {
120132
return bundles_and_dependencies.NewBundlesAndDepsVariableSource(inputVariableSource), nil

0 commit comments

Comments
 (0)