github.com/kobeld/docker@v1.12.0-rc1/api/client/service/inspect.go (about) 1 package service 2 3 import ( 4 "fmt" 5 "io" 6 "strings" 7 8 "golang.org/x/net/context" 9 10 "github.com/docker/docker/api/client" 11 "github.com/docker/docker/api/client/inspect" 12 "github.com/docker/docker/cli" 13 "github.com/docker/docker/pkg/ioutils" 14 apiclient "github.com/docker/engine-api/client" 15 "github.com/docker/engine-api/types/swarm" 16 "github.com/spf13/cobra" 17 ) 18 19 type inspectOptions struct { 20 refs []string 21 format string 22 pretty bool 23 } 24 25 func newInspectCommand(dockerCli *client.DockerCli) *cobra.Command { 26 var opts inspectOptions 27 28 cmd := &cobra.Command{ 29 Use: "inspect [OPTIONS] SERVICE [SERVICE...]", 30 Short: "Inspect a service", 31 Args: cli.RequiresMinArgs(1), 32 RunE: func(cmd *cobra.Command, args []string) error { 33 opts.refs = args 34 35 if opts.pretty && len(opts.format) > 0 { 36 return fmt.Errorf("--format is incompatible with human friendly format") 37 } 38 return runInspect(dockerCli, opts) 39 }, 40 } 41 42 flags := cmd.Flags() 43 flags.StringVarP(&opts.format, "format", "f", "", "Format the output using the given go template") 44 flags.BoolVarP(&opts.pretty, "pretty", "p", false, "Print the information in a human friendly format.") 45 return cmd 46 } 47 48 func runInspect(dockerCli *client.DockerCli, opts inspectOptions) error { 49 client := dockerCli.Client() 50 ctx := context.Background() 51 52 getRef := func(ref string) (interface{}, []byte, error) { 53 service, err := client.ServiceInspect(ctx, ref) 54 if err == nil || !apiclient.IsErrServiceNotFound(err) { 55 return service, nil, err 56 } 57 return nil, nil, fmt.Errorf("Error: no such service: %s", ref) 58 } 59 60 if !opts.pretty { 61 return inspect.Inspect(dockerCli.Out(), opts.refs, opts.format, getRef) 62 } 63 64 return printHumanFriendly(dockerCli.Out(), opts.refs, getRef) 65 } 66 67 func printHumanFriendly(out io.Writer, refs []string, getRef inspect.GetRefFunc) error { 68 for idx, ref := range refs { 69 obj, _, err := getRef(ref) 70 if err != nil { 71 return err 72 } 73 printService(out, obj.(swarm.Service)) 74 75 // TODO: better way to do this? 76 // print extra space between objects, but not after the last one 77 if idx+1 != len(refs) { 78 fmt.Fprintf(out, "\n\n") 79 } 80 } 81 return nil 82 } 83 84 // TODO: use a template 85 func printService(out io.Writer, service swarm.Service) { 86 fmt.Fprintf(out, "ID:\t\t%s\n", service.ID) 87 fmt.Fprintf(out, "Name:\t\t%s\n", service.Spec.Name) 88 if service.Spec.Labels != nil { 89 fmt.Fprintln(out, "Labels:") 90 for k, v := range service.Spec.Labels { 91 fmt.Fprintf(out, " - %s=%s\n", k, v) 92 } 93 } 94 95 if service.Spec.Mode.Global != nil { 96 fmt.Fprintln(out, "Mode:\t\tGLOBAL") 97 } else { 98 fmt.Fprintln(out, "Mode:\t\tREPLICATED") 99 if service.Spec.Mode.Replicated.Replicas != nil { 100 fmt.Fprintf(out, " Replicas:\t\t%d\n", *service.Spec.Mode.Replicated.Replicas) 101 } 102 } 103 fmt.Fprintln(out, "Placement:") 104 fmt.Fprintln(out, " Strategy:\tSPREAD") 105 fmt.Fprintf(out, "UpateConfig:\n") 106 fmt.Fprintf(out, " Parallelism:\t%d\n", service.Spec.UpdateConfig.Parallelism) 107 if service.Spec.UpdateConfig.Delay.Nanoseconds() > 0 { 108 fmt.Fprintf(out, " Delay:\t\t%s\n", service.Spec.UpdateConfig.Delay) 109 } 110 fmt.Fprintf(out, "ContainerSpec:\n") 111 printContainerSpec(out, service.Spec.TaskTemplate.ContainerSpec) 112 } 113 114 func printContainerSpec(out io.Writer, containerSpec swarm.ContainerSpec) { 115 fmt.Fprintf(out, " Image:\t\t%s\n", containerSpec.Image) 116 if len(containerSpec.Command) > 0 { 117 fmt.Fprintf(out, " Command:\t%s\n", strings.Join(containerSpec.Command, " ")) 118 } 119 if len(containerSpec.Args) > 0 { 120 fmt.Fprintf(out, " Args:\t%s\n", strings.Join(containerSpec.Args, " ")) 121 } 122 if len(containerSpec.Env) > 0 { 123 fmt.Fprintf(out, " Env:\t\t%s\n", strings.Join(containerSpec.Env, " ")) 124 } 125 ioutils.FprintfIfNotEmpty(out, " Dir\t\t%s\n", containerSpec.Dir) 126 ioutils.FprintfIfNotEmpty(out, " User\t\t%s\n", containerSpec.User) 127 }