###### tags: `tektoncd` `tep` <!-- **Note:** When your TEP is complete, all of these comment blocks should be removed. To get started with this template: - [ ] **Fill out this file as best you can.** At minimum, you should fill in the "Summary", and "Motivation" sections. These should be easy if you've preflighted the idea of the TEP with the appropriate Working Group. - [ ] **Create a PR for this TEP.** Assign it to people in the SIG that are sponsoring this process. - [ ] **Merge early and iterate.** Avoid getting hung up on specific details and instead aim to get the goals of the TEP clarified and merged quickly. The best way to do this is to just start with the high-level sections and fill out details incrementally in subsequent PRs. Just because a TEP is merged does not mean it is complete or approved. Any TEP marked as a `proposed` is a working document and subject to change. You can denote sections that are under active debate as follows: ``` <<[UNRESOLVED optional short context or usernames ]>> Stuff that is being argued. <<[/UNRESOLVED]>> ``` When editing TEPS, aim for tightly-scoped, single-topic PRs to keep discussions focused. If you disagree with what is already in a document, open a new PR with suggested changes. If there are new details that belong in the TEP, edit the TEP. Once a feature has become "implemented", major changes should get new TEPs. The canonical place for the latest set of instructions (and the likely source of this file) is [here](/teps/NNNN-TEP-template/README.md). --> # TEP-NNNN: Tekton OCI bundles <!-- toc --> - [Summary](#summary) - [Motivation](#motivation) - [Goals](#goals) - [Non-Goals](#non-goals) - [Requirements](#requirements) - [Proposal](#proposal) - [Contract](#contract) - [User Stories (optional)](#user-stories-optional) - [Risks and Mitigations](#risks-and-mitigations) - [Design Details](#design-details) - [Test Plan](#test-plan) - [Drawbacks](#drawbacks) - [Alternatives](#alternatives) <!-- /toc --> ## Summary This proposal is to be able to bundle Tasks (and Pipelines, and Resources, and potentially other future config objects) into an [OCI Artifact](https://github.com/opencontainers/artifacts), pushed to an image registry, and referenced from that registry. This is a TEP for the **Spec** of the Tekton OCI bundle that were discussed in the following docs: - [Tekton OCI Image Catalog](https://docs.google.com/document/d/1zUVrIbGZh2R9dawKQ9Hm1Cx3GevKIfOcRO3fFLdmBDc/edit#heading=h.tp9mko2koenr) - [Tekton OCI Image Design](https://docs.google.com/document/d/1lXF_SvLwl6OqqGy8JbpSXRj4hWJ6CSImlxlIl4V9rnM/edit?pl=1#) This will be based from the knowledge acquired on the [experimental oci project](https://github.com/tektoncd/experimental/tree/master/oci) we ran. ## Motivation Today, TaskRuns can be defined completely (user specifies `.spec.taskSpec.steps` etc.), or by referencing a Task that must have previously been defined in the cluster's API server (user specifies `.spec.taskRef.name` and optionally `.namespace` -- if a Task doesn't exist with the specified name in the TaskRun's namespace, we check if it's a ClusterTask). This is overly limiting. It makes versioning hard, and it makes rolling out changes to Task definitions hard. We can leverage existing tooling and infrastructure used for sharing OCI images. An OCI image is really just a format for a set of binary files that can be uploaded to a registry (think DockerHub) with a tagged version and digest. It can easily be used to version and share Tasks and other Tekton resources. ### Goals The goal of this TEP is to define the specification for the Tekton OCI bundles. The goal of the Tekton OCI bundles is to define a Spec on top of a known, widely used transport mechanisms, which are the OCI artifact (OCI images, …). ### Non-Goals How Tekton OCI bundles are used (referred to) in the different Tekton components is out of scope and will be the subject for an additional TEP. Some examples in the doc might suggest how we would reference those in Pipeline CRDs but they are only examples, not propositions. The tooling around Tekton OCI bundles is also out of scope. ## Requirements - Images have a defined format that allows Tasks, Pipelines, and any other Tekton specific types to be written in, and read out. - The spec should be documented well enough such that any user could write tooling to generate a valid Tekton Bundle ## Proposal When using a Tekton Bundle in a task or pipeline reference, the OCI artifact backing the bundle must adhere to the following contract. Our most important capability is enabling references of remote Tasks from within TaskRuns or Pipelines and Pipelines from within PipelineRuns. With that in mind, a little background on the OCI format is necessary. For a deeper understanding see https://github.com/opencontainers/image-spec. At its most basic an image is a manifest specifying a set of Layers referenced by a sha256 digest. Each Layer has a media type and can have annotations. Looking at other similar projects (eg Helm 3) and building off of the knowledge from our experiment, we have arrived at the following spec: - An image will store each resource as a new layer This allows us to quickly store and retrieve individual resources because we can key the layer they reside in against its metadata - Each layer will have a org.opencontainers.image.title annotation (this a commonly used annotation: link) that contains the ObjectMetadata.Name field of the resource - Each layer will have a cdf.tekton.image.kind annotation which specifies the Kind of the resource. For example Kind: Task would become “task” and Kind: Pipeline would become “pipeline”. - Each layer will have a cdf.tekton.image.apiVersion annotation which specifies the apiVersion of the object (eg, v1beta1). This choice presents some tradeoffs: - Two objects of the same {name, type, apiVersion} will be rejected. This is purposeful because it replicates existing in-cluster functionality. You wouldn’t be able to store two Tekton Tasks of the same name and apiVersion in a namespace so to make the task references easier to reason about, we enforce the same characteristic on the images. - We are not using any metadata about how the task was generated such as the name of any tooling, the location of the task definition on disk when it was uploaded (like a file path), etc. Nothing prevents us from adding this metadata in the future but for a better user experience and to make the feature easier to reason about, we choose not to use that metadata when referencing a remote image right now. We do not add a custom MIME type. This is something that helm does do but it presents a challenge of needing to get most registries to support this mime type. Most will simply reject it as one they do not understand which presents a challenge to adoption. We can always add this later but we can still do all of the same things with the default MIME type. ### Contract Only Tekton CRDs (eg, `Task` or `Pipeline`) may reside in a Tekton Bundle used as a Tekton bundle reference.Each layer of the image must map 1:1 with a single Tekton resource.Each layer must contain the following annotations: - `org.opencontainers.image.title` =>`ObjectMeta.Name` of the resource - `cdf.tekton.image.kind` => `TypeMeta.Kind` of the resource, all lowercased (eg, `task`) - `cdf.tekton.image.apiVersion` => `TypeMeta.APIVersion` of the resource (eg "tekton.dev/v1alpha1") Each { `apiVersion`, `kind`, `title` } must be unique in the image. No resources of the same version and kind can be named the same. The contents of each layer must be the parsed YAML of the corresponding Tekton resource. If the resource is missing any identifying fields (missing an `apiVersion` for instance) than it will not be parseable. ### User Stories (optional) <!-- Detail the things that people will be able to do if this TEP is implemented. Include as much detail as possible so that people can understand the "how" of the system. The goal here is to make this feel real for users without getting bogged down. --> **To be completed** ### Risks and Mitigations <!-- What are the risks of this proposal and how do we mitigate. Think broadly. For example, consider both security and how this will impact the larger kubernetes ecosystem. How will security be reviewed and by whom? How will UX be reviewed and by whom? Consider including folks that also work outside the WGs or subproject. --> **To be completed** ## Design Details <!-- This section should contain enough information that the specifics of your change are understandable. This may include API specs (though not always required) or even code snippets. If there's any ambiguity about HOW your proposal will be implemented, this is the place to discuss them. --> **To be completed** ## Test Plan <!-- **Note:** *Not required until targeted at a release.* Consider the following in developing a test plan for this enhancement: - Will there be e2e and integration tests, in addition to unit tests? - How will it be tested in isolation vs with other components? No need to outline all of the test cases, just the general strategy. Anything that would count as tricky in the implementation and anything particularly challenging to test should be called out. All code is expected to have adequate tests (eventually with coverage expectations). --> **To be completed** ## Drawbacks <!-- Why should this TEP _not_ be implemented? --> **To be completed** ## Alternatives <!-- What other approaches did you consider and why did you rule them out? These do not need to be as detailed as the proposal, but should include enough information to express the idea and why it was not acceptable. --> **To be completed**