Skip to content

Commit 321525f

Browse files
committed
Updated comments and README
Signed-off-by: jubittajohn <[email protected]>
1 parent b2a70c9 commit 321525f

File tree

4 files changed

+155
-86
lines changed

4 files changed

+155
-86
lines changed

test/operator-framework-e2e/README.md

Lines changed: 103 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,18 @@ The steps in the ginkgo test can be summarized as follows:
2626
- With the scale of the OLM v1 project, it is useful to have a means to test components in the operator development + lifecycle pipeline together to create a more cohesive experience for all users.
2727

2828
## Getting Started
29-
29+
- This test currently only works with the container runtime `docker`.
3030
- Building operator-controller, deploying it into the cluster and rest of the configuration is done in the `MakeFile` of this repo under the target `operator-developer-e2e`. This includes:
3131

3232
- Setting up a kind cluster named `operator-controller-op-dev-e2e`.
3333
- Installing the operator controller onto the cluster.
3434
- Setting up `opm`, `operator-sdk` and `kustomize` using bingo.
3535
- Setting up a local registry server for building and loading images.
36+
### Input Values used
37+
38+
Below are the input values used in the test which is specified in the `operator_framework_test.go`.
3639

37-
- The following structs defined are required as input for both plain+v0 and registry+v1 bundles:
40+
- The following structs defined are required, to accept input for both `plain+v0` and `registry+v1` bundles:
3841
- For getting bundle related inputs:
3942
```
4043
type BundleInfo struct {
@@ -48,11 +51,11 @@ The steps in the ginkgo test can be summarized as follows:
4851
imageRef string
4952
}
5053
```
51-
- `baseFolderPath` - Base/root path of the folder for the specific bundle type input data.[path to plain-v0 or registry-v1 bundles testdata]
54+
- `baseFolderPath` - Base/root path of the folder where the specific bundle type input data is stored.[root path to plain-v0 or registry-v1 bundles testdata]
5255
- `bundles` - Stores the data relevant to different versions of the bundle.
53-
- `bInputDir` - The input directory containing the specific version of the bundle data.
56+
- `bInputDir` - The directory that stores the specific version of the bundle data. The name of the directory is formed and is of the format `<operatorName>.v<bundleVersion>`.
5457
- `bundleVersion` - The specific version of the bundle data.
55-
- `imageRef` - This is formed. Stores the bundle image reference which will be of the format `localhost:5001/<operator_name>-bundle:v.<bundleVersion>`
58+
- `imageRef` - This is formed. Stores the bundle image reference which will be of the format `<registry_repo>/< operatorName>-bundle:v.<bundleVersion>`
5659
- For getting catalog related inputs:
5760
```
5861
type CatalogDInfo struct {
@@ -64,11 +67,11 @@ The steps in the ginkgo test can be summarized as follows:
6467
fbcFileName string
6568
}
6669
```
67-
- `baseFolderPath` - Base/root path of the folder for the catalogs.
70+
- `baseFolderPath` - Base/root path of the folder that stores the catalogs.
6871
- `operatorName` - Name of the operator to be installed from the bundles.
6972
- `desiredChannelName` - Desired channel name for the operator.
70-
- `catalogDir` - This is formed. The directory to store the FBC. The formed value will be of the format: `<operator-name>-catalog`
71-
- `imageRef` - This is formed. Stores the FBC image reference which will be of the format: `localhost:5001/<username>/<catalogDir>:test`
73+
- `catalogDir` - This is formed. The directory to store the catalog/FBC. The directory name will be of the format: `<operator-name>-catalog`
74+
- `imageRef` - This is formed. Stores the FBC image reference which will be of the format: `<registry_repo>/<catalogDir>:test`
7275
- `fbcFileName` - Name of the FBC file. This is hard-coded as `catalog.yaml`.
7376
- For getting information related to the install/upgrade action for operators:
7477
```
@@ -80,9 +83,8 @@ The steps in the ginkgo test can be summarized as follows:
8083
- `installVersion` - Version of the operator to be installed on the cluster.
8184
- `upgradeVersion` - Version of the operator to be upgraded on the cluster.
8285
83-
### Plain bundles
84-
- The plain+v0 bundles are formed using `operator-sdk` and `kustomize`.
85-
- The below input is used to form the bundle using operator-sdk.
86+
- The below inputs are used to form the bundle using operator-sdk.
87+
8688
```
8789
type SdkProjectInfo struct {
8890
projectName string
@@ -92,42 +94,109 @@ The steps in the ginkgo test can be summarized as follows:
9294
kind string
9395
}
9496
```
97+
## How to run
98+
- Makefile target `operator-developer-e2e` : Runs the entire E2E setup.
99+
- Makefile target `test-op-dev-e2e`: Runs the ginkgo test.
100+
- Makefile target `deploy-local-registry`: Deploys local registry
101+
- Makefile target `cleanup-local-registry` : Stops and removes local registry
102+
- Makefile target `kind-cluster-cleanup`: Deletes the kind cluster
103+
104+
## Bundle Types
105+
### Plain bundles
106+
- The `plain+v0` bundles are formed using `operator-sdk` and `kustomize`.
107+
- The `kustomize` organizes the different resources present in the `operator-sdk` project into a single yaml file.
108+
- The Dockerfile for the bundle is named `plainbundle.Dockerfile` and is generated using a custom routine.
109+
- The generated bundle is stored in the format:
110+
```
111+
plain-v0
112+
└── <operatorName>.v<bundleVersion>
113+
└── manifests
114+
│ └── mainfest.yaml
115+
└── plainbundle.Dockerfile
116+
```
95117
96-
- After the bundle image is created and loaded, the FBC is formed by a custom routine by using the operatorName, desiredChannelName, bundle imageRefs and bundleVersions.
97-
98-
- The generated FBC will be present in the file path: `testdata/catalogs/<operatorName>-catalog/catalog.yaml` and the Dockerfile will be formed in the file path: `testdata/catalogs/<operatorName>-catalog.Dockerfile`
99-
- `Default channel` is not used in forming the FBC as it is not an OLMv1 concept.
100-
- The package schema name will be the operatorName and the bundle name will be `<operatorName>.v<version>`.
101118
102-
- The catalog resource is then formed with the name `<operatorName>-catalog`.
119+
- The FBC template is formed by a custom routine by using the operatorName, desiredChannelName, bundle imageRefs and bundleVersions.
120+
- `Default channel` is not used in forming the FBC as it is not an OLMv1 concept.
121+
- Only one `olm.channel` is generated which is the given <desiredChannelName>.
122+
- Upgrade graph is formed with only replaces edge.
123+
- The generated FBC is not validated using `opm` as the tool has no support for plain bundles.
124+
- The Dockerfile for the catalog is named `<operator-name>-catalog.Dockerfile` and is generated using a custom routine.
125+
- The generated catalog is stored in the format:
126+
```
127+
catalogs
128+
└── <operator-name>-catalog
129+
│ └── catalog.yaml
130+
└── <operator-name>-catalog.Dockerfile
131+
```
132+
- The catalog CR is then formed with the name `<operatorName>-catalog`.
103133
104134
- The operator is then installed and has the name `<operatorName>`.
105135
106136
### Registry Bundles
107137
108138
- The registry+v1 bundles are formed using operator-sdk.
109-
- The below input is used to form the bundle using operator-sdk.
139+
- The generated CSV uses the default values.
140+
- The bundle content is formed within the operator-sdk project directory in the folder `bundle`. This is moved to the bundle directory folder.
141+
- The generated Dockerfile has the name `bundle.Dockerfile`. The Dockerfile and bundle structure is genearted by the `operator-sdk` tool.
142+
- The generated bundle is stored in the format:
110143
```
111-
type SdkProjectInfo struct {
112-
projectName string
113-
domainName string
114-
group string
115-
version string
116-
kind string
117-
}
144+
registry-v1
145+
└── <operatorName>.v<bundleVersion>
146+
└── manifests
147+
└── metadata
148+
└── bundle.Dockerfile
149+
```
150+
151+
- The FBC is formed using `opm alpha render-template semver` tool.
152+
- The semver template named `registry-semver.yaml` is formed using a custom routine by passing the bundle imageRefs.
153+
- `generatemajorchannels` and `generateminorchannels` is set to false in the semver template.
154+
- The generated catalog is stored in the format:
155+
```
156+
catalogs
157+
└── <operator-name>-catalog
158+
│ └── catalog.yaml
159+
└── <operator-name>-catalog.Dockerfile
118160
```
119-
- The generated CSV uses the default values.
120-
- The bundle content is formed in the operator-sdk project directory in the folder `bundle`. This is moved to the folder path: `testdata/bundles/registry-v1/<operatorName>.v<version>`.
121-
- The generated Dockerfile has the name `bundle.Dockerfile`.
122-
- The same project directory needs to be updated for forming a different version of the `bundle`.
123-
- After the bundle image is created and loaded, the FBC is formed using `semver` and `opm` tool.
124-
- The semver named `registry-semver.yaml` is formed by passing the bundle imageRefs.
125-
- The generated FBC will be present in the file path: `testdata/catalogs/<operatorName>-catalog/catalog.yaml` and the Dockerfile will be formed in the file path: `testdata/catalogs/<operatorName>-catalog.Dockerfile`
126-
- The package schema name will be the operator-sdk projectName.
127161
128162
- The catalog resource is then formed with the name `<operatorName>-catalog`.
129163
130164
- The operator is then installed and has the name `<operatorName>`.
131165
132166
133-
- After the e2e workflow, all the files formed are cleared and the catalog is deleted.
167+
- After the e2e workflow, all the files formed are cleared.
168+
169+
170+
## To-do
171+
1. The resources are read from input manifests using universal decoder from `k8s.io/apimachinery/pkg/runtime/serializer`.
172+
- However, in cases where a single file contains multiple YAML documents separated by `---,` the `UniversalDecoder` recognizes only the first resource. This situation is relevant as for `plain+v0` bundles generated through `kustomize,` the manifest has multiple YAML documents are combined into one file using --- separators. This is now handled by splitting the content of the YAML file and decoding each of them using the `UniversalDecoder`.
173+
- This workaround can be improved using `YAMLToJSONDecoder` from `k8s.io/apimachinery/pkg/util/yaml`. And the kind, api version and name can be get by decoding into `Unstructured` from `k8s.io/apimachinery/pkg/apis/meta/v1/unstructured`.
174+
2. All the tests pass and the operator is installed successfully. The bundledeployment succeeds and the resources are created. But the pod for the new operator failes due to `ImagePullBackOff`.
175+
- This is because the `Deployment` controller-manager uses the image `controller:latest` which is not present on the cluster.
176+
- The solution would be to replace `controller:latest` with the `busybox:latest` and then pulling and loading `busybox:latest` onto cluster.
177+
- The replacement could possibly be achieved by adding the following to `config/default/kustomization.yaml` under `operator-sdk` project:
178+
```
179+
images:
180+
- name: controller
181+
newName: controller
182+
newTag: latest
183+
```
184+
## Issues
185+
1. This test currently only works with the container runtime `docker`.
186+
- The default value of CONTAINER_RUNTIME defined in the Makefile is `docker`. Therefore the correct runtime has to be assigned to the variable `CONTAINER_RUNTIME` before calling the make target if docker is what is not being used. The test routine also assumes the runtime as `docker` if it is unable to retrieve the value of the environment variable.
187+
- But this is only a partial fix to the problem. With this change the test for `plain+v0` bundles will pass but for `registry+v1` will fail for other container runtimes. This is because `registry+v1` uses `operator-sdk` support. Thus to mimic the user experience, the targets `bundle-build` and `bundle-push` from the generated Makefile by operator-sdk tool, which has docker being hard coded as the container runtime, is used to build and push the bundle images. This could be marked as an issue and addressed when hard coding docker as container runtime in the generated Makefile is addressed by operator-sdk.
188+
189+
2. The `opm`,`operator-sdk` and `kustomize` binaries are added in operator-controller using `bingo`.
190+
- But based on discussions, if required test should be changed so that it has `opm` and `operator-sdk` in `PATH` and simply runs it like `exec.Command("opm", ...)`.
191+
- This will enable in running [a matrix](https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs) for the tests and to use different versions of `opm` and `operator-sdk`.
192+
- This might help in emulating the user experience better.
193+
194+
## Tooling gaps
195+
196+
Following are the tooling gaps identified while testing `operator-framework` end-to-end:
197+
- `opm` doesn't have plain bundle support.
198+
- No tool for forming FBC for plain bundles.
199+
- No tool for generating Dockerfile for plain bundles.
200+
- No tool for generating Dockerfile for plain catalogs.
201+
- Since `opm` doesn't have plain bundle support, there is no means to validate the FBC generated for plain bundles.
202+

test/operator-framework-e2e/create_fbc_helper.go

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,18 @@ import (
1313
)
1414

1515
const (
16-
SchemaPackage = "olm.package"
17-
SchemaChannel = "olm.channel"
18-
SchemaBundle = "olm.bundle"
1916
SchemaBundleMediatype = "olm.bundle.mediatype"
2017
BundleMediatype = "plain+v0"
2118
)
2219

2320
// Forms the FBC declartive config and creates the FBC by calling functions for forming the package, channel and bundles.
24-
func CreateFBC(operatorName, defaultChannel string, bundleRefsVersions map[string]string) *declcfg.DeclarativeConfig {
21+
func CreateFBC(operatorName, channelName string, bundleRefsVersions map[string]string) *declcfg.DeclarativeConfig {
2522
dPackage := formPackage(operatorName)
2623
bundleVersions := make([]string, 0)
2724
for _, bundleVersion := range bundleRefsVersions {
2825
bundleVersions = append(bundleVersions, bundleVersion)
2926
}
30-
dChannel := formChannel(operatorName, defaultChannel, bundleVersions)
27+
dChannel := formChannel(operatorName, channelName, bundleVersions)
3128

3229
dBundle := formBundle(operatorName, bundleRefsVersions)
3330

@@ -42,7 +39,7 @@ func CreateFBC(operatorName, defaultChannel string, bundleRefsVersions map[strin
4239
// Forms package schema for the FBC
4340
func formPackage(pkgName string) declcfg.Package {
4441
packageFormed := declcfg.Package{
45-
Schema: SchemaPackage,
42+
Schema: declcfg.SchemaPackage,
4643
Name: pkgName,
4744
}
4845
return packageFormed
@@ -52,15 +49,16 @@ func formPackage(pkgName string) declcfg.Package {
5249
func formChannel(pkgName, channelName string, bundleVersions []string) declcfg.Channel {
5350
channelEntries := formChannelEntries(pkgName, bundleVersions)
5451
channelFormed := declcfg.Channel{
55-
Schema: SchemaChannel,
52+
Schema: declcfg.SchemaChannel,
5653
Name: channelName,
5754
Package: pkgName,
5855
Entries: channelEntries,
5956
}
6057
return channelFormed
6158
}
6259

63-
// Forms the uprade graph for the FBC
60+
// Forms the uprade graph for the FBC. Only forms replaces edge. For forming replaces edge,
61+
// bundleVersions are assumed to be in increasing version number order.
6462
func formChannelEntries(pkgName string, bundleVersions []string) []declcfg.ChannelEntry {
6563
channelEntries := make([]declcfg.ChannelEntry, 0, len(bundleVersions))
6664
for i, version := range bundleVersions {
@@ -83,7 +81,7 @@ func formBundle(pkgName string, imgRefsVersions map[string]string) []declcfg.Bun
8381
for imgRef, version := range imgRefsVersions {
8482
var properties []property.Property
8583
properties = append(properties, property.Property{
86-
Type: SchemaPackage,
84+
Type: declcfg.SchemaPackage,
8785
Value: json.RawMessage(fmt.Sprintf(`{"packageName": "%s", "version": "%s"}`, pkgName, version)),
8886
})
8987
properties = append(properties, property.Property{
@@ -92,7 +90,7 @@ func formBundle(pkgName string, imgRefsVersions map[string]string) []declcfg.Bun
9290
})
9391

9492
bundleFormed = append(bundleFormed, declcfg.Bundle{
95-
Schema: SchemaBundle,
93+
Schema: declcfg.SchemaBundle,
9694
Name: pkgName + ".v" + version,
9795
Package: pkgName,
9896
Image: imgRef,
@@ -102,7 +100,7 @@ func formBundle(pkgName string, imgRefsVersions map[string]string) []declcfg.Bun
102100
return bundleFormed
103101
}
104102

105-
// Writes the formed FBC into catalog.yaml file
103+
// Writes the formed FBC into catalog.yaml file in the path fbcFilePath
106104
func WriteFBC(fbc declcfg.DeclarativeConfig, fbcFilePath, fbcFileName string) error {
107105
var buf bytes.Buffer
108106
if err := declcfg.WriteYAML(fbc, &buf); err != nil {

test/operator-framework-e2e/generate_dockerfile.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import (
55
"text/template"
66
)
77

8-
// GenerateDockerFile generates Dockerfile and its contents for a given set of yaml files
8+
// GenerateDockerFile generates Dockerfile and its contents for the data in yamlFolderName
99
func generateDockerFile(dockerFilePath, yamlFolderName, dockerfileTmpl string) error {
1010
t, err := template.New("dockerfile").Parse(dockerfileTmpl)
1111
if err != nil {
@@ -26,14 +26,14 @@ func generateDockerFile(dockerFilePath, yamlFolderName, dockerfileTmpl string) e
2626
return err
2727
}
2828

29-
// GenerateCatalogDockerFile generates Dockerfile for the catalog
30-
func generateCatalogDockerFile(dockerFilePath, yamlFolderName string) error {
31-
return generateDockerFile(dockerFilePath, yamlFolderName, catalogDockerfileTmpl)
29+
// GenerateCatalogDockerFile generates Dockerfile for the catalog content in catalogFolderName
30+
func generateCatalogDockerFile(dockerFilePath, catalogFolderName string) error {
31+
return generateDockerFile(dockerFilePath, catalogFolderName, catalogDockerfileTmpl)
3232
}
3333

34-
// GenerateBundleDockerFile generates Dockerfile for the bundle
35-
func generateBundleDockerFile(dockerFilePath, yamlFolderName string) error {
36-
return generateDockerFile(dockerFilePath, yamlFolderName, bundleDockerfileTmpl)
34+
// GenerateBundleDockerFile generates Dockerfile for the bundle content in bundleFolderName
35+
func generateBundleDockerFile(dockerFilePath, bundleFolderName string) error {
36+
return generateDockerFile(dockerFilePath, bundleFolderName, bundleDockerfileTmpl)
3737
}
3838

3939
// Dockerfile templates

0 commit comments

Comments
 (0)