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 PersistentVolumeClaim
shared with other Tasks, or simply an emptyDir
that is discarded when the TaskRun
completes.
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 TaskRun
might use a PersistentVolumeClaim
which is pre-populated withdata for the Task
to process. In both scenarios the Task's
Workspace
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 Workspace
and 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 workspacedescription
- An informative string describing the purpose of theWorkspace
readOnly
- A boolean declaring whether theTask
will write to theWorkspace
.mountPath
- A path to a location on disk where the workspace will be available toSteps
. Relativepaths will be prepended with/workspace
. If amountPath
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 manyWorkspaces
as it needs. - A
readOnly
Workspace
will have its volume mounted as read-only. Attempting to writeto areadOnly
Workspace
will result in errors and failedTaskRuns
. mountPath
can be either absolute or relative. Absolute paths start with/
and relative pathsstart with the name of a directory. For example, amountPath
of"/foobar"
is absolute and exposestheWorkspace
at/foobar
inside theTask's
Steps
, but amountPath
of"foobar"
is relative andexposes theWorkspace
at/workspace/foobar
.
Below is an example Task
definition that includes a Workspace
called messages
to which the Task
writes a message:
spec:
steps:
- name: write-message
image: ubuntu
script: |
#!/usr/bin/env bash
set -xe
echo hello! > $(workspaces.messages.path)/message
workspaces:
- name: messages
description: The folder where we write the message to
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 aWorkspace
where<name>
is the name of theWorkspace
.$(workspaces.<name>.volume)
- specifies the name of theVolume
provided for aWorkspace
where<name>
is the name of theWorkspace
.
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 theWorkspace
within theTask
for which theVolume
is being providedsubPath
- An optional subdirectory on theVolume
to store data for thatWorkspace
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 workspace
called myworkspace
. It exposes only the subdirectory my-subdir
from that PersistentVolumeClaim
:
workspaces:
- name: myworkspace
persistentVolumeClaim:
claimName: mypvc
subPath: my-subdir
In the example below, an emptyDir
is provided for a Task’s workspace
called myworkspace
:
workspaces:
- name: myworkspace
emptyDir: {}
In the example below, a ConfigMap
named my-configmap
is used for a Workspace
named myworkspace
declared inside a Task
:
workspaces:
- name: myworkspace
configmap:
name: my-configmap
In this example, a Secret
named my-secret
is used for a Workspace
named myworkspace
declared inside a Task
:
workspaces:
- name: myworkspace
secret:
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 yourPipelineRuns
will be providing. Use theworkspaces
field tospecify the targetWorkspaces
in yourPipeline
definition as shown below. Each entry in thelist must have a unique name. - A mapping of
Workspace
names between thePipeline
and theTask
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-code
Task
, then as the src
workspace declared by the commit
Task
. If the Workspace
provided by the PipelineRun
is a PersistentVolumeClaim
then these two Tasks
can sharedata within that Workspace
.
spec:
workspaces:
- name: pipeline-ws1 # Name of the workspace in the Pipeline
tasks:
- name: use-ws-from-pipeline
taskRef:
name: gen-code # gen-code expects a workspace named "output"
workspaces:
- name: output
workspace: pipeline-ws1
- name: use-ws-again
taskRef:
name: commit # commit expects a workspace named "src"
workspaces:
- name: src
workspace: pipeline-ws1
runAfter:
- 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 Tasks
will 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 PersistentVolumeClaim
for 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 theWorkspace
specified in thePipeline
definition for which a volume is being provided.subPath
- (optional) a directory on the volume that will store thatWorkspace's
data. This directory must exist at thetime theTaskRun
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 Workspace
named myworkspace
declared in a Pipeline
. It exposes only the subdirectory my-subdir
from that PersistentVolumeClaim
:
workspaces:
- name: myworkspace
persistentVolumeClaim:
claimName: mypvc
subPath: my-subdir
In the example below, a ConfigMap
named my-configmap
is used for a Workspace
named myworkspace
declared in a Pipeline
:
workspaces:
- name: myworkspace
configmap:
name: my-configmap
In the example below, a Secret
named my-secret
is used for a Workspace
named myworkspace
declared in a Pipeline
:
workspaces:
- name: myworkspace
secret:
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 aWorkspace
must exist prior to submitting theTaskRun
. 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 aWorkspace
must exist prior to submitting theTaskRun
. 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
: