github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/swarmkit/cmd/swarmctl/service/inspect.go (about) 1 package service 2 3 import ( 4 "errors" 5 "fmt" 6 "io" 7 "os" 8 "sort" 9 "strings" 10 "text/tabwriter" 11 12 "github.com/docker/swarmkit/api" 13 "github.com/docker/swarmkit/api/genericresource" 14 "github.com/docker/swarmkit/cmd/swarmctl/common" 15 "github.com/docker/swarmkit/cmd/swarmctl/task" 16 "github.com/dustin/go-humanize" 17 gogotypes "github.com/gogo/protobuf/types" 18 "github.com/spf13/cobra" 19 ) 20 21 func printServiceSummary(service *api.Service, running int) { 22 w := tabwriter.NewWriter(os.Stdout, 8, 8, 8, ' ', 0) 23 defer w.Flush() 24 25 task := service.Spec.Task 26 common.FprintfIfNotEmpty(w, "ID\t: %s\n", service.ID) 27 common.FprintfIfNotEmpty(w, "Name\t: %s\n", service.Spec.Annotations.Name) 28 if len(service.Spec.Annotations.Labels) > 0 { 29 fmt.Fprintln(w, "Labels\t") 30 for k, v := range service.Spec.Annotations.Labels { 31 fmt.Fprintf(w, " %s\t: %s\n", k, v) 32 } 33 } 34 common.FprintfIfNotEmpty(w, "Replicas\t: %s\n", getServiceReplicasTxt(service, running)) 35 36 if service.UpdateStatus != nil { 37 fmt.Fprintln(w, "Update Status\t") 38 fmt.Fprintln(w, " State\t:", service.UpdateStatus.State) 39 started, err := gogotypes.TimestampFromProto(service.UpdateStatus.StartedAt) 40 if err == nil { 41 fmt.Fprintln(w, " Started\t:", humanize.Time(started)) 42 } 43 if service.UpdateStatus.State == api.UpdateStatus_COMPLETED { 44 completed, err := gogotypes.TimestampFromProto(service.UpdateStatus.CompletedAt) 45 if err == nil { 46 fmt.Fprintln(w, " Completed\t:", humanize.Time(completed)) 47 } 48 } 49 fmt.Fprintln(w, " Message\t:", service.UpdateStatus.Message) 50 } 51 52 fmt.Fprintln(w, "Template\t") 53 fmt.Fprintln(w, " Container\t") 54 ctr := service.Spec.Task.GetContainer() 55 common.FprintfIfNotEmpty(w, " Image\t: %s\n", ctr.Image) 56 common.FprintfIfNotEmpty(w, " Command\t: %q\n", strings.Join(ctr.Command, " ")) 57 common.FprintfIfNotEmpty(w, " Args\t: [%s]\n", strings.Join(ctr.Args, ", ")) 58 common.FprintfIfNotEmpty(w, " Env\t: [%s]\n", strings.Join(ctr.Env, ", ")) 59 if task.Placement != nil { 60 common.FprintfIfNotEmpty(w, " Constraints\t: %s\n", strings.Join(task.Placement.Constraints, ", ")) 61 } 62 63 if task.Resources != nil { 64 res := task.Resources 65 fmt.Fprintln(w, " Resources\t") 66 printResources := func(w io.Writer, r *api.Resources) { 67 if r.NanoCPUs != 0 { 68 fmt.Fprintf(w, " CPU\t: %g\n", float64(r.NanoCPUs)/1e9) 69 } 70 if r.MemoryBytes != 0 { 71 fmt.Fprintf(w, " Memory\t: %s\n", humanize.IBytes(uint64(r.MemoryBytes))) 72 } 73 if len(r.Generic) != 0 { 74 fmt.Fprintln(w, " Generic Resources\t") 75 } 76 77 for _, r := range r.Generic { 78 k := genericresource.Kind(r) 79 v := genericresource.Value(r) 80 fmt.Fprintf(w, " %s\t: %s\n", k, v) 81 } 82 83 } 84 if res.Reservations != nil { 85 fmt.Fprintln(w, " Reservations:\t") 86 printResources(w, res.Reservations) 87 } 88 if res.Limits != nil { 89 fmt.Fprintln(w, " Limits:\t") 90 printResources(w, res.Limits) 91 } 92 } 93 if len(service.Spec.Task.Networks) > 0 { 94 fmt.Fprint(w, " Networks:") 95 for _, n := range service.Spec.Task.Networks { 96 fmt.Fprintf(w, " %s", n.Target) 97 } 98 } 99 100 if service.Endpoint != nil && len(service.Endpoint.Ports) > 0 { 101 fmt.Fprintln(w, "\nPorts:") 102 for _, port := range service.Endpoint.Ports { 103 fmt.Fprintf(w, " - Name\t= %s\n", port.Name) 104 fmt.Fprintf(w, " Protocol\t= %s\n", port.Protocol) 105 fmt.Fprintf(w, " Port\t= %d\n", port.TargetPort) 106 fmt.Fprintf(w, " SwarmPort\t= %d\n", port.PublishedPort) 107 } 108 } 109 110 if len(ctr.Mounts) > 0 { 111 fmt.Fprintln(w, " Mounts:") 112 for _, v := range ctr.Mounts { 113 fmt.Fprintf(w, " - target = %s\n", v.Target) 114 fmt.Fprintf(w, " source = %s\n", v.Source) 115 fmt.Fprintf(w, " readonly = %v\n", v.ReadOnly) 116 fmt.Fprintf(w, " type = %v\n", strings.ToLower(v.Type.String())) 117 } 118 } 119 120 if len(ctr.Secrets) > 0 { 121 fmt.Fprintln(w, " Secrets:") 122 for _, sr := range ctr.Secrets { 123 var targetName, mode string 124 if sr.GetFile() != nil { 125 targetName = sr.GetFile().Name 126 mode = "FILE" 127 } 128 fmt.Fprintf(w, " [%s] %s@%s:%s\n", mode, sr.SecretName, sr.SecretID, targetName) 129 } 130 } 131 132 if len(ctr.Configs) > 0 { 133 fmt.Fprintln(w, " Configs:") 134 for _, cr := range ctr.Configs { 135 var targetName, mode string 136 if cr.GetFile() != nil { 137 targetName = cr.GetFile().Name 138 mode = "FILE" 139 } 140 fmt.Fprintf(w, " [%s] %s@%s:%s\n", mode, cr.ConfigName, cr.ConfigID, targetName) 141 } 142 } 143 144 if task.LogDriver != nil { 145 fmt.Fprintf(w, " LogDriver\t: %s\n", task.LogDriver.Name) 146 var keys []string 147 148 if task.LogDriver.Options != nil { 149 for k := range task.LogDriver.Options { 150 keys = append(keys, k) 151 } 152 sort.Strings(keys) 153 154 for _, k := range keys { 155 v := task.LogDriver.Options[k] 156 if v != "" { 157 fmt.Fprintf(w, " %s\t: %s\n", k, v) 158 } else { 159 fmt.Fprintf(w, " %s\t\n", k) 160 161 } 162 } 163 } 164 } 165 } 166 167 var ( 168 inspectCmd = &cobra.Command{ 169 Use: "inspect <service ID>", 170 Short: "Inspect a service", 171 RunE: func(cmd *cobra.Command, args []string) error { 172 if len(args) == 0 { 173 return errors.New("service ID missing") 174 } 175 176 if len(args) > 1 { 177 return errors.New("inspect command takes exactly 1 argument") 178 } 179 180 flags := cmd.Flags() 181 182 all, err := flags.GetBool("all") 183 if err != nil { 184 return err 185 } 186 187 c, err := common.Dial(cmd) 188 if err != nil { 189 return err 190 } 191 192 res := common.NewResolver(cmd, c) 193 194 service, err := getService(common.Context(cmd), c, args[0]) 195 if err != nil { 196 return err 197 } 198 199 r, err := c.ListTasks(common.Context(cmd), 200 &api.ListTasksRequest{ 201 Filters: &api.ListTasksRequest_Filters{ 202 ServiceIDs: []string{service.ID}, 203 }, 204 }) 205 if err != nil { 206 return err 207 } 208 var running int 209 for _, t := range r.Tasks { 210 if t.Status.State == api.TaskStateRunning { 211 running++ 212 } 213 } 214 215 printServiceSummary(service, running) 216 if len(r.Tasks) > 0 { 217 fmt.Println() 218 task.Print(r.Tasks, all, res) 219 } 220 221 return nil 222 }, 223 } 224 ) 225 226 func init() { 227 inspectCmd.Flags().BoolP("all", "a", false, "Show all tasks (default shows just running)") 228 }