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

Oci tool: makes use of oci-artifacts to store and retrieve Tekton resources #461

Merged
merged 7 commits into from
Feb 17, 2020

Conversation

sthaha
Copy link
Member

@sthaha sthaha commented Feb 12, 2020

Changes

This PR relates to the #1839: Versioning of Tasks discussion. The PR adds an oci tool that is currently able to store and retrieve Tekton resource (Pipeline, Task, ClusterTask...) from a registry.

Credits: Thanks for Pierre Tasci @pierretasci for the initial implementation.

Submitter Checklist

These are the criteria that every PR should meet, please check them off as you
review them:

See the contribution guide
for more details.

@googlebot
Copy link

We found a Contributor License Agreement for you (the sender of this pull request), but were unable to find agreements for all the commit author(s) or Co-authors. If you authored these, maybe you used a different email address in the git commits than was used to sign the CLA (login here to double check)? If these were authored by someone else, then they will need to sign a CLA as well, and confirm that they're okay with these being contributed to Google.
In order to pass this check, please resolve this problem and then comment @googlebot I fixed it.. If the bot doesn't comment, it means it doesn't think anything has changed.

ℹ️ Googlers: Go here for more info.

@tekton-robot tekton-robot added size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. do-not-merge/invalid-owners-file Indicates that a PR should not merge because it has an invalid OWNERS file in it. labels Feb 12, 2020
This contains a POC of a cli that can push and pull tekton resources
as OCI artifacts from a supported registry.

Credits: Thanks to Pierre Tasci for this patch.

Signed-off-by: Sunil Thaha <sthaha@redhat.com>
@googlebot
Copy link

CLAs look good, thanks!

ℹ️ Googlers: Go here for more info.

@tekton-robot tekton-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Feb 12, 2020
@tekton-robot tekton-robot removed the do-not-merge/invalid-owners-file Indicates that a PR should not merge because it has an invalid OWNERS file in it. label Feb 12, 2020
}

// getNameParts will attempt to return a { "hostname/image-name", "tag or sha" } list of the provided image name. There maybe less than the full 2 elements if one of the parts isn't included in the original name.
func getNameParts(name string) (*ImageReference, error) {
Copy link
Member

Choose a reason for hiding this comment

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

The go-containerregistry library has a pretty solid set of methods for this kind of name parsing, I'd love to avoid having to maintain it in two places.

https://godoc.org/github.com/google/go-containerregistry/pkg/name#ParseReference

}

