Workspaces

Overview

Workspaces allow Tasks to declare parts of the filesystem that need to be providedat runtime by TaskRuns. A TaskRun can make these parts of the filesystem availablein many ways: using a read-only ConfigMap or Secret, a PersistentVolumeClaimshared with other Tasks, or simply an emptyDir that is discarded when the TaskRuncompletes.

Workspaces are similar to Volumes except that they allow a Task authorto defer to users and their TaskRuns when deciding which class of storage to use.

Workspaces can serve the following purposes:

  • Storage of inputs and/or outputs
  • Sharing data among Tasks
  • A mount point for credentials held in Secrets
  • A mount point for configurations held in ConfigMaps
  • A mount point for common tools shared by an organization
  • A cache of build artifacts that speed up jobs

Workspaces in Tasks and TaskRuns

Tasks specify where a Workspace resides on disk for its Steps. Atruntime, a TaskRun provides the specific details of the Volume that ismounted into that Workspace.

This separation of concerns allows for a lot of flexibility. For example, in isolation,a single TaskRun might simply provide an emptyDir volume that mounts quicklyand disappears at the end of the run. In a more complex system, however, a TaskRunmight use a PersistentVolumeClaim which is pre-populated withdata for the Task to process. In both scenarios the Task'sWorkspace declaration remains the same and only the runtimeinformation in the TaskRun changes.

Workspaces in Pipelines and PipelineRuns

A Pipeline can use Workspaces to show how storage will be shared throughits Tasks. For example, Task A might clone a source repository onto a Workspaceand Task B might compile the code that it finds in that Workspace. It’sthe Pipeline's job to ensure that the Workspace these two Tasks use is thesame, and more importantly, that the order in which they access the Workspace iscorrect.

PipelineRuns perform mostly the same duties as TaskRuns - they provide thespecific Volume information to use for the Workspaces used by each Pipeline.PipelineRuns have the added responsibility of ensuring that whatever Volume type theyprovide can be safely and correctly shared across multiple Tasks.

Configuring Workspaces

This section describes how to configure one or more Workspaces in a TaskRun.

Using Workspaces in Tasks

To configure one or more Workspaces in a Task, add a workspaces list with each entry using the following fields:

  • name - (required) A unique string identifier that can be used to refer to the workspace
  • description - An informative string describing the purpose of the Workspace
  • readOnly - A boolean declaring whether the Task will write to the Workspace.
  • mountPath - A path to a location on disk where the workspace will be available to Steps. Relativepaths will be prepended with /workspace. If a mountPath is not provided the workspacewill be placed by default at /workspace/<name> where <name> is the workspace’sunique name.

Note the following:

  • A Task definition can include as many Workspaces as it needs.
  • A readOnly Workspace will have its volume mounted as read-only. Attempting to writeto a readOnly Workspace will result in errors and failed TaskRuns.
  • mountPath can be either absolute or relative. Absolute paths start with / and relative pathsstart with the name of a directory. For example, a mountPath of "/foobar" is absolute and exposesthe Workspace at /foobar inside the Task's Steps, but a mountPath of "foobar" is relative andexposes the Workspace at /workspace/foobar.

Below is an example Task definition that includes a Workspace called messages to which the Task writes a message:

  1. spec:
  2. steps:
  3. - name: write-message
  4. image: ubuntu
  5. script: |
  6. #!/usr/bin/env bash
  7. set -xe
  8. echo hello! > $(workspaces.messages.path)/message
  9. workspaces:
  10. - name: messages
  11. description: The folder where we write the message to
  12. mountPath: /custom/path/relative/to/root

Using Workspace variables in Tasks

The following variables make information about Workspaces available to Tasks:

  • $(workspaces.<name>.path) - specifies the path to a Workspacewhere <name> is the name of the Workspace.
  • $(workspaces.<name>.volume)- specifies the name of the Volumeprovided for a Workspace where <name> is the name of the Workspace.

Mapping Workspaces in Tasks to TaskRuns

A TaskRun that executes a Task containing a workspaces list must bindthose workspaces to actual physical Volumes. To do so, the TaskRun includesits own workspaces list. Each entry in the list contains the following fields:

  • name - (required) The name of the Workspace within the Task for which the Volume is being provided
  • subPath - An optional subdirectory on the Volume to store data for that Workspace

The entry must also include one VolumeSource. See Using VolumeSources with Workspaces for more information.

Caution:- The subPath must exist on the Volume before the TaskRun executes or the execution will fail.- The Workspaces declared in a Task must be available when executing the associated TaskRun. Otherwise, the TaskRun will fail.

Examples of TaskRun definitions using Workspaces

The following examples illustrate how to specify Workspaces in your TaskRun definition.For a more in-depth example, see Workspaces in a TaskRun.

In the example below, an existing PersistentVolumeClaim called mypvc is used for a Task’s workspacecalled myworkspace. It exposes only the subdirectory my-subdir from that PersistentVolumeClaim:

  1. workspaces:
  2. - name: myworkspace
  3. persistentVolumeClaim:
  4. claimName: mypvc
  5. subPath: my-subdir

In the example below, an emptyDiris provided for a Task’s workspace called myworkspace:

  1. workspaces:
  2. - name: myworkspace
  3. emptyDir: {}

In the example below, a ConfigMap named my-configmap is used for a Workspacenamed myworkspace declared inside a Task:

  1. workspaces:
  2. - name: myworkspace
  3. configmap:
  4. name: my-configmap

