Parcourir la source

service tasks: Improve error reporting

- Tasks will display all tasks (`-a` is the default and was removed)
- Nest tasks to help display history
- Display task errors inline

Signed-off-by: Andrea Luzzardi <aluzzardi@gmail.com>
Andrea Luzzardi il y a 9 ans
Parent
commit
edd67fd4ad
3 fichiers modifiés avec 27 ajouts et 22 suppressions
  1. 0 8
      api/client/node/tasks.go
  2. 0 8
      api/client/service/tasks.go
  3. 27 6
      api/client/task/print.go

+ 0 - 8
api/client/node/tasks.go

@@ -9,13 +9,11 @@ import (
 	"github.com/docker/docker/cli"
 	"github.com/docker/docker/cli"
 	"github.com/docker/docker/opts"
 	"github.com/docker/docker/opts"
 	"github.com/docker/engine-api/types"
 	"github.com/docker/engine-api/types"
-	"github.com/docker/engine-api/types/swarm"
 	"github.com/spf13/cobra"
 	"github.com/spf13/cobra"
 )
 )
 
 
 type tasksOptions struct {
 type tasksOptions struct {
 	nodeID    string
 	nodeID    string
-	all       bool
 	noResolve bool
 	noResolve bool
 	filter    opts.FilterOpt
 	filter    opts.FilterOpt
 }
 }
@@ -33,7 +31,6 @@ func newTasksCommand(dockerCli *client.DockerCli) *cobra.Command {
 		},
 		},
 	}
 	}
 	flags := cmd.Flags()
 	flags := cmd.Flags()
-	flags.BoolVarP(&opts.all, "all", "a", false, "Display all instances")
 	flags.BoolVar(&opts.noResolve, "no-resolve", false, "Do not map IDs to Names")
 	flags.BoolVar(&opts.noResolve, "no-resolve", false, "Do not map IDs to Names")
 	flags.VarP(&opts.filter, "filter", "f", "Filter output based on conditions provided")
 	flags.VarP(&opts.filter, "filter", "f", "Filter output based on conditions provided")
 
 
@@ -55,11 +52,6 @@ func runTasks(dockerCli *client.DockerCli, opts tasksOptions) error {
 
 
 	filter := opts.filter.Value()
 	filter := opts.filter.Value()
 	filter.Add("node", node.ID)
 	filter.Add("node", node.ID)
-	if !opts.all && !filter.Include("desired-state") {
-		filter.Add("desired-state", string(swarm.TaskStateRunning))
-		filter.Add("desired-state", string(swarm.TaskStateAccepted))
-	}
-
 	tasks, err := client.TaskList(
 	tasks, err := client.TaskList(
 		ctx,
 		ctx,
 		types.TaskListOptions{Filter: filter})
 		types.TaskListOptions{Filter: filter})

+ 0 - 8
api/client/service/tasks.go

@@ -10,13 +10,11 @@ import (
 	"github.com/docker/docker/cli"
 	"github.com/docker/docker/cli"
 	"github.com/docker/docker/opts"
 	"github.com/docker/docker/opts"
 	"github.com/docker/engine-api/types"
 	"github.com/docker/engine-api/types"
-	"github.com/docker/engine-api/types/swarm"
 	"github.com/spf13/cobra"
 	"github.com/spf13/cobra"
 )
 )
 
 
 type tasksOptions struct {
 type tasksOptions struct {
 	serviceID string
 	serviceID string
-	all       bool
 	noResolve bool
 	noResolve bool
 	filter    opts.FilterOpt
 	filter    opts.FilterOpt
 }
 }
@@ -34,7 +32,6 @@ func newTasksCommand(dockerCli *client.DockerCli) *cobra.Command {
 		},
 		},
 	}
 	}
 	flags := cmd.Flags()
 	flags := cmd.Flags()
-	flags.BoolVarP(&opts.all, "all", "a", false, "Display all tasks")
 	flags.BoolVar(&opts.noResolve, "no-resolve", false, "Do not map IDs to Names")
 	flags.BoolVar(&opts.noResolve, "no-resolve", false, "Do not map IDs to Names")
 	flags.VarP(&opts.filter, "filter", "f", "Filter output based on conditions provided")
 	flags.VarP(&opts.filter, "filter", "f", "Filter output based on conditions provided")
 
 
