You've already forked woodpecker
mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2025-11-23 21:44:44 +02:00
Trace errors during SetupWorkflow, make service step setup errors visible to user (#5559)
Co-authored-by: qwerty287 <80460567+qwerty287@users.noreply.github.com> Co-authored-by: Robert Kaussow <mail@thegeeklab.de>
This commit is contained in:
@@ -41,6 +41,7 @@ import (
|
|||||||
"k8s.io/client-go/tools/cache"
|
"k8s.io/client-go/tools/cache"
|
||||||
|
|
||||||
"go.woodpecker-ci.org/woodpecker/v3/pipeline/backend/types"
|
"go.woodpecker-ci.org/woodpecker/v3/pipeline/backend/types"
|
||||||
|
pipelineErrors "go.woodpecker-ci.org/woodpecker/v3/pipeline/errors/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -237,7 +238,10 @@ func (e *kube) SetupWorkflow(ctx context.Context, conf *types.Config, taskUUID s
|
|||||||
if isService(step) {
|
if isService(step) {
|
||||||
svc, err := startService(ctx, e, step)
|
svc, err := startService(ctx, e, step)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return &pipelineErrors.ErrInvalidWorkflowSetup{
|
||||||
|
Err: err,
|
||||||
|
Step: step,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
hostAlias := types.HostAlias{Name: step.Networks[0].Aliases[0], IP: svc.Spec.ClusterIP}
|
hostAlias := types.HostAlias{Name: step.Networks[0].Aliases[0], IP: svc.Spec.ClusterIP}
|
||||||
extraHosts = append(extraHosts, hostAlias)
|
extraHosts = append(extraHosts, hostAlias)
|
||||||
|
|||||||
@@ -43,6 +43,10 @@ func mkService(step *types.Step, config *config) (*v1.Service, error) {
|
|||||||
ServiceLabel: name,
|
ServiceLabel: name,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(step.Ports) == 0 {
|
||||||
|
return nil, fmt.Errorf("kubernetes backend requires explicitly exposed ports for service steps, add 'ports' configuration to step '%s'", step.Name)
|
||||||
|
}
|
||||||
|
|
||||||
var svcPorts []v1.ServicePort
|
var svcPorts []v1.ServicePort
|
||||||
for _, port := range step.Ports {
|
for _, port := range step.Ports {
|
||||||
svcPorts = append(svcPorts, servicePort(port))
|
svcPorts = append(svcPorts, servicePort(port))
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
package types
|
package types
|
||||||
|
|
||||||
import "fmt"
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
backend "go.woodpecker-ci.org/woodpecker/v3/pipeline/backend/types"
|
||||||
|
)
|
||||||
|
|
||||||
type PipelineErrorType string
|
type PipelineErrorType string
|
||||||
|
|
||||||
@@ -22,3 +26,15 @@ type PipelineError struct {
|
|||||||
func (e *PipelineError) Error() string {
|
func (e *PipelineError) Error() string {
|
||||||
return fmt.Sprintf("[%s] %s", e.Type, e.Message)
|
return fmt.Sprintf("[%s] %s", e.Type, e.Message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ErrInvalidWorkflowSetup struct {
|
||||||
|
Err error
|
||||||
|
Step *backend.Step
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *ErrInvalidWorkflowSetup) Error() string {
|
||||||
|
if e.Step != nil {
|
||||||
|
return fmt.Sprintf("error in workflow setup step '%s': %v", e.Step.Name, e.Err)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("error in workflow setup: %v", e.Err)
|
||||||
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import (
|
|||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
|
|
||||||
backend "go.woodpecker-ci.org/woodpecker/v3/pipeline/backend/types"
|
backend "go.woodpecker-ci.org/woodpecker/v3/pipeline/backend/types"
|
||||||
|
pipelineErrors "go.woodpecker-ci.org/woodpecker/v3/pipeline/errors/types"
|
||||||
"go.woodpecker-ci.org/woodpecker/v3/pipeline/frontend/metadata"
|
"go.woodpecker-ci.org/woodpecker/v3/pipeline/frontend/metadata"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -116,6 +117,25 @@ func (r *Runtime) Run(runnerCtx context.Context) error {
|
|||||||
|
|
||||||
r.started = time.Now().Unix()
|
r.started = time.Now().Unix()
|
||||||
if err := r.engine.SetupWorkflow(runnerCtx, r.spec, r.taskUUID); err != nil {
|
if err := r.engine.SetupWorkflow(runnerCtx, r.spec, r.taskUUID); err != nil {
|
||||||
|
var stepErr *pipelineErrors.ErrInvalidWorkflowSetup
|
||||||
|
if errors.As(err, &stepErr) {
|
||||||
|
state := new(State)
|
||||||
|
state.Pipeline.Step = stepErr.Step
|
||||||
|
state.Pipeline.Error = stepErr.Err
|
||||||
|
state.Process = &backend.State{
|
||||||
|
Error: stepErr.Err,
|
||||||
|
Exited: true,
|
||||||
|
ExitCode: 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trace the error if we have a tracer
|
||||||
|
if r.tracer != nil {
|
||||||
|
if err := r.tracer.Trace(state); err != nil {
|
||||||
|
logger.Error().Err(err).Msg("failed to trace step error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user