From af5afd7445228c5ba86551ab74c66fc11e1fdece Mon Sep 17 00:00:00 2001 From: vinamra28 Date: Sun, 9 Oct 2022 21:38:52 +0530 Subject: [PATCH] [TEP-0048] Add support for default results Today, a Task can declare a Result but not produce it and it's execution will still be successful whereas if a subsequent Task in a Pipeline attempts to use that Result it will fail. This behaviour can be confusing to the users as the Task which didn't produced the Result passed and the follow-up Task fails. Moreover, the user of the Task will loose faith in it as it failed to produce what it's claiming. This patch introduces the default results, ie, Task author can now add a default value to the results so that if their Task doesn't produce any result then the default value can be emitted. Now, with this change, if the Task author doesn't specifies any default value for the result and one of the step within that Task also doesn't produces it then the Task execution in whole will be marked as failed as it failed to prove it's contract. --- docs/pipeline-api.md | 42 +++- docs/tasks.md | 40 ++++ .../pipeline-emitting-default-results.yaml | 72 +++++++ .../taskruns/alpha/default-result.yaml | 33 +++ pkg/apis/pipeline/v1/openapi_generated.go | 8 +- pkg/apis/pipeline/v1/result_types.go | 7 + pkg/apis/pipeline/v1/swagger.json | 4 + pkg/apis/pipeline/v1/zz_generated.deepcopy.go | 5 + .../pipeline/v1beta1/openapi_generated.go | 8 +- .../pipeline/v1beta1/result_conversion.go | 18 ++ pkg/apis/pipeline/v1beta1/result_types.go | 7 + .../pipeline/v1beta1/result_validation.go | 5 + .../v1beta1/result_validation_test.go | 21 ++ pkg/apis/pipeline/v1beta1/swagger.json | 4 + .../pipeline/v1beta1/zz_generated.deepcopy.go | 5 + pkg/reconciler/taskrun/taskrun.go | 22 ++ pkg/reconciler/taskrun/taskrun_test.go | 111 ++++++++++ pkg/reconciler/taskrun/validate_resources.go | 44 +++- .../taskrun/validate_resources_test.go | 168 +++++++++++++++ test/ignore_step_error_test.go | 4 +- test/pipelinefinally_test.go | 4 +- third_party/LICENSE | 27 --- third_party/crypto/internal/boring/LICENSE | 202 ------------------ .../vendor/golang.org/x/crypto/LICENSE | 27 --- third_party/vendor/golang.org/x/net/LICENSE | 27 --- third_party/vendor/golang.org/x/text/LICENSE | 27 --- 26 files changed, 616 insertions(+), 326 deletions(-) create mode 100644 examples/v1beta1/pipelineruns/alpha/pipeline-emitting-default-results.yaml create mode 100644 examples/v1beta1/taskruns/alpha/default-result.yaml delete mode 100644 third_party/LICENSE delete mode 100644 third_party/crypto/internal/boring/LICENSE delete mode 100644 third_party/vendor/golang.org/x/crypto/LICENSE delete mode 100644 third_party/vendor/golang.org/x/net/LICENSE delete mode 100644 third_party/vendor/golang.org/x/text/LICENSE diff --git a/docs/pipeline-api.md b/docs/pipeline-api.md index 3867d2b23d8..4ec7575d3c0 100644 --- a/docs/pipeline-api.md +++ b/docs/pipeline-api.md @@ -1669,7 +1669,7 @@ Used to distinguish between a single string and an array of strings.

ParamValue

-(Appears on:Param, ParamSpec, PipelineResult, PipelineRunResult, TaskRunResult) +(Appears on:Param, ParamSpec, PipelineResult, PipelineRunResult, TaskResult, TaskRunResult)

ResultValue is a type alias of ParamValue

@@ -4476,6 +4476,22 @@ string

Description is a human-readable description of the result

+ + +default
+ + +ParamValue + + + + +(Optional) +

This is an alpha field. You must set the “enable-api-fields” feature flag to “alpha” +for this field to be supported.

+

Default is the value a result produces if no result is produced by Task

+ +

TaskRunDebug @@ -8785,7 +8801,7 @@ Used to distinguish between a single string and an array of strings.

ParamValue

-(Appears on:Param, ParamSpec, PipelineResult, PipelineRunResult, TaskRunResult) +(Appears on:Param, ParamSpec, PipelineResult, PipelineRunResult, TaskResult, TaskRunResult)

ResultValue is a type alias of ParamValue

@@ -12441,8 +12457,30 @@ string

Description is a human-readable description of the result

+ + +default
+ + +ParamValue + + + + +(Optional) +

This is an alpha field. You must set the “enable-api-fields” feature flag to “alpha” +for this field to be supported.

+

Default is the value a result produces if no result is produced by Task

+ + +

TaskRunConditionType +(string alias)

+
+

TaskRunConditionType is an enum used to store TaskRun custom conditions +conditions such as one used in spire results verification

+