@@ -52,11 +49,6 @@ func runTasks(dockerCli *client.DockerCli, opts tasksOptions) error {
 
 
 	filter := opts.filter.Value()
 	filter := opts.filter.Value()
 	filter.Add("service", service.ID)
 	filter.Add("service", service.ID)
-	if !opts.all && !filter.Include("desired-state") {
-		filter.Add("desired-state", string(swarm.TaskStateRunning))
-		filter.Add("desired-state", string(swarm.TaskStateAccepted))
-	}
-
 	if filter.Include("node") {
 	if filter.Include("node") {
 		nodeFilters := filter.Get("node")
 		nodeFilters := filter.Get("node")
 		for _, nodeFilter := range nodeFilters {
 		for _, nodeFilter := range nodeFilters {

+ 27 - 6
api/client/task/print.go

@@ -16,7 +16,8 @@ import (
 )
 )
 
 
 const (
 const (
-	psTaskItemFmt = "%s\t%s\t%s\t%s\t%s %s ago\t%s\t%s\n"
+	psTaskItemFmt = "%s\t%s\t%s\t%s\t%s\t%s %s ago\t%s\n"
+	maxErrLength  = 30
 )
 )
 
 
 type tasksBySlot []swarm.Task
 type tasksBySlot []swarm.Task
@@ -47,7 +48,9 @@ func Print(dockerCli *client.DockerCli, ctx context.Context, tasks []swarm.Task,
 
 
 	// Ignore flushing errors
 	// Ignore flushing errors
 	defer writer.Flush()
 	defer writer.Flush()
-	fmt.Fprintln(writer, strings.Join([]string{"ID", "NAME", "SERVICE", "IMAGE", "LAST STATE", "DESIRED STATE", "NODE"}, "\t"))
+	fmt.Fprintln(writer, strings.Join([]string{"ID", "NAME", "IMAGE", "NODE", "DESIRED STATE", "CURRENT STATE", "ERROR"}, "\t"))
+
+	prevName := ""
 	for _, task := range tasks {
 	for _, task := range tasks {
 		serviceValue, err := resolver.Resolve(ctx, swarm.Service{}, task.ServiceID)
 		serviceValue, err := resolver.Resolve(ctx, swarm.Service{}, task.ServiceID)
 		if err != nil {
 		if err != nil {
@@ -57,21 +60,39 @@ func Print(dockerCli *client.DockerCli, ctx context.Context, tasks []swarm.Task,
 		if err != nil {
 		if err != nil {
 			return err
 			return err
 		}
 		}
+
 		name := serviceValue
 		name := serviceValue
 		if task.Slot > 0 {
 		if task.Slot > 0 {
 			name = fmt.Sprintf("%s.%d", name, task.Slot)
 			name = fmt.Sprintf("%s.%d", name, task.Slot)
 		}
 		}
+
+		// Indent the name if necessary
+		indentedName := name
+		if prevName == name {
+			indentedName = fmt.Sprintf(" \\_ %s", indentedName)
+		}
+		prevName = name
+
+		// Trim and quote the error message.
+		taskErr := task.Status.Err
+		if len(taskErr) > maxErrLength {
+			taskErr = fmt.Sprintf("%s…", taskErr[:maxErrLength-1])
+		}
+		if len(taskErr) > 0 {
+			taskErr = fmt.Sprintf("\"%s\"", taskErr)
+		}
+
 		fmt.Fprintf(
 		fmt.Fprintf(
 			writer,
 			writer,
 			psTaskItemFmt,
 			psTaskItemFmt,
 			task.ID,
 			task.ID,
-			name,
-			serviceValue,
+			indentedName,
 			task.Spec.ContainerSpec.Image,
 			task.Spec.ContainerSpec.Image,
+			nodeValue,
+			client.PrettyPrint(task.DesiredState),
 			client.PrettyPrint(task.Status.State),
 			client.PrettyPrint(task.Status.State),
 			strings.ToLower(units.HumanDuration(time.Since(task.Status.Timestamp))),
 			strings.ToLower(units.HumanDuration(time.Since(task.Status.Timestamp))),
-			client.PrettyPrint(task.DesiredState),
-			nodeValue,
+			taskErr,
 		)
 		)
 	}
 	}