// ReadPaths will recursively search each file path for Tekton resources and return the parsed specs or an error.
func ReadPaths(filePaths []string) ([]ParsedTektonResource, error) {
Copy link
Member

Choose a reason for hiding this comment

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

It looks like a lot of these methods are only called from within this package, so they don't have to be exported.

Copy link
Contributor

Choose a reason for hiding this comment

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

I believe ReadPaths and ParsedTektonResource are the only exported members and they are referenced outside of the oci package inside of the action package. Perhaps there is a case to be made for re-organizing but this tends to follow a cobra cli layout as far as I can tell.

// entities in a single file).
var entities []string
switch ext := path.Ext(filePath); true {
case ext == ".yaml" || ext == ".yml":
Copy link
Member

Choose a reason for hiding this comment

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

I'm pretty sure there's a standard K8s package to universally decode K8s config files. Can we use that instead?

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Contributor

@pierretasci pierretasci Feb 17, 2020

Choose a reason for hiding this comment

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

The UniversalDeserializer is being used here: https://github.com/tektoncd/experimental/pull/461/files/28fc8d52254c72a62a82d422db91ff4ecaf11b0a#diff-be720fcc306c3d06da4d0c6eac9ed71eR126 to decode the file contents and ensure they are parseable as Tekton crds.

The problem is that the deserializer, AFAIK, will only parse a single resource from a set of contents even if the file is a --- separated yaml config or a json array. We want to allow parsing multiple resources from a single file. If we take a look at how kubectl accomplishes this in the cli-runtime it is a bit more roundabout than what is trying to be accomplished here: https://github.com/kubernetes/kubectl/blob/4e4ec7cb5beac1fe75fd4be05d77c65030c30088/pkg/cmd/apply/apply.go#L323

To that end, for the first iteration of a tool that is meant just to be a POC, it might be worthwhile to keep the logic simple and more bespoke while we figure out how Tekton will support bundling these images. Perhaps we decide only Catalog CRDs should be bundled and we don't need parsing input at all"

)

func init() {
orascontext.GetLogger(context.Background()).Logger.SetLevel(logrus.ErrorLevel)
Copy link
Member

Choose a reason for hiding this comment

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

If we expect/hope this code will end up in either tkn or Tekton cobtrollers we should try to standardize on the logging used in those codebases, I don't think they use logrus today.

Copy link
Contributor

Choose a reason for hiding this comment

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

I believe this is actually just here to suppress the built-in logger of the oras package which spits out warnings for using a custom mime that isn't publicly registered anywhere. I don't think this PR specifies a logger and is, unfortunately, only importing logrus to set the log level.

resolver := docker.NewResolver(docker.ResolverOptions{})
memoryStore := orascontent.NewMemoryStore()

_, _, err := oras.Pull(
Copy link
Member

Choose a reason for hiding this comment

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

go-containerregistry also has pretty straightforward methods for pulling and pushing, which are already used in Tekton. Can we try to use those to make this easier to integrate down the line?

@imjasonh
Copy link
Member

imjasonh commented Feb 17, 2020

Cc @jonjohnsonjr

Copy link
Contributor

@pierretasci pierretasci left a comment

Choose a reason for hiding this comment

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

I think there is a case to be made here for exploring using go-containerregistry instead of oras if that is what Tekton already uses. Perhaps that can be done as a follow on exploration since this code as-is accomplishes the functionality intended.

// entities in a single file).
var entities []string
switch ext := path.Ext(filePath); true {
case ext == ".yaml" || ext == ".yml":
Copy link
Contributor

@pierretasci pierretasci Feb 17, 2020

Choose a reason for hiding this comment

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

The UniversalDeserializer is being used here: https://github.com/tektoncd/experimental/pull/461/files/28fc8d52254c72a62a82d422db91ff4ecaf11b0a#diff-be720fcc306c3d06da4d0c6eac9ed71eR126 to decode the file contents and ensure they are parseable as Tekton crds.

The problem is that the deserializer, AFAIK, will only parse a single resource from a set of contents even if the file is a --- separated yaml config or a json array. We want to allow parsing multiple resources from a single file. If we take a look at how kubectl accomplishes this in the cli-runtime it is a bit more roundabout than what is trying to be accomplished here: https://github.com/kubernetes/kubectl/blob/4e4ec7cb5beac1fe75fd4be05d77c65030c30088/pkg/cmd/apply/apply.go#L323

To that end, for the first iteration of a tool that is meant just to be a POC, it might be worthwhile to keep the logic simple and more bespoke while we figure out how Tekton will support bundling these images. Perhaps we decide only Catalog CRDs should be bundled and we don't need parsing input at all"

)

func init() {
orascontext.GetLogger(context.Background()).Logger.SetLevel(logrus.ErrorLevel)
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe this is actually just here to suppress the built-in logger of the oras package which spits out warnings for using a custom mime that isn't publicly registered anywhere. I don't think this PR specifies a logger and is, unfortunately, only importing logrus to set the log level.

}

// ReadPaths will recursively search each file path for Tekton resources and return the parsed specs or an error.
func ReadPaths(filePaths []string) ([]ParsedTektonResource, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe ReadPaths and ParsedTektonResource are the only exported members and they are referenced outside of the oci package inside of the action package. Perhaps there is a case to be made for re-organizing but this tends to follow a cobra cli layout as far as I can tell.

@vdemeester
Copy link
Member

I think there is a case to be made here for exploring using go-containerregistry instead of oras if that is what Tekton already uses. Perhaps that can be done as a follow on exploration since this code as-is accomplishes the functionality intended.

I would definitely vote for that 👼 This is the experimental repository, it's meant to be experiments and to be simpler to get stuff in 👼

@vdemeester
Copy link
Member

/cc @abayer @afrittoli @bobcatfish for a 2nd approval/lgtm 👼

@imjasonh
Copy link
Member

/lgtm
/approve

+1 for getting it merged first as a POC, sorry if my comments made it seem like we needed to get those in ASAP. I can send some PRs to see what it looks like using go-containerregistry.

@tekton-robot tekton-robot added the lgtm Indicates that a PR is ready to be merged. label Feb 17, 2020
@tekton-robot
Copy link

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: ImJasonH, vdemeester

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@tekton-robot tekton-robot merged commit fc335c0 into tektoncd:master Feb 17, 2020
@imjasonh
Copy link
Member

Re: supporting yamls with ---s I think it’d be fine to just prohibit those for the time being, and require inputs to be one per file. But again, we can discuss in a follow up PR, after this is merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. lgtm Indicates that a PR is ready to be merged. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants