Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[sdk-stamps] add sdk stamps to bundle images #3120

Merged

Conversation

varshaprasad96
Copy link
Member

@varshaprasad96 varshaprasad96 commented May 27, 2020

Description of the change:
Add SDK related metric labels and annotations to bundle images

Motivation for the change:
To enable OLM track SDK Operators with help of these stamps on bundle resources.

Things to do:

  • Add stamps to bundle.Dockerfile and annotaions.yaml
  • Add stamps csv (during generate csv command)
    • Write test cases to verify the stamps on CSV
  • Add stamps to crd (during generate crds command)

Note:
Adding of labels to CRDs through controller-gen for new project layouts will be done in a new PR. Adding labels through built-in crd-gen for legacy layouts is removed from this PR as of now, and will be included in a follow up later.

Co-authored by: @estroz

@openshift-ci-robot openshift-ci-robot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label May 27, 2020
@varshaprasad96
Copy link
Member Author

@estroz @joelanford @jmrodri Would be helpful to have initial reviews

return filepath.Join(filepath.Dir(manifestsDir), bundle.MetadataDir, bundle.AnnotationsFile)
}

func getSDKMetricsContent() map[string]string {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added this function here so that it remains consistent by adding scorecard labels and metrics labels in create.go

Copy link
Member

@estroz estroz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initial review

internal/util/projutil/project_util.go Outdated Show resolved Hide resolved
internal/util/projutil/project_util.go Outdated Show resolved Hide resolved
internal/util/projutil/sdk_metrics_util.go Outdated Show resolved Hide resolved
internal/util/projutil/sdk_metrics_util.go Outdated Show resolved Hide resolved
internal/util/projutil/sdk_metrics_util.go Outdated Show resolved Hide resolved
internal/util/projutil/sdk_metrics_util.go Outdated Show resolved Hide resolved
internal/util/projutil/sdk_metrics_util.go Outdated Show resolved Hide resolved
internal/util/projutil/sdk_metrics_util.go Outdated Show resolved Hide resolved
@varshaprasad96 varshaprasad96 force-pushed the sdk-stamps/metrics branch 4 times, most recently from 7f7752e to 3f5c365 Compare June 3, 2020 02:08
@varshaprasad96 varshaprasad96 changed the title [wip] add sdk stamps to bundle images [sdk-stamps] add sdk stamps to bundle images Jun 3, 2020
@openshift-ci-robot openshift-ci-robot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jun 3, 2020
@varshaprasad96 varshaprasad96 force-pushed the sdk-stamps/metrics branch 2 times, most recently from 64bc768 to c92d21b Compare June 3, 2020 17:27
registrybundle "github.com/operator-framework/operator-registry/pkg/lib/bundle"
log "github.com/sirupsen/logrus"
"gopkg.in/yaml.v2"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"gopkg.in/yaml.v2"
"sigs.k8s.io/yaml"

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switching over to gopkg.in/yaml.v2. k8s-yaml interprets and appends the name of the field defined in yaml struct while marshaling and unmarshaling, whereas gopkg-yaml uses the yaml annotation defined in the struct. Example - https://play.golang.org/p/uQ_J4oZBbCR

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are trying to remove the "gopkg.in/yaml.v2". See : #2790
So, we should not add new code with it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The operator-registry is still using gopkg.in/yaml.v2 for generation of annotation.yaml. Here: https://github.com/operator-framework/operator-registry/blob/master/pkg/lib/bundle/generate.go#L12. And this function is trying to essentially replicate their process.

This comment was marked as outdated.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The unit tests do pass with "sigs.k8s.io/yaml". However, it would fail in the scenario where we create bundle image using files already present on disk.
Explanation is as below:

To reproduce the scenario:

  1. First create bundle files on disk with operator-sdk bundle create command and --generate-only flag.
  2. Now create bundle image and push it to the registry (ie use the eg. command: operator-sdk bundle create quay.io/example/memcached-operator:latest --directory path/to/manifests --package memcached-operator)

The error which we get would be:
Unmatched number of fields. Expected 6 vs existing 0. It fails here.

Cause of error:
When we use sigs.k8s.io/yaml, the key in annotations.yaml file would be the name of the field in AnnotationMetadata struct. The annotations.yaml which would be rewritten after adding the sdk stamps, would be like this:

Annotations:
  operators.operatorframework.io.bundle.channel.default.v1: stable
  operators.operatorframework.io.bundle.channels.v1: stable
  operators.operatorframework.io.bundle.manifests.v1: manifests/

Now during unmarshalling, ie here, it would not be able to interpret this yaml because it has the key Annotations not annotations. The gopkg at operator-registry expects the key in yaml file to be annotations.

If we use "gopkg.in/yaml.v2", the annotations.yaml which we re-write, would take the marker value (name of field) defined in yaml struct, yaml:"annotations" as it does in operator-registry and it would unmarshall properly.

I have created a simple example to show the difference between both the packages in this playground: https://play.golang.org/p/uQ_J4oZBbCR

This scenario is being checked in one of the CI tests.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See that your example will work if we replace the yaml for JSON

Something int yaml:"somethingGreat,omitempty"
With
Something int json:"somethingGreat,omitempty"

Then, see that also it will work with yaml if we replace the Unmarshal/Marchal for JSONToYAML/YAMLToJSON. See: https://play.golang.org/p/D2guhgb7cvc

In SDK, we read/update/delete the files and use the lib to verify them. In this way, no matter the dep/lib that we use to manipulate it, all should work fine if at the end we have the same result. Then, I understand that if we change the impl here to use the above it should work.

However, if you still just facing problems with. could you please add a comment with a //todo: replace it for "sigs.k8s.io/yaml". Operator-registry defines the annotations with yaml format?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding //todo: because of the dependency on operator-registry. OR defines annotations.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could likely be fixed by adding json:"annotations" to the struct tag in the operator-registry repo.

So it would look like:

type AnnotationMetadata struct {
	Annotations map[string]string `yaml:"annotations" json:"annotations"``
}

Obviously this would require an upstream PR to be merged and for us to update our dependency to a new commit/version, so we shouldn't block this PR for that.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will continue with above and have an upstream PR in parallel. Ill have a follow-up PR to remove the TODO.

@varshaprasad96 varshaprasad96 force-pushed the sdk-stamps/metrics branch 3 times, most recently from cd3ecd0 to 594bda2 Compare June 4, 2020 03:06
@varshaprasad96 varshaprasad96 force-pushed the sdk-stamps/metrics branch 4 times, most recently from 06e58be to 5509ab0 Compare June 6, 2020 23:48
Copy link
Member

@estroz estroz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few minor changes required

internal/registry/validate.go Outdated Show resolved Hide resolved
internal/util/projutil/sdk_stamps_util.go Outdated Show resolved Hide resolved
internal/util/projutil/sdk_stamps_util.go Outdated Show resolved Hide resolved
@varshaprasad96 varshaprasad96 force-pushed the sdk-stamps/metrics branch 2 times, most recently from eaca440 to c0a166a Compare June 23, 2020 02:43
internal/util/projutil/sdk_stamps_util_test.go Outdated Show resolved Hide resolved
internal/util/projutil/sdk_stamps_util_test.go Outdated Show resolved Hide resolved
cmd/operator-sdk/bundle/create.go Outdated Show resolved Hide resolved
@varshaprasad96 varshaprasad96 force-pushed the sdk-stamps/metrics branch 2 times, most recently from 2e93e4e to 3ee2066 Compare June 24, 2020 03:21
annotationsDir = outputDir + bundle.MetadataDir
}

if genutil.IsNotExist(bundle.DockerFile) || genutil.IsNotExist(annotationsDir) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To make this check robust, you need to check and write to each file individually, since one may exist without the other.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but I was thinking of rewriting both of them even if one exists, because until tweaked manually GenerateFunc of OR is going to write both and also generate bundle provides a --metadata option which writes both. In the sense, if there is a scenario where only one of them exists, doesn't it mean that either it has been manually deleted or there is some error (though I assume its taken care of in respective commands create/generate) and wouldn't rewriting both of them together in a clean state be a better option in such a scenario?

Copy link
Member

@estroz estroz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm

@openshift-ci-robot openshift-ci-robot added the lgtm Indicates that a PR is ready to be merged. label Jun 30, 2020
@varshaprasad96 varshaprasad96 merged commit 87e1fc4 into operator-framework:master Jun 30, 2020
@varshaprasad96 varshaprasad96 deleted the sdk-stamps/metrics branch July 13, 2020 20:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
lgtm Indicates that a PR is ready to be merged.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants