Skip to content

Commit

Permalink
Rebase and refactor the Volume resource to be a sub-type of the gener…
Browse files Browse the repository at this point in the history
…al Storage resource.

This commit modifies the Volume resource to be a "type" of the Storage resource, and rebases
it with the recent Resource refactors.
  • Loading branch information
dlorenc committed Aug 12, 2019
1 parent 5d80dd2 commit e72692e
Show file tree
Hide file tree
Showing 16 changed files with 179 additions and 248 deletions.
9 changes: 5 additions & 4 deletions pkg/apis/pipeline/v1alpha1/build_gcs_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/tektoncd/pipeline/pkg/names"
"golang.org/x/xerrors"
corev1 "k8s.io/api/core/v1"
"k8s.io/client-go/kubernetes"
)

var (
Expand Down Expand Up @@ -166,10 +167,10 @@ func getArtifactType(val string) (GCSArtifactType, error) {
return "", xerrors.Errorf("Invalid ArtifactType %s. Should be one of %s", aType, strings.Join(valid, ","))
}

func (s *BuildGCSResource) GetUploadVolumeSpec(spec *TaskSpec) ([]corev1.Volume, error) {
return getStorageUploadVolumeSpec(s, spec)
func (s *BuildGCSResource) GetUploadVolumeSpec(ts *TaskSpec, _ *TaskRun, _ kubernetes.Interface) ([]corev1.Volume, error) {
return getStorageUploadVolumeSpec(s, ts)
}

func (s *BuildGCSResource) GetDownloadVolumeSpec(spec *TaskSpec) ([]corev1.Volume, error) {
return getStorageUploadVolumeSpec(s, spec)
func (s *BuildGCSResource) GetDownloadVolumeSpec(ts *TaskSpec, tr *TaskRun, c kubernetes.Interface) ([]corev1.Volume, error) {
return getStorageUploadVolumeSpec(s, ts)
}
5 changes: 3 additions & 2 deletions pkg/apis/pipeline/v1alpha1/cloud_event_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"strings"

corev1 "k8s.io/api/core/v1"
"k8s.io/client-go/kubernetes"
)

// CloudEventResource is an event sink to which events are delivered when a TaskRun has finished
Expand Down Expand Up @@ -91,11 +92,11 @@ func (s *CloudEventResource) GetDownloadContainerSpec(_ string) ([]corev1.Contai
}

// GetUploadVolumeSpec - no upload from volume for CloudEvent resource
func (s *CloudEventResource) GetUploadVolumeSpec(spec *TaskSpec) ([]corev1.Volume, error) {
func (s *CloudEventResource) GetUploadVolumeSpec(spec *TaskSpec, _ *TaskRun, s_ kubernetes.Interface) ([]corev1.Volume, error) {
return nil, nil
}

// GetDownloadVolumeSpec - no download from volume for CloudEvent resource
func (s *CloudEventResource) GetDownloadVolumeSpec(spec *TaskSpec) ([]corev1.Volume, error) {
func (s *CloudEventResource) GetDownloadVolumeSpec(spec *TaskSpec, _ *TaskRun, _ kubernetes.Interface) ([]corev1.Volume, error) {
return nil, nil
}
5 changes: 3 additions & 2 deletions pkg/apis/pipeline/v1alpha1/cluster_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/tektoncd/pipeline/pkg/names"
"golang.org/x/xerrors"
corev1 "k8s.io/api/core/v1"
"k8s.io/client-go/kubernetes"
)

var (
Expand Down Expand Up @@ -172,10 +173,10 @@ func (s *ClusterResource) GetDownloadContainerSpec(sourcePath string) ([]corev1.
return []corev1.Container{clusterContainer}, nil
}

func (s *ClusterResource) GetUploadVolumeSpec(spec *TaskSpec) ([]corev1.Volume, error) {
func (s *ClusterResource) GetUploadVolumeSpec(_ *TaskSpec, _ *TaskRun, _ kubernetes.Interface) ([]corev1.Volume, error) {
return nil, nil
}

func (s *ClusterResource) GetDownloadVolumeSpec(spec *TaskSpec) ([]corev1.Volume, error) {
func (s *ClusterResource) GetDownloadVolumeSpec(ts *TaskSpec, tr *TaskRun, c kubernetes.Interface) ([]corev1.Volume, error) {
return nil, nil
}
9 changes: 5 additions & 4 deletions pkg/apis/pipeline/v1alpha1/gcs_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/tektoncd/pipeline/pkg/names"
"golang.org/x/xerrors"
corev1 "k8s.io/api/core/v1"
"k8s.io/client-go/kubernetes"
)

var (
Expand Down Expand Up @@ -144,10 +145,10 @@ func (s *GCSResource) GetDownloadContainerSpec(sourcePath string) ([]corev1.Cont
}}, nil
}

func (s *GCSResource) GetUploadVolumeSpec(spec *TaskSpec) ([]corev1.Volume, error) {
return getStorageUploadVolumeSpec(s, spec)
func (s *GCSResource) GetUploadVolumeSpec(ts *TaskSpec, _ *TaskRun, _ kubernetes.Interface) ([]corev1.Volume, error) {
return getStorageUploadVolumeSpec(s, ts)
}

func (s *GCSResource) GetDownloadVolumeSpec(spec *TaskSpec) ([]corev1.Volume, error) {
return getStorageUploadVolumeSpec(s, spec)
func (s *GCSResource) GetDownloadVolumeSpec(ts *TaskSpec, tr *TaskRun, c kubernetes.Interface) ([]corev1.Volume, error) {
return getStorageUploadVolumeSpec(s, ts)
}
5 changes: 3 additions & 2 deletions pkg/apis/pipeline/v1alpha1/git_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/tektoncd/pipeline/pkg/names"
"golang.org/x/xerrors"
corev1 "k8s.io/api/core/v1"
"k8s.io/client-go/kubernetes"
)

const WorkspaceDir = "/workspace"
Expand Down Expand Up @@ -115,10 +116,10 @@ func (s *GitResource) GetUploadContainerSpec(sourcePath string) ([]corev1.Contai
return nil, nil
}

func (s *GitResource) GetUploadVolumeSpec(spec *TaskSpec) ([]corev1.Volume, error) {
func (s *GitResource) GetUploadVolumeSpec(_ *TaskSpec, _ *TaskRun, _ kubernetes.Interface) ([]corev1.Volume, error) {
return nil, nil
}

func (s *GitResource) GetDownloadVolumeSpec(spec *TaskSpec) ([]corev1.Volume, error) {
func (s *GitResource) GetDownloadVolumeSpec(ts *TaskSpec, tr *TaskRun, c kubernetes.Interface) ([]corev1.Volume, error) {
return nil, nil
}
5 changes: 3 additions & 2 deletions pkg/apis/pipeline/v1alpha1/image_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (

"golang.org/x/xerrors"
corev1 "k8s.io/api/core/v1"
"k8s.io/client-go/kubernetes"
)

// NewImageResource creates a new ImageResource from a PipelineResource.
Expand Down Expand Up @@ -98,10 +99,10 @@ func (s ImageResource) String() string {
return string(json)
}

func (s *ImageResource) GetUploadVolumeSpec(spec *TaskSpec) ([]corev1.Volume, error) {
func (s *ImageResource) GetUploadVolumeSpec(_ *TaskSpec, _ *TaskRun, _ kubernetes.Interface) ([]corev1.Volume, error) {
return nil, nil
}

func (s *ImageResource) GetDownloadVolumeSpec(spec *TaskSpec) ([]corev1.Volume, error) {
func (s *ImageResource) GetDownloadVolumeSpec(ts *TaskSpec, tr *TaskRun, c kubernetes.Interface) ([]corev1.Volume, error) {
return nil, nil
}
5 changes: 3 additions & 2 deletions pkg/apis/pipeline/v1alpha1/pull_request_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (

"github.com/tektoncd/pipeline/pkg/names"
corev1 "k8s.io/api/core/v1"
"k8s.io/client-go/kubernetes"
)

const (
Expand Down Expand Up @@ -133,10 +134,10 @@ func (s *PullRequestResource) getContainerSpec(mode string, sourcePath string) (
}}, nil
}

func (s *PullRequestResource) GetUploadVolumeSpec(spec *TaskSpec) ([]corev1.Volume, error) {
func (s *PullRequestResource) GetUploadVolumeSpec(_ *TaskSpec, _ *TaskRun, _ kubernetes.Interface) ([]corev1.Volume, error) {
return nil, nil
}

func (s *PullRequestResource) GetDownloadVolumeSpec(spec *TaskSpec) ([]corev1.Volume, error) {
func (s *PullRequestResource) GetDownloadVolumeSpec(ts *TaskSpec, tr *TaskRun, c kubernetes.Interface) ([]corev1.Volume, error) {
return nil, nil
}
10 changes: 3 additions & 7 deletions pkg/apis/pipeline/v1alpha1/resource_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"golang.org/x/xerrors"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"knative.dev/pkg/apis"
)

Expand Down Expand Up @@ -60,8 +61,8 @@ type PipelineResourceInterface interface {
Replacements() map[string]string
GetDownloadContainerSpec(sourcePath string) ([]corev1.Container, error)
GetUploadContainerSpec(sourcePath string) ([]corev1.Container, error)
GetUploadVolumeSpec(spec *TaskSpec) ([]corev1.Volume, error)
GetDownloadVolumeSpec(spec *TaskSpec) ([]corev1.Volume, error)
GetDownloadVolumeSpec(*TaskSpec, *TaskRun, kubernetes.Interface) ([]corev1.Volume, error)
GetUploadVolumeSpec(*TaskSpec, *TaskRun, kubernetes.Interface) ([]corev1.Volume, error)
}

// SecretParam indicates which secret can be used to populate a field of the resource
Expand Down Expand Up @@ -149,13 +150,8 @@ func ResourceFromType(r *PipelineResource) (PipelineResourceInterface, error) {
return NewStorageResource(r)
case PipelineResourceTypePullRequest:
return NewPullRequestResource(r)
<<<<<<< HEAD
case PipelineResourceTypeCloudEvent:
return NewCloudEventResource(r)
=======
case PipelineResourceTypeVolume:
return NewVolumeResource(r)
>>>>>>> Add "volume" PipelineResource
}
return nil, xerrors.Errorf("%s is an invalid or unimplemented PipelineResource", r.Spec.Type)
}
7 changes: 5 additions & 2 deletions pkg/apis/pipeline/v1alpha1/storage_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ type PipelineResourceStorageType string

const (
// PipelineResourceTypeGCS indicates that resource source is a GCS blob/directory.
PipelineResourceTypeGCS PipelineResourceType = "gcs"
PipelineResourceTypeBuildGCS PipelineResourceType = "build-gcs"
PipelineResourceTypeGCS PipelineResourceType = "gcs"
PipelineResourceTypeBuildGCS PipelineResourceType = "build-gcs"
PipelineResourceTypeBuildVolume PipelineResourceType = "volume"
)

// PipelineResourceInterface interface to be implemented by different PipelineResource types
Expand All @@ -50,6 +51,8 @@ func NewStorageResource(r *PipelineResource) (PipelineStorageResourceInterface,
return NewGCSResource(r)
case strings.EqualFold(param.Value, string(PipelineResourceTypeBuildGCS)):
return NewBuildGCSResource(r)
case strings.EqualFold(param.Value, string(PipelineResourceTypeBuildVolume)):
return NewVolumeResource(r)
default:
return nil, xerrors.Errorf("%s is an invalid or unimplemented PipelineStorageResource", param.Value)
}
Expand Down
111 changes: 39 additions & 72 deletions pkg/apis/pipeline/v1alpha1/volume_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,15 @@ const (
// VolumeResource is a volume from which to get artifacts which is required
// by a Build/Task for context (e.g. a archive from which to build an image).
type VolumeResource struct {
Name string `json:"name"`
Type PipelineResourceType `json:"type"`
DestinationDir string `json:"destinationDir"`
SourceDir string `json:"sourceDir"`
Size string `json:"size"`
Name string `json:"name"`
Type PipelineResourceType `json:"type"`
SourceDir string `json:"sourceDir"`
Size string `json:"size"`
}

// NewVolumeResource creates a new volume resource to pass to a Task
func NewVolumeResource(r *PipelineResource) (*VolumeResource, error) {
if r.Spec.Type != PipelineResourceTypeVolume {
if r.Spec.Type != PipelineResourceTypeStorage {
return nil, xerrors.Errorf("VolumeResource: Cannot create a volume resource from a %s Pipeline Resource", r.Spec.Type)
}
size := DefaultPvcSize
Expand All @@ -74,88 +73,52 @@ func (s VolumeResource) GetName() string {

// GetType returns the type of the resource, in this case "volume"
func (s VolumeResource) GetType() PipelineResourceType {
return PipelineResourceTypeVolume
return PipelineResourceTypeStorage
}

// Replacements is used for template replacement on an VolumeResource inside of a Taskrun.
func (s *VolumeResource) Replacements() map[string]string {
return map[string]string{
"name": s.Name,
"type": string(s.Type),
"path": s.DestinationDir,
}
}

// SetSourceDirectory sets the source directory at runtime like where is the resource going to be copied from
func (s *VolumeResource) SetSourceDirectory(srcDir string) { s.SourceDir = srcDir }

// SetDestinationDirectory sets the destination directory at runtime like where is the resource going to be copied to
func (s *VolumeResource) SetDestinationDirectory(destDir string) { s.DestinationDir = destDir }

// GetVolume returns the volume for this resource, creating it if necessary.
func (s *VolumeResource) GetVolume(c kubernetes.Interface, tr *TaskRun) (*corev1.Volume, error) {
_, err := c.CoreV1().PersistentVolumeClaims(tr.Namespace).Get(s.Name, metav1.GetOptions{})
if err != nil {
if !errors.IsNotFound(err) {
return nil, xerrors.Errorf("failed to get claim Persistent Volume %q due to error: %w", tr.Name, err)
}
pvcSize, err := resource.ParseQuantity(s.Size)
if err != nil {
return nil, xerrors.Errorf("failed to create Persistent Volume spec for %q due to error: %w", tr.Name, err)
}
pvcSpec := s.GetPVCSpec(tr, pvcSize)
_, err = c.CoreV1().PersistentVolumeClaims(tr.Namespace).Create(pvcSpec)
if err != nil {
return nil, xerrors.Errorf("failed to claim Persistent Volume %q due to error: %w", tr.Name, err)
}
}

return &corev1.Volume{
Name: s.Name,
VolumeSource: corev1.VolumeSource{
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ClaimName: s.Name},
},
}, nil
}

// GetUploadContainerSpec gets container spec for gcs resource to be uploaded like
// set environment variable from secret params and set volume mounts for those secrets
func (s *VolumeResource) GetUploadContainerSpec() ([]corev1.Container, error) {
if s.DestinationDir == "" {
return nil, xerrors.Errorf("VolumeResource: Expect Destination Directory param to be set: %s", s.Name)
}
func (s *VolumeResource) GetUploadContainerSpec(sourcePath string) ([]corev1.Container, error) {
return []corev1.Container{{
Name: names.SimpleNameGenerator.RestrictLengthWithRandomSuffix(fmt.Sprintf("upload-mkdir-%s", s.Name)),
Image: *BashNoopImage,
Command: []string{"/ko-app/bash"},
Args: []string{
"-args", strings.Join([]string{"mkdir", "-p", filepath.Join(VolumeMountDir, s.DestinationDir)}, " "),
"-args", strings.Join([]string{"mkdir", "-p", filepath.Join(VolumeMountDir, sourcePath)}, " "),
},
VolumeMounts: []corev1.VolumeMount{s.GetPvcMount()},
}, {
Name: names.SimpleNameGenerator.RestrictLengthWithRandomSuffix(fmt.Sprintf("upload-copy-%s", s.Name)),
Image: *BashNoopImage,
Command: []string{"/ko-app/bash"},
Args: []string{
"-args", strings.Join([]string{"cp", "-r", fmt.Sprintf("%s/.", s.SourceDir), filepath.Join(VolumeMountDir, s.DestinationDir)}, " "),
"-args", strings.Join([]string{"cp", "-r", fmt.Sprintf("%s/.", s.SourceDir), filepath.Join(VolumeMountDir, sourcePath)}, " "),
},
VolumeMounts: []corev1.VolumeMount{s.GetPvcMount()},
}}, nil
}

// GetDownloadContainerSpec returns an array of container specs to download gcs storage object
func (s *VolumeResource) GetDownloadContainerSpec() ([]corev1.Container, error) {
if s.DestinationDir == "" {
return nil, xerrors.Errorf("VolumeResource: Expect Destination Directory param to be set %s", s.Name)
}
func (s *VolumeResource) GetDownloadContainerSpec(sourcePath string) ([]corev1.Container, error) {

return []corev1.Container{
CreateDirContainer(s.Name, s.DestinationDir), {
CreateDirContainer(s.Name, sourcePath), {
Name: names.SimpleNameGenerator.RestrictLengthWithRandomSuffix(fmt.Sprintf("download-copy-%s", s.Name)),
Image: *BashNoopImage,
Command: []string{"/ko-app/bash"},
Args: []string{
"-args", strings.Join([]string{"cp", "-r", fmt.Sprintf("%s/.", filepath.Join(VolumeMountDir, s.SourceDir)), s.DestinationDir}, " "),
"-args", strings.Join([]string{"cp", "-r", fmt.Sprintf("%s/.", filepath.Join(VolumeMountDir, s.SourceDir)), sourcePath}, " "),
},
VolumeMounts: []corev1.VolumeMount{s.GetPvcMount()},
}}, nil
Expand Down Expand Up @@ -188,34 +151,38 @@ func (s *VolumeResource) GetPvcMount() corev1.VolumeMount {
}
}

func (s *VolumeResource) GetDownloadVolumeSpec(spec *TaskSpec) ([]corev1.Volume, error) {
volume, err := s.GetVolume(kubeClient, taskRun)
if err != nil {
return nil, err
}
return []corev1.Volume{*volume}, nil
func (s *VolumeResource) GetDownloadVolumeSpec(ts *TaskSpec, tr *TaskRun, c kubernetes.Interface) ([]corev1.Volume, error) {
return s.getVolumeSpec(tr, c)
}

// GetSecretParams returns the resource secret params
func (s *VolumeResource) GetSecretParams() []SecretParam { return nil }

func (s * VolumeResource) GetDownloadContainerSpec(spec *TaskSpec) ([]corev1.Container, error) {
var volumeContainers []corev1.Container

var actualSourcePaths []string

if len(sourcePaths) > 0 {
actualSourcePaths = append(actualSourcePaths, sourcePaths...)
} else {
actualSourcePaths = append(actualSourcePaths, volumeResource.Name)
}
func (s *VolumeResource) GetUploadVolumeSpec(ts *TaskSpec, tr *TaskRun, c kubernetes.Interface) ([]corev1.Volume, error) {
return s.getVolumeSpec(tr, c)
}

for _, src := range actualSourcePaths {
volumeResource.SetSourceDirectory(src)
containers, err := volumeResource.GetDownloadContainerSpec()
func (s *VolumeResource) getVolumeSpec(tr *TaskRun, c kubernetes.Interface) ([]corev1.Volume, error) {
_, err := c.CoreV1().PersistentVolumeClaims(tr.Namespace).Get(s.Name, metav1.GetOptions{})
if err != nil {
if !errors.IsNotFound(err) {
return nil, xerrors.Errorf("failed to get claim Persistent Volume %q due to error: %w", tr.Name, err)
}
pvcSize, err := resource.ParseQuantity(s.Size)
if err != nil {
return nil, err
return nil, xerrors.Errorf("failed to create Persistent Volume spec for %q due to error: %w", tr.Name, err)
}
pvcSpec := s.GetPVCSpec(tr, pvcSize)
_, err = c.CoreV1().PersistentVolumeClaims(tr.Namespace).Create(pvcSpec)
if err != nil {
return nil, xerrors.Errorf("failed to claim Persistent Volume %q due to error: %w", tr.Name, err)
}
volumeContainers = append(volumeContainers, containers...)
}

return volumeContainers, nil
}
return []corev1.Volume{corev1.Volume{
Name: s.Name,
VolumeSource: corev1.VolumeSource{
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ClaimName: s.Name},
},
}}, nil
}
Loading

0 comments on commit e72692e

Please sign in to comment.