Skip to content

Commit

Permalink
Merge pull request #1035 from alicerum/build-273
Browse files Browse the repository at this point in the history
Build-273 Volumes support to Build Strategies
  • Loading branch information
openshift-merge-robot authored May 11, 2022
2 parents 2a85872 + 3a8d642 commit 4dbe852
Show file tree
Hide file tree
Showing 32 changed files with 10,456 additions and 589 deletions.
4 changes: 4 additions & 0 deletions deploy/200-role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ rules:
resources: ['secrets']
verbs: ['get', 'list', 'watch']

- apiGroups: ['']
resources: ['configmaps']
verbs: ['list']

- apiGroups: ['']
resources: ['serviceaccounts']
verbs: ['get', 'list', 'watch', 'create', 'update', 'delete']
5,675 changes: 5,116 additions & 559 deletions deploy/crds/shipwright.io_buildruns.yaml

Large diffs are not rendered by default.

1,479 changes: 1,479 additions & 0 deletions deploy/crds/shipwright.io_builds.yaml

Large diffs are not rendered by default.

1,480 changes: 1,480 additions & 0 deletions deploy/crds/shipwright.io_buildstrategies.yaml

Large diffs are not rendered by default.

1,480 changes: 1,480 additions & 0 deletions deploy/crds/shipwright.io_clusterbuildstrategies.yaml

Large diffs are not rendered by default.

