diff --git a/cmd/entrypoint/main.go b/cmd/entrypoint/main.go index 54422d789e5..ee3cf089b90 100644 --- a/cmd/entrypoint/main.go +++ b/cmd/entrypoint/main.go @@ -176,7 +176,7 @@ func main() { if err := e.Go(); err != nil { breakpointExitPostFile := e.PostFile + breakpointExitSuffix switch t := err.(type) { //nolint:errorlint // checking for multiple types with errors.As is ugly. - case skipError: + case entrypoint.SkipError: log.Print("Skipping step because a previous step failed") os.Exit(1) case termination.MessageLengthError: diff --git a/cmd/entrypoint/waiter.go b/cmd/entrypoint/waiter.go index 656b015af74..f5cc79e6d0b 100644 --- a/cmd/entrypoint/waiter.go +++ b/cmd/entrypoint/waiter.go @@ -71,7 +71,7 @@ func (rw *realWaiter) Wait(ctx context.Context, file string, expectContent bool, if breakpointOnFailure { return nil } - return skipError("error file present, bail and skip the step") + return entrypoint.SkipErroPreviousStepFailed } select { case <-ctx.Done(): @@ -86,9 +86,3 @@ func (rw *realWaiter) Wait(ctx context.Context, file string, expectContent bool, } } } - -type skipError string - -func (e skipError) Error() string { - return string(e) -} diff --git a/pkg/entrypoint/entrypointer.go b/pkg/entrypoint/entrypointer.go index ac7baf16dfb..d986cc8586e 100644 --- a/pkg/entrypoint/entrypointer.go +++ b/pkg/entrypoint/entrypointer.go @@ -53,11 +53,19 @@ func (e ContextError) Error() string { return string(e) } +type SkipError string + +func (e SkipError) Error() string { + return string(e) +} + var ( // ErrContextDeadlineExceeded is the error returned when the context deadline is exceeded ErrContextDeadlineExceeded = ContextError(context.DeadlineExceeded.Error()) // ErrContextCanceled is the error returned when the context is canceled ErrContextCanceled = ContextError(context.Canceled.Error()) + // SkipErroPreviousStepFailed is the error returned when the step is skipped due to previous step error + SkipErroPreviousStepFailed = SkipError("error file present, bail and skip the step") ) // IsContextDeadlineError determine whether the error is context deadline @@ -160,6 +168,11 @@ func (e Entrypointer) Go() error { Value: time.Now().Format(timeFormat), ResultType: result.InternalTektonResultType, }) + + if errors.Is(err, SkipErroPreviousStepFailed) { + output = append(output, e.getTerminationReason(result.TerminationReasonSkipped)) + } + return err } } @@ -189,28 +202,23 @@ func (e Entrypointer) Go() error { } }() err = e.Runner.Run(ctx, e.Command...) - if errors.Is(err, ErrContextDeadlineExceeded) { - output = append(output, result.RunResult{ - Key: "Reason", - Value: "TimeoutExceeded", - ResultType: result.InternalTektonResultType, - }) - } } var ee *exec.ExitError switch { case err != nil && errors.Is(err, ErrContextCanceled): logger.Info("Step was canceling") - output = append(output, result.RunResult{ - Key: "Reason", - Value: "Cancelled", - ResultType: result.InternalTektonResultType, - }) e.WritePostFile(e.PostFile, ErrContextCanceled) e.WriteExitCodeFile(e.StepMetadataDir, syscall.SIGKILL.String()) + output = append(output, e.getTerminationReason(result.TerminationReasonCancelled)) + + case errors.Is(err, ErrContextDeadlineExceeded): + e.WritePostFile(e.PostFile, err) + output = append(output, e.getTerminationReason(result.TerminationReasonTimeoutExceeded)) + case err != nil && e.BreakpointOnFailure: logger.Info("Skipping writing to PostFile") + case e.OnError == ContinueOnError && errors.As(err, &ee): // with continue on error and an ExitError, write non-zero exit code and a post file exitCode := strconv.Itoa(ee.ExitCode()) @@ -221,13 +229,18 @@ func (e Entrypointer) Go() error { }) e.WritePostFile(e.PostFile, nil) e.WriteExitCodeFile(e.StepMetadataDir, exitCode) + output = append(output, e.getTerminationReason(result.TerminationReasonContinued)) + case err == nil: // if err is nil, write zero exit code and a post file e.WritePostFile(e.PostFile, nil) e.WriteExitCodeFile(e.StepMetadataDir, "0") + output = append(output, e.getTerminationReason(result.TerminationReasonCompleted)) + default: // for a step without continue on error and any error, write a post file with .err e.WritePostFile(e.PostFile, err) + output = append(output, e.getTerminationReason(result.TerminationReasonError)) } // strings.Split(..) with an empty string returns an array that contains one element, an empty string. @@ -317,3 +330,12 @@ func (e Entrypointer) waitingCancellation(ctx context.Context, cancel context.Ca cancel() return nil } + +// getTerminationReason returns the run result for a termination +func (e Entrypointer) getTerminationReason(terminationReason string) result.RunResult { + return result.RunResult{ + Key: "Reason", + Value: terminationReason, + ResultType: result.InternalTektonResultType, + } +} diff --git a/pkg/result/result.go b/pkg/result/result.go index cfcbc3e90a2..22f0cac9e8c 100644 --- a/pkg/result/result.go +++ b/pkg/result/result.go @@ -33,6 +33,19 @@ const ( InternalTektonResultType = 3 // UnknownResultType default unknown result type value UnknownResultType = 10 + + // TerminationReasonCompleted indicates a step finished successfully. + TerminationReasonCompleted = "Completed" + // TerminationReasonContinued indicates a step errored but was ignored since onError was set to continue. + TerminationReasonContinued = "Continued" + // TerminationReasonError indicates a step failed with a non-zero exit code. + TerminationReasonError = "Error" + // TerminationReasonTimeoutExceeded indicates a step execution timed out. + TerminationReasonTimeoutExceeded = "TimeoutExceeded" + // TerminationReasonSkipped indicates a step execution was skipped due to previous step failed. + TerminationReasonSkipped = "Skipped" + // TerminationReasonCancelled indicates a step was cancelled by user. + TerminationReasonCancelled = "Cancelled" ) // RunResult is used to write key/value pairs to TaskRun pod termination messages.