In this example, a Secret named my-secret is used for a Workspacenamed myworkspace declared inside a Task:

  1. workspaces:
  2. - name: myworkspace
  3. secret:
  4. secretName: my-secret

For a more in-depth example, see workspace.yaml.

Using Workspaces in Pipelines

While individual Tasks declare the Workspaces they need to run, the Pipeline decideswhich Workspaces are shared among its Tasks. To declare shared Workspaces in a Pipeline,you must add the following information to your Pipeline definition:

  • A list of Workspaces that your PipelineRuns will be providing. Use the workspaces field tospecify the target Workspaces in your Pipeline definition as shown below. Each entry in thelist must have a unique name.
  • A mapping of Workspace names between the Pipeline and the Task definitions.

The example below defines a Pipeline with a single Workspace named pipeline-ws1. ThisWorkspace is bound in two Tasks - first as the output workspace declared by the gen-codeTask, then as the src workspace declared by the commit Task. If the Workspaceprovided by the PipelineRun is a PersistentVolumeClaim then these two Tasks can sharedata within that Workspace.

  1. spec:
  2. workspaces:
  3. - name: pipeline-ws1 # Name of the workspace in the Pipeline
  4. tasks:
  5. - name: use-ws-from-pipeline
  6. taskRef:
  7. name: gen-code # gen-code expects a workspace named "output"
  8. workspaces:
  9. - name: output
  10. workspace: pipeline-ws1
  11. - name: use-ws-again
  12. taskRef:
  13. name: commit # commit expects a workspace named "src"
  14. workspaces:
  15. - name: src
  16. workspace: pipeline-ws1
  17. runAfter:
  18. - use-ws-from-pipeline # important: use-ws-from-pipeline writes to the workspace first

Specifying Workspace order in a Pipeline

Sharing a Workspace between Tasks requires you to define the order in which those Taskswill be accessing that Workspace since different classes of storage have different limitsfor concurrent reads and writes. For example, a PersistentVolumeClaim might only allow asingle Task writing to it at once.

Warning: You must ensure that this order is correct. Incorrectly ordering can resultin a deadlock where multiple Task Pods are attempting to mount a PersistentVolumeClaimfor writing at the same time, which would cause the Tasks to time out.

To define this order, use the runAfter field in your Pipeline definition. For moreinformation, see the runAfter documentation.

Specifying Workspaces in PipelineRuns

For a PipelineRun to execute a Pipeline that includes one or more Workspaces, it needs tobind the Workspace names to physical volumes using its own workspaces field. Each entry inthis list must correspond to a Workspace declaration in the Pipeline. Each entry in theworkspaces list must specify the following:

  • name - (required) the name of the Workspace specified in the Pipeline definition for which a volume is being provided.
  • subPath - (optional) a directory on the volume that will store that Workspace's data. This directory must exist at thetime the TaskRun executes, otherwise the execution will fail.

The entry must also include one VolumeSource. See Using VolumeSources with Workspaces for more information.

Note: If the Workspaces specified by a Pipeline are not provided at runtime by a PipelineRun, that PipelineRun will fail.

Example PipelineRun definitions using Workspaces

The examples below illustrate how to specify Workspaces in your PipelineRuns. For a more in-depth example, see theWorkspaces in PipelineRun YAML sample.

In the example below, an existing PersistentVolumeClaim named mypvc is used for a Workspacenamed myworkspace declared in a Pipeline. It exposes only the subdirectory my-subdir from that PersistentVolumeClaim:

  1. workspaces:
  2. - name: myworkspace
  3. persistentVolumeClaim:
  4. claimName: mypvc
  5. subPath: my-subdir

In the example below, a ConfigMap named my-configmap is used for a Workspacenamed myworkspace declared in a Pipeline:

  1. workspaces:
  2. - name: myworkspace
  3. configmap:
  4. name: my-configmap

In the example below, a Secret named my-secret is used for a Workspacenamed myworkspace declared in a Pipeline:

  1. workspaces:
  2. - name: myworkspace
  3. secret:
  4. secretName: my-secret

Specifying VolumeSources in Workspaces

You can only use a single type of VolumeSource per Workspace entry. The configurationoptions differ for each type. Workspaces support the following fields:

emptyDir

The emptyDir field references an emptyDir volume which holdsa temporary directory that only lives as long as the TaskRun that invokes it. emptyDir volumes are not suitable for sharing data among Tasks within a Pipeline.However, they work well for single TaskRuns where the data stored in the emptyDir needs to be shared among the Steps of the Task and discarded after execution.

persistentVolumeClaim

The persistentVolumeClaim field references a persistentVolumeClaim volume.PersistentVolumeClaim volumes are a good choice for sharing data among Tasks within a Pipeline.

configMap

The configMap field references a configMap volume.Using a configMap as a Workspace has the following limitations:

  • configMap volume sources are always mounted as read-only. Steps cannot write to them and will error out if they try.
  • The configMap you want to use as a Workspace must exist prior to submitting the TaskRun.
  • configMaps are size-limited to 1MB.

secret

The secret field references a secret volume.Using a secret volume has the following limitations:

  • secret volume sources are always mounted as read-only. Steps cannot write to them and will error out if they try.
  • The secret you want to use as a Workspace must exist prior to submitting the TaskRun.
  • secret are size-limited to 1MB.

If you need support for a VolumeSource type not listed above, open an issue ora pull request.

More examples

See the following in-depth examples of configuring Workspaces: