github.com/sld880311/docker@v0.0.0-20200524143708-d5593973a475/cli/command/system/inspect.go (about) 1 package system 2 3 import ( 4 "fmt" 5 "strings" 6 7 "golang.org/x/net/context" 8 9 "github.com/docker/docker/cli" 10 "github.com/docker/docker/cli/command" 11 "github.com/docker/docker/cli/command/inspect" 12 apiclient "github.com/docker/docker/client" 13 "github.com/spf13/cobra" 14 ) 15 16 type inspectOptions struct { 17 format string 18 inspectType string 19 size bool 20 ids []string 21 } 22 23 // NewInspectCommand creates a new cobra.Command for `docker inspect` 24 func NewInspectCommand(dockerCli *command.DockerCli) *cobra.Command { 25 var opts inspectOptions 26 27 cmd := &cobra.Command{ 28 Use: "inspect [OPTIONS] NAME|ID [NAME|ID...]", 29 Short: "Return low-level information on Docker objects", 30 Args: cli.RequiresMinArgs(1), 31 RunE: func(cmd *cobra.Command, args []string) error { 32 opts.ids = args 33 return runInspect(dockerCli, opts) 34 }, 35 } 36 37 flags := cmd.Flags() 38 flags.StringVarP(&opts.format, "format", "f", "", "Format the output using the given Go template") 39 flags.StringVar(&opts.inspectType, "type", "", "Return JSON for specified type") 40 flags.BoolVarP(&opts.size, "size", "s", false, "Display total file sizes if the type is container") 41 42 return cmd 43 } 44 45 func runInspect(dockerCli *command.DockerCli, opts inspectOptions) error { 46 var elementSearcher inspect.GetRefFunc 47 switch opts.inspectType { 48 case "", "container", "image", "node", "network", "service", "volume", "task", "plugin": 49 elementSearcher = inspectAll(context.Background(), dockerCli, opts.size, opts.inspectType) 50 default: 51 return fmt.Errorf("%q is not a valid value for --type", opts.inspectType) 52 } 53 return inspect.Inspect(dockerCli.Out(), opts.ids, opts.format, elementSearcher) 54 } 55 56 func inspectContainers(ctx context.Context, dockerCli *command.DockerCli, getSize bool) inspect.GetRefFunc { 57 return func(ref string) (interface{}, []byte, error) { 58 return dockerCli.Client().ContainerInspectWithRaw(ctx, ref, getSize) 59 } 60 } 61 62 func inspectImages(ctx context.Context, dockerCli *command.DockerCli) inspect.GetRefFunc { 63 return func(ref string) (interface{}, []byte, error) { 64 return dockerCli.Client().ImageInspectWithRaw(ctx, ref) 65 } 66 } 67 68 func inspectNetwork(ctx context.Context, dockerCli *command.DockerCli) inspect.GetRefFunc { 69 return func(ref string) (interface{}, []byte, error) { 70 return dockerCli.Client().NetworkInspectWithRaw(ctx, ref) 71 } 72 } 73 74 func inspectNode(ctx context.Context, dockerCli *command.DockerCli) inspect.GetRefFunc { 75 return func(ref string) (interface{}, []byte, error) { 76 return dockerCli.Client().NodeInspectWithRaw(ctx, ref) 77 } 78 } 79 80 func inspectService(ctx context.Context, dockerCli *command.DockerCli) inspect.GetRefFunc { 81 return func(ref string) (interface{}, []byte, error) { 82 return dockerCli.Client().ServiceInspectWithRaw(ctx, ref) 83 } 84 } 85 86 func inspectTasks(ctx context.Context, dockerCli *command.DockerCli) inspect.GetRefFunc { 87 return func(ref string) (interface{}, []byte, error) { 88 return dockerCli.Client().TaskInspectWithRaw(ctx, ref) 89 } 90 } 91 92 func inspectVolume(ctx context.Context, dockerCli *command.DockerCli) inspect.GetRefFunc { 93 return func(ref string) (interface{}, []byte, error) { 94 return dockerCli.Client().VolumeInspectWithRaw(ctx, ref) 95 } 96 } 97 98 func inspectPlugin(ctx context.Context, dockerCli *command.DockerCli) inspect.GetRefFunc { 99 return func(ref string) (interface{}, []byte, error) { 100 return dockerCli.Client().PluginInspectWithRaw(ctx, ref) 101 } 102 } 103 104 func inspectAll(ctx context.Context, dockerCli *command.DockerCli, getSize bool, typeConstraint string) inspect.GetRefFunc { 105 var inspectAutodetect = []struct { 106 objectType string 107 isSizeSupported bool 108 isSwarmObject bool 109 objectInspector func(string) (interface{}, []byte, error) 110 }{ 111 { 112 objectType: "container", 113 isSizeSupported: true, 114 objectInspector: inspectContainers(ctx, dockerCli, getSize), 115 }, 116 { 117 objectType: "image", 118 objectInspector: inspectImages(ctx, dockerCli), 119 }, 120 { 121 objectType: "network", 122 objectInspector: inspectNetwork(ctx, dockerCli), 123 }, 124 { 125 objectType: "volume", 126 objectInspector: inspectVolume(ctx, dockerCli), 127 }, 128 { 129 objectType: "service", 130 isSwarmObject: true, 131 objectInspector: inspectService(ctx, dockerCli), 132 }, 133 { 134 objectType: "task", 135 isSwarmObject: true, 136 objectInspector: inspectTasks(ctx, dockerCli), 137 }, 138 { 139 objectType: "node", 140 isSwarmObject: true, 141 objectInspector: inspectNode(ctx, dockerCli), 142 }, 143 { 144 objectType: "plugin", 145 objectInspector: inspectPlugin(ctx, dockerCli), 146 }, 147 } 148 149 // isSwarmManager does an Info API call to verify that the daemon is 150 // a swarm manager. 151 isSwarmManager := func() bool { 152 info, err := dockerCli.Client().Info(ctx) 153 if err != nil { 154 fmt.Fprintln(dockerCli.Err(), err) 155 return false 156 } 157 return info.Swarm.ControlAvailable 158 } 159 160 isErrNotSupported := func(err error) bool { 161 return strings.Contains(err.Error(), "not supported") 162 } 163 164 return func(ref string) (interface{}, []byte, error) { 165 const ( 166 swarmSupportUnknown = iota 167 swarmSupported 168 swarmUnsupported 169 ) 170 171 isSwarmSupported := swarmSupportUnknown 172 173 for _, inspectData := range inspectAutodetect { 174 if typeConstraint != "" && inspectData.objectType != typeConstraint { 175 continue 176 } 177 if typeConstraint == "" && inspectData.isSwarmObject { 178 if isSwarmSupported == swarmSupportUnknown { 179 if isSwarmManager() { 180 isSwarmSupported = swarmSupported 181 } else { 182 isSwarmSupported = swarmUnsupported 183 } 184 } 185 if isSwarmSupported == swarmUnsupported { 186 continue 187 } 188 } 189 v, raw, err := inspectData.objectInspector(ref) 190 if err != nil { 191 if typeConstraint == "" && (apiclient.IsErrNotFound(err) || isErrNotSupported(err)) { 192 continue 193 } 194 return v, raw, err 195 } 196 if getSize && !inspectData.isSizeSupported { 197 fmt.Fprintf(dockerCli.Err(), "WARNING: --size ignored for %s\n", inspectData.objectType) 198 } 199 return v, raw, err 200 } 201 return nil, nil, fmt.Errorf("Error: No such object: %s", ref) 202 } 203 }