github.1git.de/docker/cli@v26.1.3+incompatible/cli/command/task/formatter.go (about) 1 package task 2 3 import ( 4 "fmt" 5 "strings" 6 "time" 7 8 "github.com/distribution/reference" 9 "github.com/docker/cli/cli/command" 10 "github.com/docker/cli/cli/command/formatter" 11 "github.com/docker/docker/api/types/swarm" 12 "github.com/docker/docker/pkg/stringid" 13 "github.com/docker/go-units" 14 ) 15 16 const ( 17 defaultTaskTableFormat = "table {{.ID}}\t{{.Name}}\t{{.Image}}\t{{.Node}}\t{{.DesiredState}}\t{{.CurrentState}}\t{{.Error}}\t{{.Ports}}" 18 19 nodeHeader = "NODE" 20 taskIDHeader = "ID" 21 desiredStateHeader = "DESIRED STATE" 22 currentStateHeader = "CURRENT STATE" 23 24 maxErrLength = 30 25 ) 26 27 // NewTaskFormat returns a Format for rendering using a task Context 28 func NewTaskFormat(source string, quiet bool) formatter.Format { 29 switch source { 30 case formatter.TableFormatKey: 31 if quiet { 32 return formatter.DefaultQuietFormat 33 } 34 return defaultTaskTableFormat 35 case formatter.RawFormatKey: 36 if quiet { 37 return `id: {{.ID}}` 38 } 39 return `id: {{.ID}}\nname: {{.Name}}\nimage: {{.Image}}\nnode: {{.Node}}\ndesired_state: {{.DesiredState}}\ncurrent_state: {{.CurrentState}}\nerror: {{.Error}}\nports: {{.Ports}}\n` 40 } 41 return formatter.Format(source) 42 } 43 44 // FormatWrite writes the context 45 func FormatWrite(ctx formatter.Context, tasks []swarm.Task, names map[string]string, nodes map[string]string) error { 46 render := func(format func(subContext formatter.SubContext) error) error { 47 for _, task := range tasks { 48 taskCtx := &taskContext{trunc: ctx.Trunc, task: task, name: names[task.ID], node: nodes[task.ID]} 49 if err := format(taskCtx); err != nil { 50 return err 51 } 52 } 53 return nil 54 } 55 taskCtx := taskContext{} 56 taskCtx.Header = formatter.SubHeaderContext{ 57 "ID": taskIDHeader, 58 "Name": formatter.NameHeader, 59 "Image": formatter.ImageHeader, 60 "Node": nodeHeader, 61 "DesiredState": desiredStateHeader, 62 "CurrentState": currentStateHeader, 63 "Error": formatter.ErrorHeader, 64 "Ports": formatter.PortsHeader, 65 } 66 return ctx.Write(&taskCtx, render) 67 } 68 69 type taskContext struct { 70 formatter.HeaderContext 71 trunc bool 72 task swarm.Task 73 name string 74 node string 75 } 76 77 func (c *taskContext) MarshalJSON() ([]byte, error) { 78 return formatter.MarshalJSON(c) 79 } 80 81 func (c *taskContext) ID() string { 82 if c.trunc { 83 return stringid.TruncateID(c.task.ID) 84 } 85 return c.task.ID 86 } 87 88 func (c *taskContext) Name() string { 89 return c.name 90 } 91 92 func (c *taskContext) Image() string { 93 image := c.task.Spec.ContainerSpec.Image 94 if c.trunc { 95 ref, err := reference.ParseNormalizedNamed(image) 96 if err == nil { 97 // update image string for display, (strips any digest) 98 if nt, ok := ref.(reference.NamedTagged); ok { 99 if namedTagged, err := reference.WithTag(reference.TrimNamed(nt), nt.Tag()); err == nil { 100 image = reference.FamiliarString(namedTagged) 101 } 102 } 103 } 104 } 105 return image 106 } 107 108 func (c *taskContext) Node() string { 109 return c.node 110 } 111 112 func (c *taskContext) DesiredState() string { 113 return command.PrettyPrint(c.task.DesiredState) 114 } 115 116 func (c *taskContext) CurrentState() string { 117 return fmt.Sprintf("%s %s ago", 118 command.PrettyPrint(c.task.Status.State), 119 strings.ToLower(units.HumanDuration(time.Since(c.task.Status.Timestamp))), 120 ) 121 } 122 123 func (c *taskContext) Error() string { 124 // Trim and quote the error message. 125 taskErr := c.task.Status.Err 126 if c.trunc { 127 taskErr = formatter.Ellipsis(taskErr, maxErrLength) 128 } 129 if len(taskErr) > 0 { 130 taskErr = fmt.Sprintf(`"%s"`, taskErr) 131 } 132 return taskErr 133 } 134 135 func (c *taskContext) Ports() string { 136 if len(c.task.Status.PortStatus.Ports) == 0 { 137 return "" 138 } 139 ports := []string{} 140 for _, pConfig := range c.task.Status.PortStatus.Ports { 141 ports = append(ports, fmt.Sprintf("*:%d->%d/%s", 142 pConfig.PublishedPort, 143 pConfig.TargetPort, 144 pConfig.Protocol, 145 )) 146 } 147 return strings.Join(ports, ",") 148 }