From e15fde88a2f26f4fcf44eb1e2097fa6d2110525f Mon Sep 17 00:00:00 2001 From: Jerome Ju Date: Thu, 11 Aug 2022 20:48:47 +0000 Subject: [PATCH] V1: Add conversion for Pipeline.Resources This commit adds support for Pipeline.Resources when converting between v1beta1 and v1 versions of Pipelines. This will allow us to release v1 Pipeline in a backwards compatible way, by ensuring that v1beta1 Pipelines with Resources will have the Resources serialized into annotations on the v1 Pipeline on conversion. --- .../pipeline/v1beta1/pipeline_conversion.go | 28 ++++++++++++++++- .../v1beta1/pipeline_conversion_test.go | 31 ++++++++++++++----- pkg/apis/version/conversion_test.go | 25 +++++++++++++++ 3 files changed, 76 insertions(+), 8 deletions(-) diff --git a/pkg/apis/pipeline/v1beta1/pipeline_conversion.go b/pkg/apis/pipeline/v1beta1/pipeline_conversion.go index d2630e07cb4..67680499ddd 100644 --- a/pkg/apis/pipeline/v1beta1/pipeline_conversion.go +++ b/pkg/apis/pipeline/v1beta1/pipeline_conversion.go @@ -21,6 +21,8 @@ import ( "fmt" v1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" + "github.com/tektoncd/pipeline/pkg/apis/version" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "knative.dev/pkg/apis" ) @@ -34,6 +36,9 @@ func (p *Pipeline) ConvertTo(ctx context.Context, to apis.Convertible) error { switch sink := to.(type) { case *v1.Pipeline: sink.ObjectMeta = p.ObjectMeta + if err := serializePipelineResources(&sink.ObjectMeta, &p.Spec); err != nil { + return err + } return p.Spec.ConvertTo(ctx, &sink.Spec) default: return fmt.Errorf("unknown version, got: %T", sink) @@ -79,7 +84,6 @@ func (ps *PipelineSpec) ConvertTo(ctx context.Context, sink *v1.PipelineSpec) er } sink.Finally = append(sink.Finally, new) } - // TODO: Handle Resources in #4546 return nil } @@ -88,6 +92,9 @@ func (p *Pipeline) ConvertFrom(ctx context.Context, from apis.Convertible) error switch source := from.(type) { case *v1.Pipeline: p.ObjectMeta = source.ObjectMeta + if err := deserializePipelineResources(&p.ObjectMeta, &p.Spec); err != nil { + return err + } return p.Spec.ConvertFrom(ctx, &source.Spec) default: return fmt.Errorf("unknown version, got: %T", p) @@ -271,3 +278,22 @@ func (pr *PipelineResult) convertFrom(ctx context.Context, source v1.PipelineRes newValue.convertFrom(ctx, source.Value) pr.Value = newValue } + +func serializePipelineResources(meta *metav1.ObjectMeta, spec *PipelineSpec) error { + if spec.Resources == nil { + return nil + } + return version.SerializeToMetadata(meta, spec.Resources, resourcesAnnotationKey) +} + +func deserializePipelineResources(meta *metav1.ObjectMeta, spec *PipelineSpec) error { + resources := &[]PipelineDeclaredResource{} + err := version.DeserializeFromMetadata(meta, resources, resourcesAnnotationKey) + if err != nil { + return err + } + if len(*resources) != 0 { + spec.Resources = *resources + } + return nil +} diff --git a/pkg/apis/pipeline/v1beta1/pipeline_conversion_test.go b/pkg/apis/pipeline/v1beta1/pipeline_conversion_test.go index f1c98fe1a02..9fbb22bfaa2 100644 --- a/pkg/apis/pipeline/v1beta1/pipeline_conversion_test.go +++ b/pkg/apis/pipeline/v1beta1/pipeline_conversion_test.go @@ -170,7 +170,6 @@ func TestPipelineConversion(t *testing.T) { } } -// TODO handle resources and bundles in #4546 func TestPipelineConversionFromDeprecated(t *testing.T) { versions := []apis.Convertible{&v1.Pipeline{}} tests := []struct { @@ -185,18 +184,36 @@ func TestPipelineConversionFromDeprecated(t *testing.T) { Namespace: "bar", }, Spec: v1beta1.PipelineSpec{ - Resources: []v1beta1.PipelineDeclaredResource{{ - Name: "pipeline resource", - Type: v1beta1.PipelineResourceTypeGit, - Optional: true, - }}, + Resources: []v1beta1.PipelineDeclaredResource{ + { + Name: "1st pipeline resource", + Type: v1beta1.PipelineResourceTypeGit, + Optional: true, + }, { + Name: "2nd pipeline resource", + Type: v1beta1.PipelineResourceTypeGit, + Optional: false, + }, + }, }}, want: &v1beta1.Pipeline{ ObjectMeta: metav1.ObjectMeta{ Name: "foo", Namespace: "bar", }, - Spec: v1beta1.PipelineSpec{}, + Spec: v1beta1.PipelineSpec{ + Resources: []v1beta1.PipelineDeclaredResource{ + { + Name: "1st pipeline resource", + Type: v1beta1.PipelineResourceTypeGit, + Optional: true, + }, { + Name: "2nd pipeline resource", + Type: v1beta1.PipelineResourceTypeGit, + Optional: false, + }, + }, + }, }, }} diff --git a/pkg/apis/version/conversion_test.go b/pkg/apis/version/conversion_test.go index b2e127a5ec6..a98a72ae3f0 100644 --- a/pkg/apis/version/conversion_test.go +++ b/pkg/apis/version/conversion_test.go @@ -52,3 +52,28 @@ func TestSerializationRoundTrip(t *testing.T) { t.Errorf("Unexpected diff after serialization/deserialization round trip: %s", d) } } + +func TestSliceSerializationRoundTrip(t *testing.T) { + meta := metav1.ObjectMeta{} + source := []testStruct{{Field: "foo"}, {Field: "bar"}} + key := "my-key" + err := version.SerializeToMetadata(&meta, source, key) + if err != nil { + t.Fatalf("Serialization error: %s", err) + } + + sink := []testStruct{} + err = version.DeserializeFromMetadata(&meta, &sink, key) + if err != nil { + t.Fatalf("Deserialization error: %s", err) + } + + _, ok := meta.Annotations[key] + if ok { + t.Errorf("Expected key %s not to be present in annotations but it was", key) + } + + if d := cmp.Diff(source, sink); d != "" { + t.Errorf("Unexpected diff after serialization/deserialization round trip: %s", d) + } +}