diff --git a/cli/cdsctl/workflow_artifact.go b/cli/cdsctl/workflow_artifact.go index 94b2715130..d5a5acf274 100644 --- a/cli/cdsctl/workflow_artifact.go +++ b/cli/cdsctl/workflow_artifact.go @@ -59,7 +59,7 @@ var workflowArtifactDownloadCmd = cli.Command{ {Name: "number"}, }, OptionalArgs: []cli.Arg{ - {Name: "artefact-name"}, + {Name: "artifact-name"}, }, Flags: []cli.Flag{ { @@ -92,7 +92,7 @@ func workflowArtifactDownloadRun(v cli.Values) error { var ok bool for _, a := range artifacts { - if v.GetString("artefact-name") != "" && v.GetString("artefact-name") != a.Name { + if v.GetString("artifact-name") != "" && v.GetString("artifact-name") != a.Name { continue } if v.GetString("exclude") != "" && reg.MatchString(a.Name) { diff --git a/engine/worker/cmd_artifacts.go b/engine/worker/cmd_artifacts.go index 7d40ae7660..5dd4df036c 100644 --- a/engine/worker/cmd_artifacts.go +++ b/engine/worker/cmd_artifacts.go @@ -34,7 +34,7 @@ Inside a job, you can list artifacts of a workflow: } c.Flags().StringVar(&cmdDownloadWorkflowName, "workflow", "", "Workflow name. Optional, default: current workflow") c.Flags().StringVar(&cmdDownloadNumber, "number", "", "Workflow Number. Optional, default: current workflow run") - c.Flags().StringVar(&cmdDownloadArtefactName, "pattern", "", "Pattern matching files to list. Optional, default: *") + c.Flags().StringVar(&cmdDownloadArtifactName, "pattern", "", "Pattern matching files to list. Optional, default: *") c.Flags().StringVar(&cmdDownloadTag, "tag", "", "Tag matching files to list. Optional") return c @@ -64,7 +64,7 @@ func artifactsCmd() func(cmd *cobra.Command, args []string) { a := workerruntime.DownloadArtifact{ Workflow: cmdDownloadWorkflowName, Number: number, - Pattern: cmdDownloadArtefactName, + Pattern: cmdDownloadArtifactName, Tag: cmdDownloadTag, } diff --git a/engine/worker/cmd_download.go b/engine/worker/cmd_download.go index c47d33de52..e2264e8b4b 100644 --- a/engine/worker/cmd_download.go +++ b/engine/worker/cmd_download.go @@ -19,7 +19,7 @@ import ( var ( cmdDownloadWorkflowName string cmdDownloadNumber string - cmdDownloadArtefactName string + cmdDownloadArtifactName string cmdDownloadTag string ) @@ -51,7 +51,7 @@ Theses two commands have the same result: } c.Flags().StringVar(&cmdDownloadWorkflowName, "workflow", "", "Workflow name to download from. Optional, default: current workflow") c.Flags().StringVar(&cmdDownloadNumber, "number", "", "Workflow Number to download from. Optional, default: current workflow run") - c.Flags().StringVar(&cmdDownloadArtefactName, "pattern", "", "Pattern matching files to download. Optional, default: *") + c.Flags().StringVar(&cmdDownloadArtifactName, "pattern", "", "Pattern matching files to download. Optional, default: *") c.Flags().StringVar(&cmdDownloadTag, "tag", "", "Tag matching files to download. Optional") return c } @@ -81,7 +81,7 @@ func downloadCmd() func(cmd *cobra.Command, args []string) { a := workerruntime.DownloadArtifact{ Workflow: cmdDownloadWorkflowName, Number: number, - Pattern: cmdDownloadArtefactName, + Pattern: cmdDownloadArtifactName, Tag: cmdDownloadTag, Destination: wd, } @@ -107,7 +107,7 @@ func downloadCmd() func(cmd *cobra.Command, args []string) { if resp.StatusCode >= 300 { body, err := ioutil.ReadAll(resp.Body) if err != nil { - sdk.Exit("cannot artefact download HTTP %v\n", err) + sdk.Exit("cannot artifact download HTTP %v\n", err) } cdsError := sdk.DecodeError(body) sdk.Exit("download failed: %v\n", cdsError) diff --git a/engine/worker/cmd_upload.go b/engine/worker/cmd_upload.go index f7f7c94f77..238b5eea7a 100644 --- a/engine/worker/cmd_upload.go +++ b/engine/worker/cmd_upload.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/json" "fmt" + "io/ioutil" "net/http" "net/url" "os" @@ -88,7 +89,12 @@ func uploadCmd() func(cmd *cobra.Command, args []string) { } if resp.StatusCode >= 300 { - sdk.Exit("cannot artifact upload HTTP %d\n", resp.StatusCode) + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + sdk.Exit("cannot artifact upload HTTP %v\n", err) + } + cdsError := sdk.DecodeError(body) + sdk.Exit("artifact upload failed: %v\n", cdsError) } } } diff --git a/engine/worker/internal/action/builtin_artifact_download_test.go b/engine/worker/internal/action/builtin_artifact_download_test.go index 27b85a4e25..882f74aef1 100644 --- a/engine/worker/internal/action/builtin_artifact_download_test.go +++ b/engine/worker/internal/action/builtin_artifact_download_test.go @@ -19,12 +19,12 @@ func TestRunArtifactDownload(t *testing.T) { wk, ctx := SetupTest(t) as := []sdk.WorkflowNodeRunArtifact{ - sdk.WorkflowNodeRunArtifact{ + { ID: 1, Name: "myFile.txt", Tag: "999", }, - sdk.WorkflowNodeRunArtifact{ + { ID: 2, Name: "myFile.csv", Tag: "999", @@ -90,7 +90,7 @@ func TestRunArtifactDownloadOutsideWorkspace(t *testing.T) { fileName := sdk.RandomString(10) as := []sdk.WorkflowNodeRunArtifact{ - sdk.WorkflowNodeRunArtifact{ + { ID: 1, Name: fileName, Tag: "999", diff --git a/engine/worker/internal/action/builtin_artifact_upload.go b/engine/worker/internal/action/builtin_artifact_upload.go index f88a11b897..99b7c99502 100644 --- a/engine/worker/internal/action/builtin_artifact_upload.go +++ b/engine/worker/internal/action/builtin_artifact_upload.go @@ -2,7 +2,6 @@ package action import ( "context" - "errors" "fmt" "path/filepath" "strings" @@ -47,17 +46,17 @@ func RunArtifactUpload(ctx context.Context, wk workerruntime.Runtime, a sdk.Acti tag := sdk.ParameterFind(a.Parameters, "tag") if tag == nil { - return res, errors.New("tag variable is empty. aborting") + return res, sdk.NewError(sdk.ErrWorkerErrorCommand, fmt.Errorf("tag variable is empty. aborting")) } // Global all files matching filePath filesPath, err := afero.Glob(afero.NewOsFs(), artifactPath) if err != nil { - return res, fmt.Errorf("cannot perform globbing of pattern '%s': %s", artifactPath, err) + return res, sdk.NewError(sdk.ErrWorkerErrorCommand, fmt.Errorf("cannot perform globbing of pattern '%s': %s", artifactPath, err)) } if len(filesPath) == 0 { - return res, fmt.Errorf("pattern '%s' matched no file", artifactPath) + return res, sdk.NewError(sdk.ErrWorkerErrorCommand, fmt.Errorf("pattern '%s' matched no file", artifactPath)) } var globalError = &sdk.MultiError{} @@ -105,8 +104,7 @@ func RunArtifactUpload(ctx context.Context, wk workerruntime.Runtime, a sdk.Acti wgErrors.Wait() if !globalError.IsEmpty() { - log.Error(ctx, "Error while uploading artifact: %v", globalError.Error()) - return res, fmt.Errorf("error: %v", globalError.Error()) + return res, sdk.NewError(sdk.ErrUnknownError, fmt.Errorf("error: %v", globalError.Error())) } return res, nil diff --git a/engine/worker/internal/handler_download.go b/engine/worker/internal/handler_download.go index 750f1b27c4..35d007124f 100644 --- a/engine/worker/internal/handler_download.go +++ b/engine/worker/internal/handler_download.go @@ -141,7 +141,7 @@ func downloadHandler(ctx context.Context, wk *CurrentWorker) http.HandlerFunc { wg.Wait() if isInError { - newError := sdk.NewError(sdk.ErrUnknownError, fmt.Errorf("Error while downloading artefacts - see previous logs")) + newError := sdk.NewError(sdk.ErrUnknownError, fmt.Errorf("Error while downloading artifacts - see previous logs")) writeError(w, r, newError) } } diff --git a/engine/worker/internal/handler_key.go b/engine/worker/internal/handler_key.go index f1b5a9293c..85f7f444d9 100644 --- a/engine/worker/internal/handler_key.go +++ b/engine/worker/internal/handler_key.go @@ -21,8 +21,7 @@ func keyInstallHandler(ctx context.Context, wk *CurrentWorker) http.HandlerFunc body, err := ioutil.ReadAll(r.Body) if err != nil { - sdkerr := sdk.NewError(sdk.ErrWrongRequest, err).(sdk.Error) - writeJSON(w, sdkerr, sdkerr.Status) + writeError(w, r, sdk.NewError(sdk.ErrWrongRequest, err)) return } @@ -31,10 +30,7 @@ func keyInstallHandler(ctx context.Context, wk *CurrentWorker) http.HandlerFunc var mapBody = make(map[string]string) if len(body) > 0 { if err := json.Unmarshal(body, &mapBody); err != nil { - sdkerr := sdk.Error{ - Status: sdk.ErrWrongRequest.Status, - Message: err.Error()} - writeJSON(w, sdkerr, sdkerr.Status) + writeError(w, r, sdk.NewError(sdk.ErrWrongRequest, err)) return } } @@ -42,12 +38,8 @@ func keyInstallHandler(ctx context.Context, wk *CurrentWorker) http.HandlerFunc var key *sdk.Variable if wk.currentJob.secrets == nil { - err := sdk.Error{ - Message: "Cannot find any keys for your job", - Status: http.StatusBadRequest, - } log.Error(ctx, "%v", err) - writeJSON(w, err, err.Status) + writeError(w, r, sdk.NewError(sdk.ErrWrongRequest, fmt.Errorf("Cannot find any keys for your job"))) return } @@ -59,12 +51,8 @@ func keyInstallHandler(ctx context.Context, wk *CurrentWorker) http.HandlerFunc } if key == nil { - err := sdk.Error{ - Message: fmt.Sprintf("Key %s not found", keyName), - Status: http.StatusNotFound, - } log.Error(ctx, "%v", err) - writeJSON(w, err, err.Status) + writeError(w, r, sdk.NewError(sdk.ErrNotFound, fmt.Errorf("Cannot find any keys for your job"))) return } @@ -73,13 +61,9 @@ func keyInstallHandler(ctx context.Context, wk *CurrentWorker) http.HandlerFunc if err != nil { log.Error(ctx, "Unable to install key %s: %v", key.Name, err) if sdkerr, ok := err.(*sdk.Error); ok { - writeJSON(w, sdkerr, sdkerr.Status) + writeError(w, r, sdkerr) } else { - err := sdk.Error{ - Message: err.Error(), - Status: sdk.ErrUnknownError.Status, - } - writeJSON(w, err, err.Status) + writeError(w, r, sdk.NewError(sdk.ErrUnknownError, err)) } return } diff --git a/engine/worker/internal/handler_upload.go b/engine/worker/internal/handler_upload.go index 8db4e24e9e..28045b9fef 100644 --- a/engine/worker/internal/handler_upload.go +++ b/engine/worker/internal/handler_upload.go @@ -58,7 +58,7 @@ func uploadHandler(ctx context.Context, wk *CurrentWorker) http.HandlerFunc { workingDir, err := workerruntime.WorkingDirectory(wk.currentJob.context) if err != nil { wk.SendLog(ctx, workerruntime.LevelError, fmt.Sprintf("Artifact upload failed: %v", err)) - log.Error(ctx, "Artifact upload failed: No woorking directory: %v", err) + log.Error(ctx, "Artifact upload failed: No working directory: %v", err) writeError(w, r, err) return } @@ -74,7 +74,7 @@ func uploadHandler(ctx context.Context, wk *CurrentWorker) http.HandlerFunc { if result.Status != sdk.StatusSuccess { wk.SendLog(ctx, workerruntime.LevelError, fmt.Sprintf("Artifact upload failed: %s", result.Reason)) log.Error(ctx, "Artifact upload failed: %v", result) - w.WriteHeader(http.StatusInternalServerError) + writeError(w, r, fmt.Errorf("Artifact upload failed: %s", result.Reason)) return } } diff --git a/engine/worker/internal/keys.go b/engine/worker/internal/keys.go index 2ca01628a2..6d8f2a1e09 100644 --- a/engine/worker/internal/keys.go +++ b/engine/worker/internal/keys.go @@ -4,7 +4,6 @@ import ( "bytes" "fmt" "io/ioutil" - "net/http" "os" "os/exec" "path" @@ -27,19 +26,11 @@ func (wk *CurrentWorker) InstallKey(key sdk.Variable) (*workerruntime.KeyRespons installedKeyPath := path.Join(keysDirectory.Name(), key.Name) if err := vcs.CleanAllSSHKeys(wk.basedir, keysDirectory.Name()); err != nil { - errClean := sdk.Error{ - Message: fmt.Sprintf("Cannot clean ssh keys : %v", err), - Status: http.StatusInternalServerError, - } - return nil, sdk.WithStack(errClean) + return nil, sdk.NewError(sdk.ErrUnknownError, fmt.Errorf("Cannot clean ssh keys : %v", err)) } if err := vcs.SetupSSHKey(wk.basedir, keysDirectory.Name(), key); err != nil { - errSetup := sdk.Error{ - Message: fmt.Sprintf("Cannot setup ssh key %s : %v", key.Name, err), - Status: http.StatusInternalServerError, - } - return nil, sdk.WithStack(errSetup) + return nil, sdk.NewError(sdk.ErrUnknownError, fmt.Errorf("Cannot setup ssh key %s : %v", key.Name, err)) } if x, ok := wk.BaseDir().(*afero.BasePathFs); ok { @@ -61,40 +52,24 @@ func (wk *CurrentWorker) InstallKey(key sdk.Variable) (*workerruntime.KeyRespons if !gpg2Found { if _, err := exec.LookPath("gpg"); err != nil { - errBinary := sdk.Error{ - Message: fmt.Sprintf("Cannot use gpg in your worker because you haven't gpg or gpg2 binary"), - Status: http.StatusBadRequest, - } - return nil, sdk.WithStack(errBinary) + return nil, sdk.NewError(sdk.ErrWorkerErrorCommand, fmt.Errorf("Cannot use gpg in your worker because you haven't gpg or gpg2 binary")) } } content := []byte(key.Value) tmpfile, errTmpFile := ioutil.TempFile("", key.Name) if errTmpFile != nil { - errFile := sdk.Error{ - Message: fmt.Sprintf("Cannot setup pgp key %s : %v", key.Name, errTmpFile), - Status: http.StatusInternalServerError, - } - return nil, sdk.WithStack(errFile) + return nil, sdk.NewError(sdk.ErrWorkerErrorCommand, fmt.Errorf("Cannot setup pgp key %s : %v", key.Name, errTmpFile)) } defer func() { _ = os.Remove(tmpfile.Name()) }() if _, err := tmpfile.Write(content); err != nil { - errW := sdk.Error{ - Message: fmt.Sprintf("Cannot setup pgp key file %s : %v", key.Name, err), - Status: http.StatusInternalServerError, - } - return nil, sdk.WithStack(errW) + return nil, sdk.NewError(sdk.ErrWorkerErrorCommand, fmt.Errorf("Cannot setup pgp key file %s : %v", key.Name, err)) } if err := tmpfile.Close(); err != nil { - errC := sdk.Error{ - Message: fmt.Sprintf("Cannot setup pgp key file %s (close) : %v", key.Name, err), - Status: http.StatusInternalServerError, - } - return nil, sdk.WithStack(errC) + return nil, sdk.NewError(sdk.ErrWorkerErrorCommand, fmt.Errorf("Cannot setup pgp key file %s (close) : %v", key.Name, err)) } gpgBin := "gpg" @@ -105,11 +80,7 @@ func (wk *CurrentWorker) InstallKey(key sdk.Variable) (*workerruntime.KeyRespons var out bytes.Buffer cmd.Stdout = &out if err := cmd.Run(); err != nil { - errR := sdk.Error{ - Message: fmt.Sprintf("Cannot import pgp key %s : %v", key.Name, err), - Status: http.StatusInternalServerError, - } - return nil, sdk.WithStack(errR) + return nil, sdk.NewError(sdk.ErrWorkerErrorCommand, fmt.Errorf("Cannot import pgp key %s : %v", key.Name, err)) } return &workerruntime.KeyResponse{ Type: sdk.KeyTypePGP, @@ -118,11 +89,7 @@ func (wk *CurrentWorker) InstallKey(key sdk.Variable) (*workerruntime.KeyRespons }, nil default: - err := sdk.Error{ - Message: fmt.Sprintf("Type key %s is not implemented", key.Type), - Status: http.StatusNotImplemented, - } - return nil, sdk.WithStack(err) + return nil, sdk.NewError(sdk.ErrWorkerErrorCommand, fmt.Errorf("Type key %s is not implemented", key.Type)) } } @@ -145,11 +112,7 @@ func (wk *CurrentWorker) InstallKeyTo(key sdk.Variable, destinationPath string) } if err := vcs.WriteKey(afero.NewOsFs(), destinationPath, key.Value); err != nil { - errSetup := sdk.Error{ - Message: fmt.Sprintf("Cannot setup ssh key %s : %v", key.Name, err), - Status: http.StatusInternalServerError, - } - return nil, sdk.WithStack(errSetup) + return nil, sdk.NewError(sdk.ErrWorkerErrorCommand, fmt.Errorf("Cannot setup ssh key %s : %v", key.Name, err)) } return &workerruntime.KeyResponse{ @@ -167,40 +130,24 @@ func (wk *CurrentWorker) InstallKeyTo(key sdk.Variable, destinationPath string) if !gpg2Found { if _, err := exec.LookPath("gpg"); err != nil { - errBinary := sdk.Error{ - Message: fmt.Sprintf("Cannot use gpg in your worker because you haven't gpg or gpg2 binary"), - Status: http.StatusBadRequest, - } - return nil, sdk.WithStack(errBinary) + return nil, sdk.NewError(sdk.ErrWorkerErrorCommand, fmt.Errorf("Cannot use gpg in your worker because you haven't gpg or gpg2 binary")) } } content := []byte(key.Value) tmpfile, errTmpFile := ioutil.TempFile("", key.Name) if errTmpFile != nil { - errFile := sdk.Error{ - Message: fmt.Sprintf("Cannot setup pgp key %s : %v", key.Name, errTmpFile), - Status: http.StatusInternalServerError, - } - return nil, sdk.WithStack(errFile) + return nil, sdk.NewError(sdk.ErrWorkerErrorCommand, fmt.Errorf("Cannot setup pgp key %s : %v", key.Name, errTmpFile)) } defer func() { _ = os.Remove(tmpfile.Name()) }() if _, err := tmpfile.Write(content); err != nil { - errW := sdk.Error{ - Message: fmt.Sprintf("Cannot setup pgp key file %s : %v", key.Name, err), - Status: http.StatusInternalServerError, - } - return nil, sdk.WithStack(errW) + return nil, sdk.NewError(sdk.ErrWorkerErrorCommand, fmt.Errorf("Cannot setup pgp key file %s : %v", key.Name, err)) } if err := tmpfile.Close(); err != nil { - errC := sdk.Error{ - Message: fmt.Sprintf("Cannot setup pgp key file %s (close) : %v", key.Name, err), - Status: http.StatusInternalServerError, - } - return nil, sdk.WithStack(errC) + return nil, sdk.NewError(sdk.ErrWorkerErrorCommand, fmt.Errorf("Cannot setup pgp key file %s (close) : %v", key.Name, err)) } gpgBin := "gpg" @@ -211,11 +158,7 @@ func (wk *CurrentWorker) InstallKeyTo(key sdk.Variable, destinationPath string) var out bytes.Buffer cmd.Stdout = &out if err := cmd.Run(); err != nil { - errR := sdk.Error{ - Message: fmt.Sprintf("Cannot import pgp key %s : %v", key.Name, err), - Status: http.StatusInternalServerError, - } - return nil, sdk.WithStack(errR) + return nil, sdk.NewError(sdk.ErrWorkerErrorCommand, fmt.Errorf("Cannot import pgp key %s : %v", key.Name, err)) } return &workerruntime.KeyResponse{ Type: sdk.KeyTypePGP, @@ -224,10 +167,6 @@ func (wk *CurrentWorker) InstallKeyTo(key sdk.Variable, destinationPath string) }, nil default: - err := sdk.Error{ - Message: fmt.Sprintf("Type key %s is not implemented", key.Type), - Status: http.StatusNotImplemented, - } - return nil, sdk.WithStack(err) + return nil, sdk.NewError(sdk.ErrWorkerErrorCommand, fmt.Errorf("Type key %s is not implemented", key.Type)) } } diff --git a/sdk/error.go b/sdk/error.go index e756c3f00d..5dd549e00b 100644 --- a/sdk/error.go +++ b/sdk/error.go @@ -196,6 +196,7 @@ var ( ErrWorkflowAsCodeResync = Error{ID: 186, Status: http.StatusForbidden} ErrWorkflowNodeNameDuplicate = Error{ID: 187, Status: http.StatusBadRequest} ErrUnsupportedMediaType = Error{ID: 188, Status: http.StatusUnsupportedMediaType} + ErrWorkerErrorCommand = Error{ID: 189, Status: http.StatusBadRequest} ) var errorsAmericanEnglish = map[int]string{ @@ -374,6 +375,7 @@ var errorsAmericanEnglish = map[int]string{ ErrWorkflowAsCodeResync.ID: "You cannot resynchronize an as-code workflow", ErrWorkflowNodeNameDuplicate.ID: "You cannot have same name for different pipelines in your workflow", ErrUnsupportedMediaType.ID: "Request format invalid", + ErrWorkerErrorCommand.ID: "Worker command in error", } var errorsFrench = map[int]string{ @@ -552,6 +554,7 @@ var errorsFrench = map[int]string{ ErrWorkflowAsCodeResync.ID: "Impossible de resynchroniser un workflow en mode as-code", ErrWorkflowNodeNameDuplicate.ID: "Vous ne pouvez pas avoir plusieurs fois le même nom de pipeline dans votre workflow", ErrUnsupportedMediaType.ID: "Le format de la requête est invalide", + ErrWorkerErrorCommand.ID: "Commande du worker en erreur:", } var errorsLanguages = []map[int]string{