-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add CloudEvents for Run definitions #4659
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,11 +6,12 @@ weight: 700 | |
--> | ||
# Events in Tekton | ||
|
||
Tekton's task controller emits [Kubernetes events](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#event-v1-core) | ||
Tekton's controllers emits [Kubernetes events](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#event-v1-core) | ||
when `TaskRuns` and `PipelineRuns` execute. This allows you to monitor and react to what's happening during execution by | ||
retrieving those events using the `kubectl describe` command. Tekton can also emit [CloudEvents](https://github.com/cloudevents/spec). | ||
|
||
**Note:** `Conditions` [do not yet emit events](https://github.com/tektoncd/pipeline/issues/2461). | ||
**Note:** `Conditions` [do not emit events](https://github.com/tektoncd/pipeline/issues/2461) | ||
but the underlying `TaskRun` do. | ||
|
||
## Events in `TaskRuns` | ||
|
||
|
@@ -53,7 +54,7 @@ events as described in the table below. | |
|
||
Tekton sends cloud events in a parallel routine to allow for retries without blocking the | ||
reconciler. A routine is started every time the `Succeeded` condition changes - either state, | ||
reason or message. Retries are sent using an exponential back-off strategy. | ||
reason or message. Retries are sent using an exponential back-off strategy. | ||
Because of retries, events are not guaranteed to be sent to the target sink in the order they happened. | ||
|
||
Resource |Event |Event Type | ||
|
@@ -68,6 +69,12 @@ Resource |Event |Event Type | |
`PipelineRun` | `Condition Change while Running` | `dev.tekton.event.pipelinerun.unknown.v1` | ||
`PipelineRun` | `Succeed` | `dev.tekton.event.pipelinerun.successful.v1` | ||
`PipelineRun` | `Failed` | `dev.tekton.event.pipelinerun.failed.v1` | ||
`Run` | `Started` | `dev.tekton.event.run.started.v1` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what's the reason not to send a condition change while running event? is this because we don't know what the run's previous status was, and can't make assumptions based on what it currently is? Is this a feature users might want? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We cannot make assumptions about the |
||
`Run` | `Running` | `dev.tekton.event.run.running.v1` | ||
`Run` | `Succeed` | `dev.tekton.event.run.successful.v1` | ||
`Run` | `Failed` | `dev.tekton.event.run.failed.v1` | ||
|
||
`CloudEvents` for `Runs` are defined but not sent yet. | ||
|
||
## Format of `CloudEvents` | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,19 +20,21 @@ import ( | |
"testing" | ||
|
||
"github.com/google/go-cmp/cmp" | ||
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" | ||
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" | ||
"github.com/tektoncd/pipeline/test/diff" | ||
"github.com/tektoncd/pipeline/test/names" | ||
corev1 "k8s.io/api/core/v1" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
"knative.dev/pkg/apis" | ||
duckv1 "knative.dev/pkg/apis/duck/v1" | ||
duckv1beta1 "knative.dev/pkg/apis/duck/v1beta1" | ||
) | ||
|
||
const ( | ||
defaultEventSourceURI = "/runtocompletion/1234" | ||
taskRunName = "faketaskrunname" | ||
pipelineRunName = "fakepipelinerunname" | ||
runName = "fakerunname" | ||
) | ||
|
||
func getTaskRunByCondition(status corev1.ConditionStatus, reason string) *v1beta1.TaskRun { | ||
|
@@ -83,6 +85,34 @@ func getPipelineRunByCondition(status corev1.ConditionStatus, reason string) *v1 | |
} | ||
} | ||
|
||
func createRunWithCondition(status corev1.ConditionStatus, reason string) *v1alpha1.Run { | ||
myrun := &v1alpha1.Run{ | ||
TypeMeta: metav1.TypeMeta{ | ||
Kind: "Run", | ||
APIVersion: "v1alpha1", | ||
}, | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: runName, | ||
Namespace: "marshmallow", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. :) |
||
SelfLink: defaultEventSourceURI, | ||
}, | ||
Spec: v1alpha1.RunSpec{}, | ||
} | ||
switch status { | ||
case corev1.ConditionFalse, corev1.ConditionUnknown, corev1.ConditionTrue: | ||
myrun.Status = v1alpha1.RunStatus{ | ||
Status: duckv1.Status{ | ||
Conditions: []apis.Condition{{ | ||
Type: apis.ConditionSucceeded, | ||
Status: status, | ||
Reason: reason, | ||
}}, | ||
}, | ||
} | ||
} | ||
return myrun | ||
} | ||
|
||
func TestEventForTaskRun(t *testing.T) { | ||
taskRunTests := []struct { | ||
desc string | ||
|
@@ -121,7 +151,6 @@ func TestEventForTaskRun(t *testing.T) { | |
|
||
for _, c := range taskRunTests { | ||
t.Run(c.desc, func(t *testing.T) { | ||
names.TestingSeed() | ||
|
||
got, err := eventForTaskRun(c.taskRun) | ||
if err != nil { | ||
|
@@ -180,7 +209,6 @@ func TestEventForPipelineRun(t *testing.T) { | |
|
||
for _, c := range pipelineRunTests { | ||
t.Run(c.desc, func(t *testing.T) { | ||
names.TestingSeed() | ||
|
||
got, err := eventForPipelineRun(c.pipelineRun) | ||
if err != nil { | ||
|
@@ -209,3 +237,61 @@ func TestEventForPipelineRun(t *testing.T) { | |
}) | ||
} | ||
} | ||
|
||
func TestEventForRun(t *testing.T) { | ||
runTests := []struct { | ||
desc string | ||
run *v1alpha1.Run | ||
wantEventType TektonEventType | ||
}{{ | ||
desc: "send a cloud event with unset condition, just started", | ||
run: createRunWithCondition("", ""), | ||
wantEventType: RunStartedEventV1, | ||
}, { | ||
desc: "send a cloud event with unknown status run, empty reason", | ||
run: createRunWithCondition(corev1.ConditionUnknown, ""), | ||
wantEventType: RunRunningEventV1, | ||
}, { | ||
desc: "send a cloud event with unknown status run, some reason set", | ||
run: createRunWithCondition(corev1.ConditionUnknown, "custom controller reason"), | ||
wantEventType: RunRunningEventV1, | ||
}, { | ||
desc: "send a cloud event with successful status run", | ||
run: createRunWithCondition(corev1.ConditionTrue, "yay"), | ||
wantEventType: RunSuccessfulEventV1, | ||
}, { | ||
desc: "send a cloud event with unknown status run", | ||
run: createRunWithCondition(corev1.ConditionFalse, "meh"), | ||
wantEventType: RunFailedEventV1, | ||
}} | ||
|
||
for _, c := range runTests { | ||
t.Run(c.desc, func(t *testing.T) { | ||
|
||
got, err := eventForRun(c.run) | ||
if err != nil { | ||
t.Fatalf("I did not expect an error but I got %s", err) | ||
} else { | ||
wantSubject := runName | ||
if d := cmp.Diff(wantSubject, got.Subject()); d != "" { | ||
t.Errorf("Wrong Event ID %s", diff.PrintWantGot(d)) | ||
} | ||
if d := cmp.Diff(string(c.wantEventType), got.Type()); d != "" { | ||
t.Errorf("Wrong Event Type %s", diff.PrintWantGot(d)) | ||
} | ||
wantData := newTektonCloudEventData(c.run) | ||
gotData := TektonCloudEventData{} | ||
if err := got.DataAs(&gotData); err != nil { | ||
t.Errorf("Unexpected error from DataAsl; %s", err) | ||
} | ||
if d := cmp.Diff(wantData, gotData); d != "" { | ||
t.Errorf("Wrong Event data %s", diff.PrintWantGot(d)) | ||
} | ||
|
||
if err := got.Validate(); err != nil { | ||
t.Errorf("Expected event to be valid; %s", err) | ||
} | ||
} | ||
}) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just some grammar nits:
controllers emits
->controllers emit
andthe underlying TaskRun do
->the underlying TaskRuns do
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch, thank you!