Browse code

Migrate info command to cobra

Signed-off-by: Tomasz Kopczynski <tomek@kopczynski.net.pl>

Tomasz Kopczynski authored on 2016/06/09 06:42:25
Showing 5 changed files
... ...
@@ -4,7 +4,6 @@ package client
4 4
 func (cli *DockerCli) Command(name string) func(...string) error {
5 5
 	return map[string]func(...string) error{
6 6
 		"exec":    cli.CmdExec,
7
-		"info":    cli.CmdInfo,
8 7
 		"inspect": cli.CmdInspect,
9 8
 		"update":  cli.CmdUpdate,
10 9
 	}[name]
11 10
deleted file mode 100644
... ...
@@ -1,199 +0,0 @@
1
-package client
2
-
3
-import (
4
-	"fmt"
5
-	"strings"
6
-
7
-	"golang.org/x/net/context"
8
-
9
-	Cli "github.com/docker/docker/cli"
10
-	"github.com/docker/docker/pkg/ioutils"
11
-	flag "github.com/docker/docker/pkg/mflag"
12
-	"github.com/docker/docker/utils"
13
-	"github.com/docker/engine-api/types/swarm"
14
-	"github.com/docker/go-units"
15
-)
16
-
17
-// CmdInfo displays system-wide information.
18
-//
19
-// Usage: docker info
20
-func (cli *DockerCli) CmdInfo(args ...string) error {
21
-	cmd := Cli.Subcmd("info", nil, Cli.DockerCommands["info"].Description, true)
22
-	cmd.Require(flag.Exact, 0)
23
-
24
-	cmd.ParseFlags(args, true)
25
-
26
-	info, err := cli.client.Info(context.Background())
27
-	if err != nil {
28
-		return err
29
-	}
30
-
31
-	fmt.Fprintf(cli.out, "Containers: %d\n", info.Containers)
32
-	fmt.Fprintf(cli.out, " Running: %d\n", info.ContainersRunning)
33
-	fmt.Fprintf(cli.out, " Paused: %d\n", info.ContainersPaused)
34
-	fmt.Fprintf(cli.out, " Stopped: %d\n", info.ContainersStopped)
35
-	fmt.Fprintf(cli.out, "Images: %d\n", info.Images)
36
-	ioutils.FprintfIfNotEmpty(cli.out, "Server Version: %s\n", info.ServerVersion)
37
-	ioutils.FprintfIfNotEmpty(cli.out, "Storage Driver: %s\n", info.Driver)
38
-	if info.DriverStatus != nil {
39
-		for _, pair := range info.DriverStatus {
40
-			fmt.Fprintf(cli.out, " %s: %s\n", pair[0], pair[1])
41
-
42
-			// print a warning if devicemapper is using a loopback file
43
-			if pair[0] == "Data loop file" {
44
-				fmt.Fprintln(cli.err, " WARNING: Usage of loopback devices is strongly discouraged for production use. Either use `--storage-opt dm.thinpooldev` or use `--storage-opt dm.no_warn_on_loop_devices=true` to suppress this warning.")
45
-			}
46
-		}
47
-
48
-	}
49
-	if info.SystemStatus != nil {
50
-		for _, pair := range info.SystemStatus {
51
-			fmt.Fprintf(cli.out, "%s: %s\n", pair[0], pair[1])
52
-		}
53
-	}
54
-	ioutils.FprintfIfNotEmpty(cli.out, "Execution Driver: %s\n", info.ExecutionDriver)
55
-	ioutils.FprintfIfNotEmpty(cli.out, "Logging Driver: %s\n", info.LoggingDriver)
56
-	ioutils.FprintfIfNotEmpty(cli.out, "Cgroup Driver: %s\n", info.CgroupDriver)
57
-
58
-	fmt.Fprintf(cli.out, "Plugins:\n")
59
-	fmt.Fprintf(cli.out, " Volume:")
60
-	fmt.Fprintf(cli.out, " %s", strings.Join(info.Plugins.Volume, " "))
61
-	fmt.Fprintf(cli.out, "\n")
62
-	fmt.Fprintf(cli.out, " Network:")
63
-	fmt.Fprintf(cli.out, " %s", strings.Join(info.Plugins.Network, " "))
64
-	fmt.Fprintf(cli.out, "\n")
65
-
66
-	if len(info.Plugins.Authorization) != 0 {
67
-		fmt.Fprintf(cli.out, " Authorization:")
68
-		fmt.Fprintf(cli.out, " %s", strings.Join(info.Plugins.Authorization, " "))
69
-		fmt.Fprintf(cli.out, "\n")
70
-	}
71
-
72
-	fmt.Fprintf(cli.out, "Swarm: %v\n", info.Swarm.LocalNodeState)
73
-	if info.Swarm.LocalNodeState != swarm.LocalNodeStateInactive {
74
-		fmt.Fprintf(cli.out, " NodeID: %s\n", info.Swarm.NodeID)
75
-		if info.Swarm.Error != "" {
76
-			fmt.Fprintf(cli.out, " Error: %v\n", info.Swarm.Error)
77
-		}
78
-		if info.Swarm.ControlAvailable {
79
-			fmt.Fprintf(cli.out, " IsManager: Yes\n")
80
-			fmt.Fprintf(cli.out, " Managers: %d\n", info.Swarm.Managers)
81
-			fmt.Fprintf(cli.out, " Nodes: %d\n", info.Swarm.Nodes)
82
-			ioutils.FprintfIfNotEmpty(cli.out, " CACertHash: %s\n", info.Swarm.CACertHash)
83
-		} else {
84
-			fmt.Fprintf(cli.out, " IsManager: No\n")
85
-		}
86
-	}
87
-
88
-	if len(info.Runtimes) > 0 {
89
-		fmt.Fprintf(cli.out, "Runtimes:")
90
-		for name := range info.Runtimes {
91
-			fmt.Fprintf(cli.out, " %s", name)
92
-		}
93
-		fmt.Fprint(cli.out, "\n")
94
-		fmt.Fprintf(cli.out, "Default Runtime: %s\n", info.DefaultRuntime)
95
-	}
96
-
97
-	fmt.Fprintf(cli.out, "Security Options:")
98
-	ioutils.FprintfIfNotEmpty(cli.out, " %s", strings.Join(info.SecurityOptions, " "))
99
-	fmt.Fprintf(cli.out, "\n")
100
-
101
-	ioutils.FprintfIfNotEmpty(cli.out, "Kernel Version: %s\n", info.KernelVersion)
102
-	ioutils.FprintfIfNotEmpty(cli.out, "Operating System: %s\n", info.OperatingSystem)
103
-	ioutils.FprintfIfNotEmpty(cli.out, "OSType: %s\n", info.OSType)
104
-	ioutils.FprintfIfNotEmpty(cli.out, "Architecture: %s\n", info.Architecture)
105
-	fmt.Fprintf(cli.out, "CPUs: %d\n", info.NCPU)
106
-	fmt.Fprintf(cli.out, "Total Memory: %s\n", units.BytesSize(float64(info.MemTotal)))
107
-	ioutils.FprintfIfNotEmpty(cli.out, "Name: %s\n", info.Name)
108
-	ioutils.FprintfIfNotEmpty(cli.out, "ID: %s\n", info.ID)
109
-	fmt.Fprintf(cli.out, "Docker Root Dir: %s\n", info.DockerRootDir)
110
-	fmt.Fprintf(cli.out, "Debug Mode (client): %v\n", utils.IsDebugEnabled())
111
-	fmt.Fprintf(cli.out, "Debug Mode (server): %v\n", info.Debug)
112
-
113
-	if info.Debug {
114
-		fmt.Fprintf(cli.out, " File Descriptors: %d\n", info.NFd)
115
-		fmt.Fprintf(cli.out, " Goroutines: %d\n", info.NGoroutines)
116
-		fmt.Fprintf(cli.out, " System Time: %s\n", info.SystemTime)
117
-		fmt.Fprintf(cli.out, " EventsListeners: %d\n", info.NEventsListener)
118
-	}
119
-
120
-	ioutils.FprintfIfNotEmpty(cli.out, "Http Proxy: %s\n", info.HTTPProxy)
121
-	ioutils.FprintfIfNotEmpty(cli.out, "Https Proxy: %s\n", info.HTTPSProxy)
122
-	ioutils.FprintfIfNotEmpty(cli.out, "No Proxy: %s\n", info.NoProxy)
123
-
124
-	if info.IndexServerAddress != "" {
125
-		u := cli.configFile.AuthConfigs[info.IndexServerAddress].Username
126
-		if len(u) > 0 {
127
-			fmt.Fprintf(cli.out, "Username: %v\n", u)
128
-		}
129
-		fmt.Fprintf(cli.out, "Registry: %v\n", info.IndexServerAddress)
130
-	}
131
-
132
-	// Only output these warnings if the server does not support these features
133
-	if info.OSType != "windows" {
134
-		if !info.MemoryLimit {
135
-			fmt.Fprintln(cli.err, "WARNING: No memory limit support")
136
-		}
137
-		if !info.SwapLimit {
138
-			fmt.Fprintln(cli.err, "WARNING: No swap limit support")
139
-		}
140
-		if !info.KernelMemory {
141
-			fmt.Fprintln(cli.err, "WARNING: No kernel memory limit support")
142
-		}
143
-		if !info.OomKillDisable {
144
-			fmt.Fprintln(cli.err, "WARNING: No oom kill disable support")
145
-		}
146
-		if !info.CPUCfsQuota {
147
-			fmt.Fprintln(cli.err, "WARNING: No cpu cfs quota support")
148
-		}
149
-		if !info.CPUCfsPeriod {
150
-			fmt.Fprintln(cli.err, "WARNING: No cpu cfs period support")
151
-		}
152
-		if !info.CPUShares {
153
-			fmt.Fprintln(cli.err, "WARNING: No cpu shares support")
154
-		}
155
-		if !info.CPUSet {
156
-			fmt.Fprintln(cli.err, "WARNING: No cpuset support")
157
-		}
158
-		if !info.IPv4Forwarding {
159
-			fmt.Fprintln(cli.err, "WARNING: IPv4 forwarding is disabled")
160
-		}
161
-		if !info.BridgeNfIptables {
162
-			fmt.Fprintln(cli.err, "WARNING: bridge-nf-call-iptables is disabled")
163
-		}
164
-		if !info.BridgeNfIP6tables {
165
-			fmt.Fprintln(cli.err, "WARNING: bridge-nf-call-ip6tables is disabled")
166
-		}
167
-	}
168
-
169
-	if info.Labels != nil {
170
-		fmt.Fprintln(cli.out, "Labels:")
171
-		for _, attribute := range info.Labels {
172
-			fmt.Fprintf(cli.out, " %s\n", attribute)
173
-		}
174
-	}
175
-
176
-	ioutils.FprintfIfTrue(cli.out, "Experimental: %v\n", info.ExperimentalBuild)
177
-	if info.ClusterStore != "" {
178
-		fmt.Fprintf(cli.out, "Cluster Store: %s\n", info.ClusterStore)
179
-	}
180
-
181
-	if info.ClusterAdvertise != "" {
182
-		fmt.Fprintf(cli.out, "Cluster Advertise: %s\n", info.ClusterAdvertise)
183
-	}
184
-
185
-	if info.RegistryConfig != nil && (len(info.RegistryConfig.InsecureRegistryCIDRs) > 0 || len(info.RegistryConfig.IndexConfigs) > 0) {
186
-		fmt.Fprintln(cli.out, "Insecure Registries:")
187
-		for _, registry := range info.RegistryConfig.IndexConfigs {
188
-			if registry.Secure == false {
189
-				fmt.Fprintf(cli.out, " %s\n", registry.Name)
190
-			}
191
-		}
192
-
193
-		for _, registry := range info.RegistryConfig.InsecureRegistryCIDRs {
194
-			mask, _ := registry.Mask.Size()
195
-			fmt.Fprintf(cli.out, " %s/%d\n", registry.IP.String(), mask)
196
-		}
197
-	}
198
-	return nil
199
-}
200 1
new file mode 100644
... ...
@@ -0,0 +1,206 @@
0
+package system
1
+
2
+import (
3
+	"fmt"
4
+	"strings"
5
+
6
+	"golang.org/x/net/context"
7
+
8
+	"github.com/docker/docker/api/client"
9
+	"github.com/docker/docker/cli"
10
+	"github.com/docker/docker/pkg/ioutils"
11
+	"github.com/docker/docker/utils"
12
+	"github.com/docker/engine-api/types/swarm"
13
+	"github.com/docker/go-units"
14
+	"github.com/spf13/cobra"
15
+)
16
+
17
+// NewInfoCommand creates a new cobra.Command for `docker info`
18
+func NewInfoCommand(dockerCli *client.DockerCli) *cobra.Command {
19
+	cmd := &cobra.Command{
20
+		Use:   "info",
21
+		Short: "Display system-wide information",
22
+		Args:  cli.ExactArgs(0),
23
+		RunE: func(cmd *cobra.Command, args []string) error {
24
+			return runInfo(dockerCli)
25
+		},
26
+	}
27
+	return cmd
28
+
29
+}
30
+
31
+func runInfo(dockerCli *client.DockerCli) error {
32
+	info, err := dockerCli.Client().Info(context.Background())
33
+	if err != nil {
34
+		return err
35
+	}
36
+
37
+	fmt.Fprintf(dockerCli.Out(), "Containers: %d\n", info.Containers)
38
+	fmt.Fprintf(dockerCli.Out(), " Running: %d\n", info.ContainersRunning)
39
+	fmt.Fprintf(dockerCli.Out(), " Paused: %d\n", info.ContainersPaused)
40
+	fmt.Fprintf(dockerCli.Out(), " Stopped: %d\n", info.ContainersStopped)
41
+	fmt.Fprintf(dockerCli.Out(), "Images: %d\n", info.Images)
42
+	ioutils.FprintfIfNotEmpty(dockerCli.Out(), "Server Version: %s\n", info.ServerVersion)
43
+	ioutils.FprintfIfNotEmpty(dockerCli.Out(), "Storage Driver: %s\n", info.Driver)
44
+	if info.DriverStatus != nil {
45
+		for _, pair := range info.DriverStatus {
46
+			fmt.Fprintf(dockerCli.Out(), " %s: %s\n", pair[0], pair[1])
47
+
48
+			// print a warning if devicemapper is using a loopback file
49
+			if pair[0] == "Data loop file" {
50
+				fmt.Fprintln(dockerCli.Err(), " WARNING: Usage of loopback devices is strongly discouraged for production use. Either use `--storage-opt dm.thinpooldev` or use `--storage-opt dm.no_warn_on_loop_devices=true` to suppress this warning.")
51
+			}
52
+		}
53
+
54
+	}
55
+	if info.SystemStatus != nil {
56
+		for _, pair := range info.SystemStatus {
57
+			fmt.Fprintf(dockerCli.Out(), "%s: %s\n", pair[0], pair[1])
58
+		}
59
+	}
60
+	ioutils.FprintfIfNotEmpty(dockerCli.Out(), "Execution Driver: %s\n", info.ExecutionDriver)
61
+	ioutils.FprintfIfNotEmpty(dockerCli.Out(), "Logging Driver: %s\n", info.LoggingDriver)
62
+	ioutils.FprintfIfNotEmpty(dockerCli.Out(), "Cgroup Driver: %s\n", info.CgroupDriver)
63
+
64
+	fmt.Fprintf(dockerCli.Out(), "Plugins: \n")
65
+	fmt.Fprintf(dockerCli.Out(), " Volume:")
66
+	fmt.Fprintf(dockerCli.Out(), " %s", strings.Join(info.Plugins.Volume, " "))
67
+	fmt.Fprintf(dockerCli.Out(), "\n")
68
+	fmt.Fprintf(dockerCli.Out(), " Network:")
69
+	fmt.Fprintf(dockerCli.Out(), " %s", strings.Join(info.Plugins.Network, " "))
70
+	fmt.Fprintf(dockerCli.Out(), "\n")
71
+
72
+	if len(info.Plugins.Authorization) != 0 {
73
+		fmt.Fprintf(dockerCli.Out(), " Authorization:")
74
+		fmt.Fprintf(dockerCli.Out(), " %s", strings.Join(info.Plugins.Authorization, " "))
75
+		fmt.Fprintf(dockerCli.Out(), "\n")
76
+	}
77
+
78
+	fmt.Fprintf(dockerCli.Out(), "Swarm: %v\n", info.Swarm.LocalNodeState)
79
+	if info.Swarm.LocalNodeState != swarm.LocalNodeStateInactive {
80
+		fmt.Fprintf(dockerCli.Out(), " NodeID: %s\n", info.Swarm.NodeID)
81
+		if info.Swarm.Error != "" {
82
+			fmt.Fprintf(dockerCli.Out(), " Error: %v\n", info.Swarm.Error)
83
+		}
84
+		if info.Swarm.ControlAvailable {
85
+			fmt.Fprintf(dockerCli.Out(), " IsManager: Yes\n")
86
+			fmt.Fprintf(dockerCli.Out(), " Managers: %d\n", info.Swarm.Managers)
87
+			fmt.Fprintf(dockerCli.Out(), " Nodes: %d\n", info.Swarm.Nodes)
88
+			ioutils.FprintfIfNotEmpty(dockerCli.Out(), " CACertHash: %s\n", info.Swarm.CACertHash)
89
+		} else {
90
+			fmt.Fprintf(dockerCli.Out(), " IsManager: No\n")
91
+		}
92
+	}
93
+
94
+	if len(info.Runtimes) > 0 {
95
+		fmt.Fprintf(dockerCli.Out(), "Runtimes:")
96
+		for name := range info.Runtimes {
97
+			fmt.Fprintf(dockerCli.Out(), " %s", name)
98
+		}
99
+		fmt.Fprint(dockerCli.Out(), "\n")
100
+		fmt.Fprintf(dockerCli.Out(), "Default Runtime: %s\n", info.DefaultRuntime)
101
+	}
102
+
103
+	fmt.Fprintf(dockerCli.Out(), "Security Options:")
104
+	ioutils.FprintfIfNotEmpty(dockerCli.Out(), " %s", strings.Join(info.SecurityOptions, " "))
105
+	fmt.Fprintf(dockerCli.Out(), "\n")
106
+
107
+	ioutils.FprintfIfNotEmpty(dockerCli.Out(), "Kernel Version: %s\n", info.KernelVersion)
108
+	ioutils.FprintfIfNotEmpty(dockerCli.Out(), "Operating System: %s\n", info.OperatingSystem)
109
+	ioutils.FprintfIfNotEmpty(dockerCli.Out(), "OSType: %s\n", info.OSType)
110
+	ioutils.FprintfIfNotEmpty(dockerCli.Out(), "Architecture: %s\n", info.Architecture)
111
+	fmt.Fprintf(dockerCli.Out(), "CPUs: %d\n", info.NCPU)
112
+	fmt.Fprintf(dockerCli.Out(), "Total Memory: %s\n", units.BytesSize(float64(info.MemTotal)))
113
+	ioutils.FprintfIfNotEmpty(dockerCli.Out(), "Name: %s\n", info.Name)
114
+	ioutils.FprintfIfNotEmpty(dockerCli.Out(), "ID: %s\n", info.ID)
115
+	fmt.Fprintf(dockerCli.Out(), "Docker Root Dir: %s\n", info.DockerRootDir)
116
+	fmt.Fprintf(dockerCli.Out(), "Debug Mode (client): %v\n", utils.IsDebugEnabled())
117
+	fmt.Fprintf(dockerCli.Out(), "Debug Mode (server): %v\n", info.Debug)
118
+
119
+	if info.Debug {
120
+		fmt.Fprintf(dockerCli.Out(), " File Descriptors: %d\n", info.NFd)
121
+		fmt.Fprintf(dockerCli.Out(), " Goroutines: %d\n", info.NGoroutines)
122
+		fmt.Fprintf(dockerCli.Out(), " System Time: %s\n", info.SystemTime)
123
+		fmt.Fprintf(dockerCli.Out(), " EventsListeners: %d\n", info.NEventsListener)
124
+	}
125
+
126
+	ioutils.FprintfIfNotEmpty(dockerCli.Out(), "Http Proxy: %s\n", info.HTTPProxy)
127
+	ioutils.FprintfIfNotEmpty(dockerCli.Out(), "Https Proxy: %s\n", info.HTTPSProxy)
128
+	ioutils.FprintfIfNotEmpty(dockerCli.Out(), "No Proxy: %s\n", info.NoProxy)
129
+
130
+	if info.IndexServerAddress != "" {
131
+		u := dockerCli.ConfigFile().AuthConfigs[info.IndexServerAddress].Username
132
+		if len(u) > 0 {
133
+			fmt.Fprintf(dockerCli.Out(), "Username: %v\n", u)
134
+		}
135
+		fmt.Fprintf(dockerCli.Out(), "Registry: %v\n", info.IndexServerAddress)
136
+	}
137
+
138
+	// Only output these warnings if the server does not support these features
139
+	if info.OSType != "windows" {
140
+		if !info.MemoryLimit {
141
+			fmt.Fprintln(dockerCli.Err(), "WARNING: No memory limit support")
142
+		}
143
+		if !info.SwapLimit {
144
+			fmt.Fprintln(dockerCli.Err(), "WARNING: No swap limit support")
145
+		}
146
+		if !info.KernelMemory {
147
+			fmt.Fprintln(dockerCli.Err(), "WARNING: No kernel memory limit support")
148
+		}
149
+		if !info.OomKillDisable {
150
+			fmt.Fprintln(dockerCli.Err(), "WARNING: No oom kill disable support")
151
+		}
152
+		if !info.CPUCfsQuota {
153
+			fmt.Fprintln(dockerCli.Err(), "WARNING: No cpu cfs quota support")
154
+		}
155
+		if !info.CPUCfsPeriod {
156
+			fmt.Fprintln(dockerCli.Err(), "WARNING: No cpu cfs period support")
157
+		}
158
+		if !info.CPUShares {
159
+			fmt.Fprintln(dockerCli.Err(), "WARNING: No cpu shares support")
160
+		}
161
+		if !info.CPUSet {
162
+			fmt.Fprintln(dockerCli.Err(), "WARNING: No cpuset support")
163
+		}
164
+		if !info.IPv4Forwarding {
165
+			fmt.Fprintln(dockerCli.Err(), "WARNING: IPv4 forwarding is disabled")
166
+		}
167
+		if !info.BridgeNfIptables {
168
+			fmt.Fprintln(dockerCli.Err(), "WARNING: bridge-nf-call-iptables is disabled")
169
+		}
170
+		if !info.BridgeNfIP6tables {
171
+			fmt.Fprintln(dockerCli.Err(), "WARNING: bridge-nf-call-ip6tables is disabled")
172
+		}
173
+	}
174
+
175
+	if info.Labels != nil {
176
+		fmt.Fprintln(dockerCli.Out(), "Labels:")
177
+		for _, attribute := range info.Labels {
178
+			fmt.Fprintf(dockerCli.Out(), " %s\n", attribute)
179
+		}
180
+	}
181
+
182
+	ioutils.FprintfIfTrue(dockerCli.Out(), "Experimental: %v\n", info.ExperimentalBuild)
183
+	if info.ClusterStore != "" {
184
+		fmt.Fprintf(dockerCli.Out(), "Cluster Store: %s\n", info.ClusterStore)
185
+	}
186
+
187
+	if info.ClusterAdvertise != "" {
188
+		fmt.Fprintf(dockerCli.Out(), "Cluster Advertise: %s\n", info.ClusterAdvertise)
189
+	}
190
+
191
+	if info.RegistryConfig != nil && (len(info.RegistryConfig.InsecureRegistryCIDRs) > 0 || len(info.RegistryConfig.IndexConfigs) > 0) {
192
+		fmt.Fprintln(dockerCli.Out(), "Insecure Registries:")
193
+		for _, registry := range info.RegistryConfig.IndexConfigs {
194
+			if registry.Secure == false {
195
+				fmt.Fprintf(dockerCli.Out(), " %s\n", registry.Name)
196
+			}
197
+		}
198
+
199
+		for _, registry := range info.RegistryConfig.InsecureRegistryCIDRs {
200
+			mask, _ := registry.Mask.Size()
201
+			fmt.Fprintf(dockerCli.Out(), " %s/%d\n", registry.IP.String(), mask)
202
+		}
203
+	}
204
+	return nil
205
+}
... ...
@@ -84,6 +84,7 @@ func NewCobraAdaptor(clientFlags *cliflags.ClientFlags) CobraAdaptor {
84 84
 		registry.NewLogoutCommand(dockerCli),
85 85
 		system.NewVersionCommand(dockerCli),
86 86
 		volume.NewVolumeCommand(dockerCli),
87
+		system.NewInfoCommand(dockerCli),
87 88
 	)
88 89
 	plugin.NewPluginCommand(rootCmd, dockerCli)
89 90
 
... ...
@@ -9,7 +9,6 @@ type Command struct {
9 9
 // DockerCommandUsage lists the top level docker commands and their short usage
10 10
 var DockerCommandUsage = []Command{
11 11
 	{"exec", "Run a command in a running container"},
12
-	{"info", "Display system-wide information"},
13 12
 	{"inspect", "Return low-level information on a container, image or task"},
14 13
 	{"update", "Update configuration of one or more containers"},
15 14
 }