Skip to content

Tanzu Supply Chains Component Architecture

A Component defines the API spec that is passed up to the supply chain, the Tekton pipeline run spec, inputs and outputs.

See hello-component for a basic example of a component.

Variables

If a component requires variable as inputs, their schema is defined under the component spec as shown below.

apiVersion: supply-chain.apps.tanzu.vmware.com/v1alpha1
kind: Component
...
spec:
  config:
  - path: spec.who-dis
    schema:
      type: object
      properties:
        name:
          type: string
          description: String input to be printed after "Hello "
          example: bob
      required:
        - name

When a supply chain is applied into the cluster all components schemas are aggregated together to form the API of the workload.

Inputs and Outputs

Tekton by design does not pass not pass data between workspace spaces and a workspace should be bound to a pipeline run. To get around this Tanzu Supply Chains use the container registry for inter-pipeline storage. If a component needs to store data to pass on to another component it needs to contain a system task that pushes the contents of a workspace to the container registry.

The result of the task includes the URL and sha of the image, which is passed back to via the pipelinerun to the stage and the workloadrun. Subsequent components must default the names of any inputs, then within the pipeline define the fetch steps which pull the inputs into the relevant workspace.

Output example

This example taken from the carvel-package component, which builds a Carvel package and pushes the manifest to the image repository.

The component maps the output to a container registry URL and digest generated by the pipeline.

component.yaml

apiVersion: supply-chain.apps.tanzu.vmware.com/v1alpha1
kind: Component
...
spec:
  ...
  outputs:
    - name: package
      type: package
      digest: $(pipeline.results.digest) # optional field. results.digest used by default
      url: $(pipeline.results.url) # optional field. results.url used by default

In the pipeline the store task expects a workspace called input, which it then pushes to the config repo defined by the workload. The secrets are handled by the standard Tekton mechanism for Docker or the namespace provisioner.

pipeline.yaml

apiVersion: tekton.dev/v1
kind: Pipeline
spec:
...
  tasks:
    ... # Some logic to populate the workspace `shared-data`
    - name: store
      runAfter:
        - previous-task
      params:
        - name: workload-name
          value: $(params.workload-name)
      taskRef:
        name: store-content-oci
      workspaces:
        - name: input
          workspace: shared-data
  results:
    - name: url
      description: url of the resulting source object you can use in your chain
      type: string
      value: $(tasks.store.results.url)
    - name: digest
      description: digest of the shipped content sent to 'url'
      type: string
      value: $(tasks.store.results.digest)

When building a supply chain using the carvel-package component, the outputs become available to all subsequent components in the supply chain.

Input example

This example taken from the deployer component, takes a Carvel package as an input and deploys it into the workload namespace.

To use the output of a previous component it must be called by name and type in the component definition. The pipelineRun definition then passes in the input as a variable named oci-image-with-yaml into the pipeline.

component.yaml

apiVersion: supply-chain.apps.tanzu.vmware.com/v1alpha1
kind: Component
...
spec:
  ...
  inputs:
    - name: package
      type: package
  pipelineRun:
  ...
  params:
    - name: oci-image-with-yaml
      value: $(inputs.package.url)
  workspaces:
      - name: shared-data
        volumeClaimTemplate:
          spec:
            accessModes:
              - ReadWriteOnce
            resources:
              requests:
                storage: 1Gi

The pipeline definition takes the oci-image-with-yaml variable from the pipelineRun and passes it down into the task which sets up the workspace.

The fetch-tgz-content-oci task is a TAP system task which will pull an OCI image and unpack it into a workspace. As with outputs, the secrets are handled by the standard Tekton mechanism for Docker or the namespace provisioner.

pipeline.yaml

apiVersion: tekton.dev/v1
kind: Pipeline
...
spec:
  params:
    - name: oci-image-with-yaml
      type: string
    ...
  workspaces:
    - name: shared-data
  tasks:
    - name: fetch-yaml
      workspaces:
        - name: store
          workspace: shared-data
      params:
        - name: url
          value: $(params.oci-image-with-yaml)
      taskRef:
        name: fetch-tgz-content-oci
    - name: deployer
      workspaces:
        - name: content
          workspace: shared-data
      ...
      taskRef:
        name: deployer
      runAfter:
        - fetch-yaml

PipelineRun

This section of the API partially replicates the Tekton PipelineRun API.

The example below taken from the deloyer OOB component takes variables from the input, calls the deployer pipeline by name, sets the UIDs and GIDs for the tasks and sets the workspace to use a dynamically created persistent volume.

apiVersion: supply-chain.apps.tanzu.vmware.com/v1alpha1
kind: Component
...
  pipelineRun:
    params:
      - name: oci-image-with-yaml
        value: $(inputs.package.url)
      ...
    pipelineRef:
      name: deployer
    taskRunTemplate:
      podTemplate:
        securityContext:
          fsGroup: 1000
          runAsGroup: 1000
          runAsUser: 1001
    workspaces:
      - name: shared-data
        volumeClaimTemplate:
          spec:
            accessModes:
              - ReadWriteOnce
            resources:
              requests:
                storage: 1Gi

When the stage is created it will create a PipelineRun from the template above.