31 changes: 31 additions & 0 deletions docs/build.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ SPDX-License-Identifier: Apache-2.0
- [Defining the Builder or Dockerfile](#defining-the-builder-or-dockerfile)
- [Defining the Output](#defining-the-output)
- [Defining Retention Parameters](#defining-retention-parameters)
- [Defining Volumes](#defining-volumes)
- [BuildRun deletion](#BuildRun-deletion)

## Overview
Expand Down Expand Up @@ -571,6 +572,36 @@ An example of a user using both TTL and Limit retention fields. In case of such

**NOTE**: When changes are made to `retention.failedLimit` and `retention.succeededLimit` values, they come into effect as soon as the build is applied, thereby enforcing the new limits. On the other hand, changing the `retention.ttlAfterFailed` and `retention.ttlAfterSucceeded` values will only affect new buildruns. Old buildruns will adhere to the old TTL retention values. In case TTL values are defined in buildrun specifications as well as build specifications, priority will be given to the values defined in the buildrun specifications.

### Defining Volumes

`Builds` can declare `volumes`. They must override `volumes` defined by the according `BuildStrategy`. If a `volume`
is not `overridable` then the `BuildRun` will eventually fail.

`Volumes` follow the declaration of [Pod Volumes](https://kubernetes.io/docs/concepts/storage/volumes/), so
all the usual `volumeSource` types are supported.

Here is an example of `Build` object that overrides `volumes`:

```yaml
apiVersion: shipwright.io/v1alpha1
kind: Build
metadata:
name: build-name
spec:
source:
url: https://github.com/example/url
strategy:
name: buildah
kind: ClusterBuildStrategy
dockerfile: Dockerfile
output:
image: registry/namespace/image:latest
volumes:
- name: volume-name
configMap:
name: test-config
```

### Sources

Sources represent remote artifacts, as in external entities added to the build context before the actual Build starts. Therefore, you may employ `.spec.sources` to download artifacts from external repositories.
Expand Down
28 changes: 28 additions & 0 deletions docs/buildrun.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ SPDX-License-Identifier: Apache-2.0
- [Defining ParamValues](#defining-paramvalues)
- [Defining the ServiceAccount](#defining-the-serviceaccount)
- [Defining Retention Parameters](#defining-retention-parameters)
- [Defining Volumes](#defining-volumes)
- [Canceling a `BuildRun`](#canceling-a-buildrun)
- [Automatic `BuildRun` deletion](#automatic-buildrun-deletion)
- [Specifying Environment Variables](#specifying-environment-variables)
Expand Down Expand Up @@ -194,6 +195,33 @@ spec:

**NOTE** In case TTL values are defined in buildrun specifications as well as build specifications, priority will be given to the values defined in the buildrun specifications.

### Defining Volumes

`BuildRuns` can declare `volumes`. They must override `volumes` defined by the according `BuildStrategy`. If a `volume`
is not `overridable` then the `BuildRun` will eventually fail.

In case `Build` and `BuildRun` that refers to this `Build` override the same `volume`, one that is defined in the `BuildRun`
is the one used eventually.

`Volumes` follow the declaration of [Pod Volumes](https://kubernetes.io/docs/concepts/storage/volumes/), so
all the usual `volumeSource` types are supported.

Here is an example of `BuildRun` object that overrides `volumes`:

```yaml
apiVersion: shipwright.io/v1alpha1
kind: BuildRun
metadata:
name: buildrun-name
spec:
buildRef:
name: build-name
volumes:
- name: volume-name
configMap:
name: test-config
```

## Canceling a `BuildRun`

To cancel a `BuildRun` that's currently executing, update its status to mark it as canceled.
Expand Down
43 changes: 38 additions & 5 deletions docs/buildstrategies.md
Original file line number Diff line number Diff line change
Expand Up @@ -881,9 +881,42 @@ A Kubernetes administrator can further restrict the usage of annotations by usin

## Volumes and VolumeMounts

Build steps can declare a `volumeMount`, which allows data in the provided path to be shared across build steps.
When a `volumeMount` is declared, Shipwright will create an `emptyDir` volume with the corresponding name.
Build steps whose volume mounts share the same name will share the same underlying `emtpyDir` volume.
Build Strategies can declare `volumes`. These `volumes` can be referred to by the build steps using `volumeMount`.
Volumes in Build Strategy follow the declaration of [Pod Volumes](https://kubernetes.io/docs/concepts/storage/volumes/), so
all the usual `volumeSource` types are supported.

In a future release, build strategy authors will be able to use other volume types for the volume mounts.
When this feature is introduced, the volume and volume type will need to be explicitly declared.
Volumes can be overridden by `Build`s and `BuildRun`s, so Build Strategies' volumes support an `overridable` flag, which
is a boolean, and is `false` by default. In case volume is not overridable, `Build` or `BuildRun` that tries to override it,
will fail.

Build steps can declare a `volumeMount`, which allows them to access volumes defined by `BuildStrategy`, `Build` or `BuildRun`.

Here is an example of `BuildStrategy` object that defines `volumes` and `volumeMount`s:
```
apiVersion: shipwright.io/v1alpha1
kind: BuildStrategy
metadata:
name: buildah
spec:
buildSteps:
- name: build
image: quay.io/containers/buildah:v1.23.1
workingDir: $(params.shp-source-root)
command:
- buildah
- bud
- --tls-verify=false
- --layers
- -f
- $(build.dockerfile)
- -t
- $(params.shp-output-image)
- $(params.shp-source-context)
volumeMounts:
- name: varlibcontainers
mountPath: /var/lib/containers
volumes:
- name: varlibcontainers
overridable: true
emptyDir: {}
```
26 changes: 26 additions & 0 deletions pkg/apis/build/v1alpha1/build_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ const (
RemoteRepositoryUnreachable BuildReason = "RemoteRepositoryUnreachable"
// BuildNameInvalid indicates the build name is invalid
BuildNameInvalid BuildReason = "BuildNameInvalid"
// VolumeDoesNotExist indicates that volume referenced by the Build does not exist, therefore Build cannot be run
VolumeDoesNotExist BuildReason = "VolumeDoesNotExist"
// VolumeNotOverridable indicates that volume defined by build is not set as overridable in the strategy
VolumeNotOverridable BuildReason = "VolumeNotOverridable"
// UndefinedVolume indicates that volume defined by build is not found in the strategy
UndefinedVolume BuildReason = "UndefinedVolume"
// AllValidationsSucceeded indicates a Build was successfully validated
AllValidationsSucceeded = "all validations succeeded"
)
Expand Down Expand Up @@ -143,6 +149,26 @@ type BuildSpec struct {
//
// +optional
Retention *BuildRetention `json:"retention,omitempty"`

// Volumes contains volume Overrides of the BuildStrategy volumes in case those are allowed
// to be overridden. Must only contain volumes that exist in the corresponding BuildStrategy
// +optional
Volumes []BuildVolume `json:"volumes,omitempty"`
}

// BuildVolume is a volume that will be mounted in build pod during build step
type BuildVolume struct {
// Name of the Build Volume
// +required
Name string `json:"name"`

// Description of the Build Volume
// +optional
Description *string `json:"description,omitempty"`

// Represents the source of a volume to mount
// +required
corev1.VolumeSource `json:",inline"`
}

// StrategyName returns the name of the configured strategy, or 'undefined' in
Expand Down
5 changes: 5 additions & 0 deletions pkg/apis/build/v1alpha1/buildrun_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ type BuildRunSpec struct {
// Contains information about retention params
// +optional
Retention *BuildRunRetention `json:"retention,omitempty"`

// Volumes contains volume Overrides of the BuildStrategy volumes in case those are allowed
// to be overridden. Must only contain volumes that exist in the corresponding BuildStrategy
// +optional
Volumes []BuildVolume `json:"volumes,omitempty"`
}

// BuildRunRequestedState defines the buildrun state the user can provide to override whatever is the current state.
Expand Down
19 changes: 17 additions & 2 deletions pkg/apis/build/v1alpha1/buildstrategy.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ const (

// BuildStrategySpec defines the desired state of BuildStrategy
type BuildStrategySpec struct {
BuildSteps []BuildStep `json:"buildSteps,omitempty"`
Parameters []Parameter `json:"parameters,omitempty"`
BuildSteps []BuildStep `json:"buildSteps,omitempty"`
Parameters []Parameter `json:"parameters,omitempty"`
Volumes []BuildStrategyVolume `json:"volumes,omitempty"`
}

// ParameterType indicates the type of a parameter
Expand Down Expand Up @@ -59,6 +60,19 @@ type Parameter struct {
Defaults *[]string `json:"defaults"`
}

// BuildStrategyVolume is a volume that will be mounted in build pod during build step
// of the Build Strategy
type BuildStrategyVolume struct {
// Indicates that this Volume can be overridden in a Build or BuildRun.
// Defaults to false
// +optional
Overridable *bool `json:"overridable,omitempty"`

// Inline BuildVolume object, same as Build's Volume
// +required
BuildVolume `json:",inline"`
}

// BuildStep defines a partial step that needs to run in container for building the image.
// If the build step declares a volumeMount, Shipwright will create an emptyDir volume mount for the named volume.
// Build steps which share the same named volume in the volumeMount will share the same underlying emptyDir volume.
Expand Down Expand Up @@ -97,4 +111,5 @@ type BuilderStrategy interface {
GetResourceLabels() map[string]string
GetBuildSteps() []BuildStep
GetParameters() []Parameter
GetVolumes() []BuildStrategyVolume
}
5 changes: 5 additions & 0 deletions pkg/apis/build/v1alpha1/buildstrategy_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ func (s BuildStrategy) GetParameters() []Parameter {
return s.Spec.Parameters
}

// GetVolumes returns the volumes defined by the build strategy
func (s BuildStrategy) GetVolumes() []BuildStrategyVolume {
return s.Spec.Volumes
}

func init() {
SchemeBuilder.Register(&BuildStrategy{}, &BuildStrategyList{})
}
5 changes: 5 additions & 0 deletions pkg/apis/build/v1alpha1/clusterbuildstrategy_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ func (s ClusterBuildStrategy) GetParameters() []Parameter {
return s.Spec.Parameters
}

// GetVolumes returns the volumes defined by the build strategy
func (s ClusterBuildStrategy) GetVolumes() []BuildStrategyVolume {
return s.Spec.Volumes
}

func init() {
SchemeBuilder.Register(&ClusterBuildStrategy{}, &ClusterBuildStrategyList{})
}
65 changes: 65 additions & 0 deletions pkg/apis/build/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 25 additions & 0 deletions pkg/reconciler/buildrun/buildrun.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,15 @@ func (r *ReconcileBuildRun) Reconcile(ctx context.Context, request reconcile.Req
return reconcile.Result{}, nil
}

// Validate the volumes
valid, reason, message = validate.BuildRunVolumes(strategy.GetVolumes(), buildRun.Spec.Volumes)
if !valid {
if err := resources.UpdateConditionWithFalseStatus(ctx, r.client, buildRun, message, reason); err != nil {
return reconcile.Result{}, err
}
return reconcile.Result{}, nil
}

// Create the TaskRun, this needs to be the last step in this block to be idempotent
generatedTaskRun, err := r.createTaskRun(ctx, svcAccount, strategy, build, buildRun)
if err != nil {
Expand All @@ -292,6 +301,22 @@ func (r *ReconcileBuildRun) Reconcile(ctx context.Context, request reconcile.Req
return reconcile.Result{}, err
}

err = resources.CheckTaskRunVolumesExist(ctx, r.client, generatedTaskRun)
// if resource is not found, fais the build run
if err != nil {
if apierrors.IsNotFound(err) {
if err := resources.UpdateConditionWithFalseStatus(ctx, r.client, buildRun, err.Error(), string(buildv1alpha1.VolumeDoesNotExist)); err != nil {
return reconcile.Result{}, err
}

// end of reconciliation
return reconcile.Result{}, nil
}

// some other error might have happened, return it and reconcile again
return reconcile.Result{}, err
}

ctxlog.Info(ctx, "creating TaskRun from BuildRun", namespace, request.Namespace, name, generatedTaskRun.GenerateName, "BuildRun", buildRun.Name)
if err = r.client.Create(ctx, generatedTaskRun); err != nil {
// system call failure, reconcile again
Expand Down
Loading

0 comments on commit 4dbe852

Please sign in to comment.