TaskRunDebug

diff --git a/docs/tasks.md b/docs/tasks.md index 3782ed7cc67..80c7ab0c660 100644 --- a/docs/tasks.md +++ b/docs/tasks.md @@ -847,6 +847,46 @@ available size will less than 4096 bytes. As a general rule-of-thumb, if a result needs to be larger than a kilobyte, you should likely use a [`Workspace`](#specifying-workspaces) to store and pass it between `Tasks` within a `Pipeline`. +#### Default value + +Results declarations (within Tasks and Pipelines) can include default values which will be used if the Result is +not produced, for example to specify defaults for both string params and array params +([full example](../examples/v1beta1/taskruns/alpha/default-result.yaml)) : + +```yaml +apiVersion: tekton.dev/v1beta1 +kind: Task +metadata: + name: task-with-default-result +spec: + results: + - name: branch + default: main +``` + +**Note**: If a Task doesn't specify any default value for a particular `Result` +and also fails to emit that `Result`, in that case, the following `Task` is going +to be marked as `Failed` as specified in [TEP-0048](https://github.com/tektoncd/community/blob/main/teps/0048-task-results-without-results.md). Below is the example in which the TaskRun +is going to fail as one of the Result wasn't produced. + +```yaml +apiVersion: tekton.dev/v1beta1 +kind: TaskRun +metadata: + generateName: test-tr- +spec: + taskSpec: + results: + - name: result1 + description: will be produced + - name: result2 + description: will not be produced + steps: + - name: failing-step + image: busybox + script: "echo -n 123 | tee $(results.result1.path)" +``` + ### Specifying `Volumes` Specifies one or more [`Volumes`](https://kubernetes.io/docs/concepts/storage/volumes/) that the `Steps` in your diff --git a/examples/v1beta1/pipelineruns/alpha/pipeline-emitting-default-results.yaml b/examples/v1beta1/pipelineruns/alpha/pipeline-emitting-default-results.yaml new file mode 100644 index 00000000000..08ffbbe146f --- /dev/null +++ b/examples/v1beta1/pipelineruns/alpha/pipeline-emitting-default-results.yaml @@ -0,0 +1,72 @@ +apiVersion: tekton.dev/v1beta1 +kind: PipelineRun +metadata: + name: pipelinerun-emit-default-results +spec: + pipelineSpec: + tasks: + - name: task1 + taskSpec: + results: + - name: array-results + type: array + description: The array results + default: + - "1" + - "2" + - "3" + steps: + - name: write-array + image: bash:latest + script: | + #!/usr/bin/env bash + echo -n "this script won't emit array result" + - name: task2 + taskSpec: + results: + - name: object-results + type: object + description: The object results + properties: + foo: { type: string } + hello: { type: string } + default: + foo: bar + hello: world + steps: + - name: write-array + image: bash:latest + script: | + #!/usr/bin/env bash + echo -n "this script won't emit object result" + results: + - name: array-results + type: array + description: whole array + value: $(tasks.task1.results.array-results[*]) + - name: array-results-from-array-indexing-and-object-elements + type: array + description: whole array + value: + [ + "$(tasks.task1.results.array-results[0])", + "$(tasks.task2.results.object-results.foo)", + ] + - name: array-indexing-results + type: string + description: array element + value: $(tasks.task1.results.array-results[1]) + - name: object-results + type: object + description: whole object + value: $(tasks.task2.results.object-results[*]) + - name: object-results-from-array-indexing-and-object-elements + type: object + description: whole object + value: + key1: $(tasks.task1.results.array-results[1]) + key2: $(tasks.task2.results.object-results.hello) + - name: object-element + type: string + description: object element + value: $(tasks.task2.results.object-results.foo) diff --git a/examples/v1beta1/taskruns/alpha/default-result.yaml b/examples/v1beta1/taskruns/alpha/default-result.yaml new file mode 100644 index 00000000000..21d2f83cb5f --- /dev/null +++ b/examples/v1beta1/taskruns/alpha/default-result.yaml @@ -0,0 +1,33 @@ +apiVersion: tekton.dev/v1beta1 +kind: TaskRun +metadata: + generateName: default-result-run- +spec: + taskSpec: + results: + - name: result1 + description: will be produced + - name: string-result + description: will not be produced by step but has default value + default: "string value" + - name: array-result + description: default array result will be produced + default: + - "foo" + - "bar" + - name: eight-results + type: object + properties: + IMAGE_URL: {type: string} + IMAGE_DIGEST: {type: string} + default: + IMAGE_URL: "default.com" + IMAGE_DIGEST: "defaultsha" + steps: + - name: failing-step + onError: continue + image: busybox + script: | + echo -n 123 | tee $(results.result1.path) + exit 1 + echo -n 456 | tee $(results.string-result.path) diff --git a/pkg/apis/pipeline/v1/openapi_generated.go b/pkg/apis/pipeline/v1/openapi_generated.go index c586cb3b274..e1a3438eb58 100644 --- a/pkg/apis/pipeline/v1/openapi_generated.go +++ b/pkg/apis/pipeline/v1/openapi_generated.go @@ -3176,12 +3176,18 @@ func schema_pkg_apis_pipeline_v1_TaskResult(ref common.ReferenceCallback) common Format: "", }, }, + "default": { + SchemaProps: spec.SchemaProps{ + Description: "This is an alpha field. You must set the \"enable-api-fields\" feature flag to \"alpha\" for this field to be supported.\n\nDefault is the value a result produces if no result is produced by Task", + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.ParamValue"), + }, + }, }, Required: []string{"name"}, }, }, Dependencies: []string{ - "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.PropertySpec"}, + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.ParamValue", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.PropertySpec"}, } } diff --git a/pkg/apis/pipeline/v1/result_types.go b/pkg/apis/pipeline/v1/result_types.go index a64c867f225..2ce39cc32bd 100644 --- a/pkg/apis/pipeline/v1/result_types.go +++ b/pkg/apis/pipeline/v1/result_types.go @@ -32,6 +32,13 @@ type TaskResult struct { // Description is a human-readable description of the result // +optional Description string `json:"description,omitempty"` + + // This is an alpha field. You must set the "enable-api-fields" feature flag to "alpha" + // for this field to be supported. + // + // Default is the value a result produces if no result is produced by Task + // +optional + Default *ResultValue `json:"default,omitempty"` } // TaskRunResult used to describe the results of a task diff --git a/pkg/apis/pipeline/v1/swagger.json b/pkg/apis/pipeline/v1/swagger.json index 0960125b903..c6cfeb854b4 100644 --- a/pkg/apis/pipeline/v1/swagger.json +++ b/pkg/apis/pipeline/v1/swagger.json @@ -1615,6 +1615,10 @@ "name" ], "properties": { + "default": { + "description": "This is an alpha field. You must set the \"enable-api-fields\" feature flag to \"alpha\" for this field to be supported.\n\nDefault is the value a result produces if no result is produced by Task", + "$ref": "#/definitions/v1.ParamValue" + }, "description": { "description": "Description is a human-readable description of the result", "type": "string" diff --git a/pkg/apis/pipeline/v1/zz_generated.deepcopy.go b/pkg/apis/pipeline/v1/zz_generated.deepcopy.go index ef03a3bb5ad..a5069ddabe3 100644 --- a/pkg/apis/pipeline/v1/zz_generated.deepcopy.go +++ b/pkg/apis/pipeline/v1/zz_generated.deepcopy.go @@ -1285,6 +1285,11 @@ func (in *TaskResult) DeepCopyInto(out *TaskResult) { (*out)[key] = val } } + if in.Default != nil { + in, out := &in.Default, &out.Default + *out = new(ParamValue) + (*in).DeepCopyInto(*out) + } return } diff --git a/pkg/apis/pipeline/v1beta1/openapi_generated.go b/pkg/apis/pipeline/v1beta1/openapi_generated.go index 10ee016640b..76a2d759efb 100644 --- a/pkg/apis/pipeline/v1beta1/openapi_generated.go +++ b/pkg/apis/pipeline/v1beta1/openapi_generated.go @@ -4386,12 +4386,18 @@ func schema_pkg_apis_pipeline_v1beta1_TaskResult(ref common.ReferenceCallback) c Format: "", }, }, + "default": { + SchemaProps: spec.SchemaProps{ + Description: "This is an alpha field. You must set the \"enable-api-fields\" feature flag to \"alpha\" for this field to be supported.\n\nDefault is the value a result produces if no result is produced by Task", + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.ParamValue"), + }, + }, }, Required: []string{"name"}, }, }, Dependencies: []string{ - "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.PropertySpec"}, + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.ParamValue", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.PropertySpec"}, } } diff --git a/pkg/apis/pipeline/v1beta1/result_conversion.go b/pkg/apis/pipeline/v1beta1/result_conversion.go index 70197bed164..4acb3abce55 100644 --- a/pkg/apis/pipeline/v1beta1/result_conversion.go +++ b/pkg/apis/pipeline/v1beta1/result_conversion.go @@ -26,4 +26,22 @@ func (r *TaskResult) convertFrom(ctx context.Context, source v1.TaskResult) { properties[k] = PropertySpec{Type: ParamType(v.Type)} } r.Properties = properties + if source.Default != nil { + r.Default = &ParamValue{ + Type: ParamType(source.Default.Type), + } + + if source.Default.StringVal != "" { + r.Default.StringVal = source.Default.StringVal + } + + if len(source.Default.ArrayVal) != 0 { + r.Default.ArrayVal = source.Default.ArrayVal + } + + if len(source.Default.ObjectVal) != 0 { + r.Default.ObjectVal = source.Default.ObjectVal + } + + } } diff --git a/pkg/apis/pipeline/v1beta1/result_types.go b/pkg/apis/pipeline/v1beta1/result_types.go index d71f513c4b3..0e77039d181 100644 --- a/pkg/apis/pipeline/v1beta1/result_types.go +++ b/pkg/apis/pipeline/v1beta1/result_types.go @@ -32,6 +32,13 @@ type TaskResult struct { // Description is a human-readable description of the result // +optional Description string `json:"description,omitempty"` + + // This is an alpha field. You must set the "enable-api-fields" feature flag to "alpha" + // for this field to be supported. + // + // Default is the value a result produces if no result is produced by Task + // +optional + Default *ResultValue `json:"default,omitempty"` } // TaskRunResult used to describe the results of a task diff --git a/pkg/apis/pipeline/v1beta1/result_validation.go b/pkg/apis/pipeline/v1beta1/result_validation.go index 4232b174fad..1e7f9fe0cb6 100644 --- a/pkg/apis/pipeline/v1beta1/result_validation.go +++ b/pkg/apis/pipeline/v1beta1/result_validation.go @@ -27,6 +27,11 @@ func (tr TaskResult) Validate(ctx context.Context) (errs *apis.FieldError) { if !resultNameFormatRegex.MatchString(tr.Name) { return apis.ErrInvalidKeyName(tr.Name, "name", fmt.Sprintf("Name must consist of alphanumeric characters, '-', '_', and must start and end with an alphanumeric character (e.g. 'MyName', or 'my-name', or 'my_name', regex used for validation is '%s')", ResultNameFormat)) } + // Default results in alpha feature + if tr.Default != nil { + errs = errs.Also(version.ValidateEnabledAPIFields(ctx, "default results", config.AlphaAPIFields)) + return errs + } // Array and Object is alpha feature if tr.Type == ResultsTypeArray || tr.Type == ResultsTypeObject { errs := validateObjectResult(tr) diff --git a/pkg/apis/pipeline/v1beta1/result_validation_test.go b/pkg/apis/pipeline/v1beta1/result_validation_test.go index 57019c02143..63d66bd8864 100644 --- a/pkg/apis/pipeline/v1beta1/result_validation_test.go +++ b/pkg/apis/pipeline/v1beta1/result_validation_test.go @@ -67,6 +67,15 @@ func TestResultsValidate(t *testing.T) { Properties: map[string]v1beta1.PropertySpec{"hello": {Type: v1beta1.ParamTypeString}}, }, apiFields: "alpha", + }, { + name: "valid result with default value", + Result: v1beta1.TaskResult{ + Name: "MY-RESULT", + Type: v1beta1.ResultsTypeString, + Description: "my great result", + Default: &v1beta1.ParamValue{StringVal: "string value"}, + }, + apiFields: "alpha", }} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -161,6 +170,18 @@ func TestResultsValidateError(t *testing.T) { Message: "missing field(s)", Paths: []string{"MY-RESULT.properties"}, }, + }, { + name: "valid result with default value", + Result: v1beta1.TaskResult{ + Name: "MY-RESULT", + Type: v1beta1.ResultsTypeString, + Description: "my great result", + Default: &v1beta1.ParamValue{StringVal: "string value"}, + }, + apiFields: "stable", + expectedError: apis.FieldError{ + Message: "default results requires \"enable-api-fields\" feature gate to be \"alpha\" but it is \"stable\"", + }, }} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/pkg/apis/pipeline/v1beta1/swagger.json b/pkg/apis/pipeline/v1beta1/swagger.json index 1f451832821..89f8b95b184 100644 --- a/pkg/apis/pipeline/v1beta1/swagger.json +++ b/pkg/apis/pipeline/v1beta1/swagger.json @@ -2572,6 +2572,10 @@ "name" ], "properties": { + "default": { + "description": "This is an alpha field. You must set the \"enable-api-fields\" feature flag to \"alpha\" for this field to be supported.\n\nDefault is the value a result produces if no result is produced by Task", + "$ref": "#/definitions/v1beta1.ParamValue" + }, "description": { "description": "Description is a human-readable description of the result", "type": "string" diff --git a/pkg/apis/pipeline/v1beta1/zz_generated.deepcopy.go b/pkg/apis/pipeline/v1beta1/zz_generated.deepcopy.go index 2706537bef1..f1e0e055cdf 100644 --- a/pkg/apis/pipeline/v1beta1/zz_generated.deepcopy.go +++ b/pkg/apis/pipeline/v1beta1/zz_generated.deepcopy.go @@ -1834,6 +1834,11 @@ func (in *TaskResult) DeepCopyInto(out *TaskResult) { (*out)[key] = val } } + if in.Default != nil { + in, out := &in.Default, &out.Default + *out = new(ParamValue) + (*in).DeepCopyInto(*out) + } return } diff --git a/pkg/reconciler/taskrun/taskrun.go b/pkg/reconciler/taskrun/taskrun.go index cc4ae38ee68..753d77a59d4 100644 --- a/pkg/reconciler/taskrun/taskrun.go +++ b/pkg/reconciler/taskrun/taskrun.go @@ -428,6 +428,19 @@ func (c *Reconciler) prepare(ctx context.Context, tr *v1beta1.TaskRun) (*v1beta1 return nil, nil, controller.NewPermanentError(err) } + if tr.Status.TaskRunResults == nil || len(tr.Status.TaskRunResults) == 0 { + tr.Status.TaskRunResults = make([]v1beta1.TaskRunResult, 0) + for _, tR := range rtr.TaskSpec.Results { + if tR.Default != nil { + tr.Status.TaskRunResults = append(tr.Status.TaskRunResults, v1beta1.TaskRunResult{ + Name: tR.Name, + Type: tR.Type, + Value: *tR.Default, + }) + } + } + } + // Initialize the cloud events if at least a CloudEventResource is defined // and they have not been initialized yet. // FIXME(afrittoli) This resource specific logic will have to be replaced @@ -545,6 +558,15 @@ func (c *Reconciler) reconcile(ctx context.Context, tr *v1beta1.TaskRun, rtr *re return err } + if string(tr.Status.Conditions[0].Type) == string(apis.ConditionSucceeded) && string(tr.Status.Conditions[0].Status) != string(corev1.ConditionUnknown) { + + if err := validateResultsProduced(tr, rtr.TaskSpec); err != nil { + logger.Error(err) + tr.Status.MarkResourceFailed(v1beta1.TaskRunReasonFailed, err) + return err + } + } + logger.Infof("Successfully reconciled taskrun %s/%s with status: %#v", tr.Name, tr.Namespace, tr.Status.GetCondition(apis.ConditionSucceeded)) return nil } diff --git a/pkg/reconciler/taskrun/taskrun_test.go b/pkg/reconciler/taskrun/taskrun_test.go index b75204b7f6a..5617c3b155f 100644 --- a/pkg/reconciler/taskrun/taskrun_test.go +++ b/pkg/reconciler/taskrun/taskrun_test.go @@ -25,6 +25,7 @@ import ( "net/url" "os" "path/filepath" + "reflect" "strconv" "strings" "testing" @@ -4980,3 +4981,113 @@ status: t.Errorf("expected Status.TaskSpec to match, but differed: %s", diff.PrintWantGot(d)) } } + +func TestReconcile_TestDefaultResults(t *testing.T) { + + defaultStringResult := "default-result" + defaultArrayResult := []string{"default-result-a", "default-result-b"} + defaultObjectResult := map[string]string{"url": "foobar", "commit": "commit"} + + defaultResultsTask := &v1beta1.Task{ + ObjectMeta: objectMeta("test-results-task", "foo"), + Spec: v1beta1.TaskSpec{ + Steps: []v1beta1.Step{simpleStep}, + Results: []v1beta1.TaskResult{ + { + Name: "aResult", + Type: v1beta1.ResultsTypeString, + Default: &v1beta1.ParamValue{StringVal: defaultStringResult}, + }, + { + Name: "bResult", + Type: v1beta1.ResultsTypeArray, + Default: &v1beta1.ParamValue{ArrayVal: defaultArrayResult}, + }, + { + Name: "cResult", + Type: v1beta1.ResultsTypeObject, + Properties: map[string]v1beta1.PropertySpec{"url": {Type: "string"}, "commit": {Type: "string"}}, + Default: &v1beta1.ParamValue{ObjectVal: defaultObjectResult}, + }, + }, + }, + } + + taskRunWithResults := parse.MustParseTaskRun(t, ` +metadata: + name: test-taskrun-results-type-valid + namespace: foo +spec: + taskRef: + name: test-results-task +status: + taskResults: + - name: aResult + type: string + value: default-result + - name: bResult + type: array + value: + - default-result-a + - default-result-b + - name: cResult + type: object + value: + url: foobar + commit: commit +`) + + d := test.Data{ + TaskRuns: []*v1beta1.TaskRun{taskRunWithResults}, + Tasks: []*v1beta1.Task{defaultResultsTask}, + ConfigMaps: []*corev1.ConfigMap{{ + ObjectMeta: metav1.ObjectMeta{Namespace: system.Namespace(), Name: config.GetFeatureFlagsConfigName()}, + Data: map[string]string{ + "enable-api-fields": config.AlphaAPIFields, + }, + }}, + } + for _, tc := range []struct { + name string + taskRun *v1beta1.TaskRun + }{{ + name: "taskrun with default results", + taskRun: taskRunWithResults, + }} { + t.Run(tc.name, func(t *testing.T) { + testAssets, cancel := getTaskRunController(t, d) + defer cancel() + createServiceAccount(t, testAssets, tc.taskRun.Spec.ServiceAccountName, tc.taskRun.Namespace) + + // Reconcile the TaskRun. This creates a Pod. + if err := testAssets.Controller.Reconciler.Reconcile(testAssets.Ctx, getRunName(tc.taskRun)); err == nil { + t.Error("Wanted a wrapped requeue error, but got nil.") + } else if ok, _ := controller.IsRequeueKey(err); !ok { + t.Errorf("Error reconciling TaskRun. Got error %v", err) + } + + tr, err := testAssets.Clients.Pipeline.TektonV1beta1().TaskRuns(tc.taskRun.Namespace).Get(testAssets.Ctx, tc.taskRun.Name, metav1.GetOptions{}) + if err != nil { + t.Fatalf("getting updated taskrun: %v", err) + } + + condition := tr.Status.GetCondition(apis.ConditionSucceeded) + if condition.Type != apis.ConditionSucceeded || condition.Reason != "Running" { + t.Errorf("Expected TaskRun to succeed but it did not. Final conditions were:\n%#v", tr.Status.Conditions) + } + + if !strings.EqualFold(tr.Status.TaskRunResults[0].Value.StringVal, defaultStringResult) { + t.Errorf("Expected default result but found something else") + } + + if !reflect.DeepEqual(tr.Status.TaskRunResults[1].Value.ArrayVal, defaultArrayResult) { + t.Errorf("Expected default result but found something else") + } + + if !reflect.DeepEqual(tr.Status.TaskRunResults[2].Value.ObjectVal, defaultObjectResult) { + t.Errorf("Expected default result but found something else") + } + + }) + } +} diff --git a/pkg/reconciler/taskrun/validate_resources.go b/pkg/reconciler/taskrun/validate_resources.go index 29dc1c096be..da073f74f2e 100644 --- a/pkg/reconciler/taskrun/validate_resources.go +++ b/pkg/reconciler/taskrun/validate_resources.go @@ -291,14 +291,7 @@ func validateSidecarOverrides(ts *v1beta1.TaskSpec, trs *v1beta1.TaskRunSpec) er // validateResults checks the emitted results type and object properties against the ones defined in spec. func validateTaskRunResults(tr *v1beta1.TaskRun, resolvedTaskSpec *v1beta1.TaskSpec) error { - specResults := []v1beta1.TaskResult{} - if tr.Spec.TaskSpec != nil { - specResults = append(specResults, tr.Spec.TaskSpec.Results...) - } - - if resolvedTaskSpec != nil { - specResults = append(specResults, resolvedTaskSpec.Results...) - } + specResults := collectAllTaskResults(tr, resolvedTaskSpec) // When get the results, check if the type of result is the expected one if missmatchedTypes := mismatchedTypesResults(tr, specResults); len(missmatchedTypes) != 0 { @@ -312,6 +305,28 @@ func validateTaskRunResults(tr *v1beta1.TaskRun, resolvedTaskSpec *v1beta1.TaskS return nil } +func validateResultsProduced(tr *v1beta1.TaskRun, resolvedTaskSpec *v1beta1.TaskSpec) error { + specResults := collectAllTaskResults(tr, resolvedTaskSpec) + + neededResults := make([]string, 0) + providedResults := make([]string, 0) + // collect needed keys for object results + for _, r := range specResults { + neededResults = append(neededResults, r.Name) + } + + // collect provided keys for object results + for _, trr := range tr.Status.TaskRunResults { + providedResults = append(providedResults, trr.Name) + } + + if missingKeys := list.DiffLeft(neededResults, providedResults); len(missingKeys) != 0 { + return fmt.Errorf("%s TaskRun missing following results: %v", tr.Name, missingKeys) + } + + return nil +} + // mismatchedTypesResults checks and returns all the mismatched types of emitted results against specified results. func mismatchedTypesResults(tr *v1beta1.TaskRun, specResults []v1beta1.TaskResult) map[string][]string { neededTypes := make(map[string][]string) @@ -548,3 +563,16 @@ func validateContainerParamArrayIndexing(c *corev1.Container, arrayParams map[st extractParamIndex(v.SubPath, arrayParams, outofBoundParams) } } + +// Collects all the Results from TaskRun.Spec.TaskSpec and Task.TaskSpec into one array +func collectAllTaskResults(tr *v1beta1.TaskRun, resolvedTaskSpec *v1beta1.TaskSpec) []v1beta1.TaskResult { + specResults := []v1beta1.TaskResult{} + if tr.Spec.TaskSpec != nil { + specResults = append(specResults, tr.Spec.TaskSpec.Results...) + } + + if resolvedTaskSpec != nil { + specResults = append(specResults, resolvedTaskSpec.Results...) + } + return specResults +} diff --git a/pkg/reconciler/taskrun/validate_resources_test.go b/pkg/reconciler/taskrun/validate_resources_test.go index 5771b3acd74..e721f27eb96 100644 --- a/pkg/reconciler/taskrun/validate_resources_test.go +++ b/pkg/reconciler/taskrun/validate_resources_test.go @@ -19,6 +19,7 @@ package taskrun import ( "context" "fmt" + "reflect" "strings" "testing" @@ -1077,3 +1078,170 @@ func TestValidateParamArrayIndex(t *testing.T) { } } + +func TestValidateMissingResultsInTaskRuns(t *testing.T) { + tcs := []struct { + name string + tr *v1beta1.TaskRun + rtr *v1beta1.TaskSpec + wantErr bool + }{{ + name: "all results emitted by taskrun", + tr: &v1beta1.TaskRun{ + Spec: v1beta1.TaskRunSpec{ + TaskSpec: &v1beta1.TaskSpec{ + Results: []v1beta1.TaskResult{ + { + Name: "string-result", + Type: v1beta1.ResultsTypeString, + }, + { + Name: "array-result", + Type: v1beta1.ResultsTypeArray, + }, + { + Name: "object-result", + Type: v1beta1.ResultsTypeObject, + Properties: map[string]v1beta1.PropertySpec{"hello": {Type: "string"}}, + }, + }, + }, + }, + Status: v1beta1.TaskRunStatus{ + TaskRunStatusFields: v1beta1.TaskRunStatusFields{ + TaskRunResults: []v1beta1.TaskRunResult{ + { + Name: "string-result", + Type: v1beta1.ResultsTypeString, + Value: *v1beta1.NewStructuredValues("hello"), + }, + { + Name: "array-result", + Type: v1beta1.ResultsTypeArray, + Value: *v1beta1.NewStructuredValues("hello", "world"), + }, + { + Name: "object-result", + Type: v1beta1.ResultsTypeObject, + Value: *v1beta1.NewObject(map[string]string{"hello": "world"}), + }, + }, + }, + }, + }, + rtr: &v1beta1.TaskSpec{ + Results: []v1beta1.TaskResult{}, + }, + wantErr: false, + }, { + name: "result was missed to be produced", + tr: &v1beta1.TaskRun{ + Spec: v1beta1.TaskRunSpec{ + TaskSpec: &v1beta1.TaskSpec{ + Results: []v1beta1.TaskResult{ + { + Name: "string-result", + Type: v1beta1.ResultsTypeString, + }, + { + Name: "array-result", + Type: v1beta1.ResultsTypeArray, + }, + { + Name: "object-result", + Type: v1beta1.ResultsTypeObject, + Properties: map[string]v1beta1.PropertySpec{"hello": {Type: "string"}}, + }, + }, + }, + }, + Status: v1beta1.TaskRunStatus{ + TaskRunStatusFields: v1beta1.TaskRunStatusFields{ + TaskRunResults: []v1beta1.TaskRunResult{ + { + Name: "string-result", + Type: v1beta1.ResultsTypeArray, + Value: *v1beta1.NewStructuredValues("hello", "world"), + }, + { + Name: "array-result", + Type: v1beta1.ResultsTypeObject, + Value: *v1beta1.NewObject(map[string]string{"hello": "world"}), + }, + }, + }, + }, + }, + rtr: &v1beta1.TaskSpec{ + Results: []v1beta1.TaskResult{}, + }, + wantErr: true, + }} + for _, tc := range tcs { + t.Run(tc.name, func(t *testing.T) { + err := validateResultsProduced(tc.tr, tc.rtr) + if (err != nil) != tc.wantErr { + t.Errorf("expected err: %t, but got err %s", tc.wantErr, err) + } + }) + } +} + +func TestCollectAllTaskResults(t *testing.T) { + tcs := []struct { + name string + tr *v1beta1.TaskRun + rtr *v1beta1.TaskSpec + expected []v1beta1.TaskResult + }{{ + name: "all results emitted by taskrun", + tr: &v1beta1.TaskRun{ + Spec: v1beta1.TaskRunSpec{ + TaskSpec: &v1beta1.TaskSpec{ + Results: []v1beta1.TaskResult{ + { + Name: "string-result", + Type: v1beta1.ResultsTypeString, + }, + { + Name: "array-result", + Type: v1beta1.ResultsTypeArray, + }, + }, + }, + }, + }, + rtr: &v1beta1.TaskSpec{ + Results: []v1beta1.TaskResult{ + { + Name: "object-result", + Type: v1beta1.ResultsTypeObject, + Properties: map[string]v1beta1.PropertySpec{"hello": {Type: "string"}}, + }, + }, + }, + expected: []v1beta1.TaskResult{ + { + Name: "string-result", + Type: v1beta1.ResultsTypeString, + }, + { + Name: "array-result", + Type: v1beta1.ResultsTypeArray, + }, + { + Name: "object-result", + Type: v1beta1.ResultsTypeObject, + Properties: map[string]v1beta1.PropertySpec{"hello": {Type: "string"}}, + }, + }, + }} + for _, tc := range tcs { + t.Run(tc.name, func(t *testing.T) { + actualResultsArray := collectAllTaskResults(tc.tr, tc.rtr) + if !reflect.DeepEqual(tc.expected, actualResultsArray) { + t.Errorf("expected length: %d, but got length: %d", len(tc.expected), len(actualResultsArray)) + } + }) + } +} diff --git a/test/ignore_step_error_test.go b/test/ignore_step_error_test.go index bc77fdcc8f0..d3329733236 100644 --- a/test/ignore_step_error_test.go +++ b/test/ignore_step_error_test.go @@ -26,7 +26,7 @@ import ( "github.com/tektoncd/pipeline/test/parse" - "github.com/tektoncd/pipeline/pkg/reconciler/pipelinerun" + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" knativetest "knative.dev/pkg/test" "knative.dev/pkg/test/helpers" @@ -77,7 +77,7 @@ spec: } t.Logf("Waiting for PipelineRun in namespace %s to fail", namespace) - if err := WaitForPipelineRunState(ctx, c, pipelineRun.Name, timeout, FailedWithReason(pipelinerun.ReasonInvalidTaskResultReference, pipelineRun.Name), "InvalidTaskResultReference"); err != nil { + if err := WaitForPipelineRunState(ctx, c, pipelineRun.Name, timeout, FailedWithReason(v1beta1.PipelineRunReasonFailed.String(), pipelineRun.Name), "Tasks Completed: 1 (Failed: 1, Cancelled 0), Skipped: 1"); err != nil { t.Errorf("Error waiting for PipelineRun to fail: %s", err) } diff --git a/test/pipelinefinally_test.go b/test/pipelinefinally_test.go index c5afe638c09..d373d9d2ff5 100644 --- a/test/pipelinefinally_test.go +++ b/test/pipelinefinally_test.go @@ -273,8 +273,8 @@ spec: t.Errorf("Error waiting for TaskRun to succeed: %v", err) } case n == "finaltask1": - if err := WaitForTaskRunState(ctx, c, taskrunItem.Name, TaskRunSucceed(taskrunItem.Name), "TaskRunSuccess"); err != nil { - t.Errorf("Error waiting for TaskRun to succeed: %v", err) + if err := WaitForTaskRunState(ctx, c, taskrunItem.Name, TaskRunFailed(taskrunItem.Name), "TaskRunFailed"); err != nil { + t.Errorf("Error waiting for TaskRun to fail: %v", err) } finalTaskStartTime = taskrunItem.Status.StartTime case n == "finaltask2": diff --git a/third_party/LICENSE b/third_party/LICENSE deleted file mode 100644 index 6a66aea5eaf..00000000000 --- a/third_party/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/third_party/crypto/internal/boring/LICENSE b/third_party/crypto/internal/boring/LICENSE deleted file mode 100644 index 38990bdb771..00000000000 --- a/third_party/crypto/internal/boring/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ -The Go source code and supporting files in this directory -are covered by the usual Go license (see ../../../../LICENSE). - -When building with GOEXPERIMENT=boringcrypto, the following applies. - -The goboringcrypto_linux_amd64.syso object file is built -from BoringSSL source code by build/build.sh and is covered -by the BoringSSL license reproduced below and also at -https://boringssl.googlesource.com/boringssl/+/fips-20190808/LICENSE. - -BoringSSL is a fork of OpenSSL. As such, large parts of it fall under OpenSSL -licensing. Files that are completely new have a Google copyright and an ISC -license. This license is reproduced at the bottom of this file. - -Contributors to BoringSSL are required to follow the CLA rules for Chromium: -https://cla.developers.google.com/clas - -Some files from Intel are under yet another license, which is also included -underneath. - -The OpenSSL toolkit stays under a dual license, i.e. both the conditions of the -OpenSSL License and the original SSLeay license apply to the toolkit. See below -for the actual license texts. Actually both licenses are BSD-style Open Source -licenses. In case of any license issues related to OpenSSL please contact -openssl-core@openssl.org. - -The following are Google-internal bug numbers where explicit permission from -some authors is recorded for use of their work. (This is purely for our own -record keeping.) - 27287199 - 27287880 - 27287883 - - OpenSSL License - --------------- - -/* ==================================================================== - * Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - - Original SSLeay License - ----------------------- - -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - - -ISC license used for completely new code in BoringSSL: - -/* Copyright (c) 2015, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - - -Some files from Intel carry the following license: - -# Copyright (c) 2012, Intel Corporation -# -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the -# distribution. -# -# * Neither the name of the Intel Corporation nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# -# THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION ""AS IS"" AND ANY -# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/third_party/vendor/golang.org/x/crypto/LICENSE b/third_party/vendor/golang.org/x/crypto/LICENSE deleted file mode 100644 index 6a66aea5eaf..00000000000 --- a/third_party/vendor/golang.org/x/crypto/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/third_party/vendor/golang.org/x/net/LICENSE b/third_party/vendor/golang.org/x/net/LICENSE deleted file mode 100644 index 6a66aea5eaf..00000000000 --- a/third_party/vendor/golang.org/x/net/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/third_party/vendor/golang.org/x/text/LICENSE b/third_party/vendor/golang.org/x/text/LICENSE deleted file mode 100644 index 6a66aea5eaf..00000000000 --- a/third_party/vendor/golang.org/x/text/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.