github.com/portworx/docker@v1.12.1/api/client/task/print.go (about) 1 package task 2 3 import ( 4 "fmt" 5 "sort" 6 "strings" 7 "text/tabwriter" 8 "time" 9 10 "golang.org/x/net/context" 11 12 "github.com/docker/docker/api/client" 13 "github.com/docker/docker/api/client/idresolver" 14 "github.com/docker/engine-api/types/swarm" 15 "github.com/docker/go-units" 16 ) 17 18 const ( 19 psTaskItemFmt = "%s\t%s\t%s\t%s\t%s\t%s %s ago\t%s\n" 20 maxErrLength = 30 21 ) 22 23 type tasksBySlot []swarm.Task 24 25 func (t tasksBySlot) Len() int { 26 return len(t) 27 } 28 29 func (t tasksBySlot) Swap(i, j int) { 30 t[i], t[j] = t[j], t[i] 31 } 32 33 func (t tasksBySlot) Less(i, j int) bool { 34 // Sort by slot. 35 if t[i].Slot != t[j].Slot { 36 return t[i].Slot < t[j].Slot 37 } 38 39 // If same slot, sort by most recent. 40 return t[j].Meta.CreatedAt.Before(t[i].CreatedAt) 41 } 42 43 // Print task information in a table format 44 func Print(dockerCli *client.DockerCli, ctx context.Context, tasks []swarm.Task, resolver *idresolver.IDResolver) error { 45 sort.Stable(tasksBySlot(tasks)) 46 47 writer := tabwriter.NewWriter(dockerCli.Out(), 0, 4, 2, ' ', 0) 48 49 // Ignore flushing errors 50 defer writer.Flush() 51 fmt.Fprintln(writer, strings.Join([]string{"ID", "NAME", "IMAGE", "NODE", "DESIRED STATE", "CURRENT STATE", "ERROR"}, "\t")) 52 53 prevName := "" 54 for _, task := range tasks { 55 serviceValue, err := resolver.Resolve(ctx, swarm.Service{}, task.ServiceID) 56 if err != nil { 57 return err 58 } 59 nodeValue, err := resolver.Resolve(ctx, swarm.Node{}, task.NodeID) 60 if err != nil { 61 return err 62 } 63 64 name := serviceValue 65 if task.Slot > 0 { 66 name = fmt.Sprintf("%s.%d", name, task.Slot) 67 } 68 69 // Indent the name if necessary 70 indentedName := name 71 if prevName == name { 72 indentedName = fmt.Sprintf(" \\_ %s", indentedName) 73 } 74 prevName = name 75 76 // Trim and quote the error message. 77 taskErr := task.Status.Err 78 if len(taskErr) > maxErrLength { 79 taskErr = fmt.Sprintf("%s…", taskErr[:maxErrLength-1]) 80 } 81 if len(taskErr) > 0 { 82 taskErr = fmt.Sprintf("\"%s\"", taskErr) 83 } 84 85 fmt.Fprintf( 86 writer, 87 psTaskItemFmt, 88 task.ID, 89 indentedName, 90 task.Spec.ContainerSpec.Image, 91 nodeValue, 92 client.PrettyPrint(task.DesiredState), 93 client.PrettyPrint(task.Status.State), 94 strings.ToLower(units.HumanDuration(time.Since(task.Status.Timestamp))), 95 taskErr, 96 ) 97 } 98 99 return nil 100 }