Skip to content

Commit

Permalink
cmd/docker: split handling exit-code to a separate utility
Browse files Browse the repository at this point in the history
This allows dockerMain() to return an error "as usual", and puts the
responsibility for turning that into an appropriate exit-code in
main() (which also sets the exit-code when terminating).

We could consider putting this utility in the cli package and exporting
it if would be useful for doing a similar handling in plugins.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
  • Loading branch information
thaJeztah committed Jul 4, 2024
1 parent 5aae44b commit 4c62b2a
Showing 1 changed file with 23 additions and 25 deletions.
48 changes: 23 additions & 25 deletions cmd/docker/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,43 +29,41 @@ import (
)

func main() {
statusCode := dockerMain()
if statusCode != 0 {
os.Exit(statusCode)
err := dockerMain(context.Background())
if err != nil && !errdefs.IsCancelled(err) {
_, _ = fmt.Fprintln(os.Stderr, err)
os.Exit(getExitCode(err))
}
}

func dockerMain() int {
ctx, cancelNotify := signal.NotifyContext(context.Background(), platformsignals.TerminationSignals...)
func dockerMain(ctx context.Context) error {
ctx, cancelNotify := signal.NotifyContext(ctx, platformsignals.TerminationSignals...)
defer cancelNotify()

dockerCli, err := command.NewDockerCli(command.WithBaseContext(ctx))
if err != nil {
fmt.Fprintln(os.Stderr, err)
return 1
return err
}
logrus.SetOutput(dockerCli.Err())
otel.SetErrorHandler(debug.OTELErrorHandler)

if err := runDocker(ctx, dockerCli); err != nil {
if sterr, ok := err.(cli.StatusError); ok {
if sterr.Status != "" {
fmt.Fprintln(dockerCli.Err(), sterr.Status)
}
// StatusError should only be used for errors, and all errors should
// have a non-zero exit status, so never exit with 0
if sterr.StatusCode == 0 {
return 1
}
return sterr.StatusCode
}
if errdefs.IsCancelled(err) {
return 0
}
fmt.Fprintln(dockerCli.Err(), err)
return 1
return runDocker(ctx, dockerCli)
}

// getExitCode returns the exit-code to use for the given error.
// If err is a [cli.StatusError] and has a StatusCode set, it uses the
// status-code from it, otherwise it returns "1" for any error.
func getExitCode(err error) int {
if err == nil {
return 0
}
return 0
var stErr cli.StatusError
if errors.As(err, &stErr) && stErr.StatusCode != 0 {
return stErr.StatusCode
}

// No status-code provided; all errors should have a non-zero exit code.
return 1
}

func newDockerCommand(dockerCli *command.DockerCli) *cli.TopLevelCommand {
Expand Down

0 comments on commit 4c62b2a

Please sign in to comment.