diff --git a/cli/command/system/info.go b/cli/command/system/info.go index d30f8b2dfb..2e57bf4213 100644 --- a/cli/command/system/info.go +++ b/cli/command/system/info.go @@ -28,8 +28,8 @@ type infoOptions struct { } type clientInfo struct { - Debug bool - Context string + Debug bool + clientVersion Plugins []pluginmanager.Plugin Warnings []string } @@ -46,6 +46,13 @@ type info struct { ClientErrors []string `json:",omitempty"` } +func (i *info) clientPlatform() string { + if i.ClientInfo != nil && i.ClientInfo.Platform != nil { + return i.ClientInfo.Platform.Name + } + return "" +} + // NewInfoCommand creates a new cobra.Command for `docker info` func NewInfoCommand(dockerCli command.Cli) *cobra.Command { var opts infoOptions @@ -71,8 +78,11 @@ func NewInfoCommand(dockerCli command.Cli) *cobra.Command { func runInfo(cmd *cobra.Command, dockerCli command.Cli, opts *infoOptions) error { info := info{ ClientInfo: &clientInfo{ - Context: dockerCli.CurrentContext(), - Debug: debug.IsEnabled(), + // Don't pass a dockerCLI to newClientVersion(), because we currently + // don't include negotiated API version, and want to avoid making an + // API connection when only printing the Client section. + clientVersion: newClientVersion(dockerCli.CurrentContext(), nil), + Debug: debug.IsEnabled(), }, Info: &types.Info{}, } @@ -147,7 +157,12 @@ func needsServerInfo(template string, info info) bool { } func prettyPrintInfo(dockerCli command.Cli, info info) error { - fmt.Fprintln(dockerCli.Out(), "Client:") + // Only append the platform info if it's not empty, to prevent printing a trailing space. + if p := info.clientPlatform(); p != "" { + _, _ = fmt.Fprintln(dockerCli.Out(), "Client:", p) + } else { + _, _ = fmt.Fprintln(dockerCli.Out(), "Client:") + } if info.ClientInfo != nil { prettyPrintClientInfo(dockerCli, *info.ClientInfo) } @@ -173,6 +188,7 @@ func prettyPrintInfo(dockerCli command.Cli, info info) error { } func prettyPrintClientInfo(dockerCli command.Cli, info clientInfo) { + fprintlnNonEmpty(dockerCli.Out(), " Version: ", info.Version) fmt.Fprintln(dockerCli.Out(), " Context: ", info.Context) fmt.Fprintln(dockerCli.Out(), " Debug Mode:", info.Debug) diff --git a/cli/command/system/info_test.go b/cli/command/system/info_test.go index 5df964006f..298fa5d963 100644 --- a/cli/command/system/info_test.go +++ b/cli/command/system/info_test.go @@ -278,8 +278,12 @@ func TestPrettyPrintInfo(t *testing.T) { dockerInfo: info{ Info: &sampleInfoNoSwarm, ClientInfo: &clientInfo{ - Context: "default", - Debug: true, + clientVersion: clientVersion{ + Platform: &platformInfo{Name: "Docker Engine - Community"}, + Version: "24.0.0", + Context: "default", + }, + Debug: true, }, }, prettyGolden: "docker-info-no-swarm", @@ -290,8 +294,8 @@ func TestPrettyPrintInfo(t *testing.T) { dockerInfo: info{ Info: &sampleInfoNoSwarm, ClientInfo: &clientInfo{ - Context: "default", - Plugins: samplePluginsInfo, + clientVersion: clientVersion{Context: "default"}, + Plugins: samplePluginsInfo, }, }, prettyGolden: "docker-info-plugins", @@ -302,7 +306,7 @@ func TestPrettyPrintInfo(t *testing.T) { doc: "info with nil labels", dockerInfo: info{ Info: &sampleInfoLabelsNil, - ClientInfo: &clientInfo{Context: "default"}, + ClientInfo: &clientInfo{clientVersion: clientVersion{Context: "default"}}, }, prettyGolden: "docker-info-with-labels-nil", }, @@ -310,7 +314,7 @@ func TestPrettyPrintInfo(t *testing.T) { doc: "info with empty labels", dockerInfo: info{ Info: &sampleInfoLabelsEmpty, - ClientInfo: &clientInfo{Context: "default"}, + ClientInfo: &clientInfo{clientVersion: clientVersion{Context: "default"}}, }, prettyGolden: "docker-info-with-labels-empty", }, @@ -319,8 +323,8 @@ func TestPrettyPrintInfo(t *testing.T) { dockerInfo: info{ Info: &infoWithSwarm, ClientInfo: &clientInfo{ - Context: "default", - Debug: false, + clientVersion: clientVersion{Context: "default"}, + Debug: false, }, }, prettyGolden: "docker-info-with-swarm", @@ -331,8 +335,12 @@ func TestPrettyPrintInfo(t *testing.T) { dockerInfo: info{ Info: &infoWithWarningsLinux, ClientInfo: &clientInfo{ - Context: "default", - Debug: true, + clientVersion: clientVersion{ + Platform: &platformInfo{Name: "Docker Engine - Community"}, + Version: "24.0.0", + Context: "default", + }, + Debug: true, }, }, prettyGolden: "docker-info-no-swarm", @@ -344,8 +352,12 @@ func TestPrettyPrintInfo(t *testing.T) { dockerInfo: info{ Info: &sampleInfoDaemonWarnings, ClientInfo: &clientInfo{ - Context: "default", - Debug: true, + clientVersion: clientVersion{ + Platform: &platformInfo{Name: "Docker Engine - Community"}, + Version: "24.0.0", + Context: "default", + }, + Debug: true, }, }, prettyGolden: "docker-info-no-swarm", @@ -376,6 +388,7 @@ func TestPrettyPrintInfo(t *testing.T) { expectedError: "errors pretty printing info", }, } { + tc := tc t.Run(tc.doc, func(t *testing.T) { cli := test.NewFakeCli(&fakeClient{}) err := prettyPrintInfo(cli, tc.dockerInfo) @@ -429,6 +442,7 @@ func TestFormatInfo(t *testing.T) { expectedError: `template: :1:2: executing "" at <.badString>: can't evaluate field badString in type system.info`, }, } { + tc := tc t.Run(tc.doc, func(t *testing.T) { cli := test.NewFakeCli(&fakeClient{}) info := info{ diff --git a/cli/command/system/testdata/docker-client-version.json.golden b/cli/command/system/testdata/docker-client-version.json.golden index 3a6688548b..088d7dc466 100644 --- a/cli/command/system/testdata/docker-client-version.json.golden +++ b/cli/command/system/testdata/docker-client-version.json.golden @@ -1 +1 @@ -{"Client":{"Platform":{"Name":""},"Version":"18.99.5-ce","ApiVersion":"1.38","DefaultAPIVersion":"1.38","GitCommit":"deadbeef","GoVersion":"go1.10.2","Os":"linux","Arch":"amd64","BuildTime":"Wed May 30 22:21:05 2018","Context":"my-context"},"Server":{"Platform":{"Name":"Docker Enterprise Edition (EE) 2.0"},"Components":[{"Name":"Engine","Version":"17.06.2-ee-15","Details":{"ApiVersion":"1.30","Arch":"amd64","BuildTime":"Mon Jul 9 23:38:38 2018","Experimental":"false","GitCommit":"64ddfa6","GoVersion":"go1.8.7","MinAPIVersion":"1.12","Os":"linux"}},{"Name":"Universal Control Plane","Version":"17.06.2-ee-15","Details":{"ApiVersion":"1.30","Arch":"amd64","BuildTime":"Mon Jul 2 21:24:07 UTC 2018","GitCommit":"4513922","GoVersion":"go1.9.4","MinApiVersion":"1.20","Os":"linux","Version":"3.0.3-tp2"}},{"Name":"Kubernetes","Version":"1.8+","Details":{"buildDate":"2018-04-26T16:51:21Z","compiler":"gc","gitCommit":"8d637aedf46b9c21dde723e29c645b9f27106fa5","gitTreeState":"clean","gitVersion":"v1.8.11-docker-8d637ae","goVersion":"go1.8.3","major":"1","minor":"8+","platform":"linux/amd64"}},{"Name":"Calico","Version":"v3.0.8","Details":{"cni":"v2.0.6","kube-controllers":"v2.0.5","node":"v3.0.8"}}],"Version":"","ApiVersion":"","GitCommit":"","GoVersion":"","Os":"","Arch":""}} +{"Client":{"Version":"18.99.5-ce","ApiVersion":"1.38","DefaultAPIVersion":"1.38","GitCommit":"deadbeef","GoVersion":"go1.10.2","Os":"linux","Arch":"amd64","BuildTime":"Wed May 30 22:21:05 2018","Context":"my-context"},"Server":{"Platform":{"Name":"Docker Enterprise Edition (EE) 2.0"},"Components":[{"Name":"Engine","Version":"17.06.2-ee-15","Details":{"ApiVersion":"1.30","Arch":"amd64","BuildTime":"Mon Jul 9 23:38:38 2018","Experimental":"false","GitCommit":"64ddfa6","GoVersion":"go1.8.7","MinAPIVersion":"1.12","Os":"linux"}},{"Name":"Universal Control Plane","Version":"17.06.2-ee-15","Details":{"ApiVersion":"1.30","Arch":"amd64","BuildTime":"Mon Jul 2 21:24:07 UTC 2018","GitCommit":"4513922","GoVersion":"go1.9.4","MinApiVersion":"1.20","Os":"linux","Version":"3.0.3-tp2"}},{"Name":"Kubernetes","Version":"1.8+","Details":{"buildDate":"2018-04-26T16:51:21Z","compiler":"gc","gitCommit":"8d637aedf46b9c21dde723e29c645b9f27106fa5","gitTreeState":"clean","gitVersion":"v1.8.11-docker-8d637ae","goVersion":"go1.8.3","major":"1","minor":"8+","platform":"linux/amd64"}},{"Name":"Calico","Version":"v3.0.8","Details":{"cni":"v2.0.6","kube-controllers":"v2.0.5","node":"v3.0.8"}}],"Version":"","ApiVersion":"","GitCommit":"","GoVersion":"","Os":"","Arch":""}} diff --git a/cli/command/system/testdata/docker-info-daemon-warnings.json.golden b/cli/command/system/testdata/docker-info-daemon-warnings.json.golden index 8bf4523577..486f8bf6eb 100644 --- a/cli/command/system/testdata/docker-info-daemon-warnings.json.golden +++ b/cli/command/system/testdata/docker-info-daemon-warnings.json.golden @@ -1 +1 @@ -{"ID":"EKHL:QDUU:QZ7U:MKGD:VDXK:S27Q:GIPU:24B7:R7VT:DGN6:QCSF:2UBX","Containers":0,"ContainersRunning":0,"ContainersPaused":0,"ContainersStopped":0,"Images":0,"Driver":"aufs","DriverStatus":[["Root Dir","/var/lib/docker/aufs"],["Backing Filesystem","extfs"],["Dirs","0"],["Dirperm1 Supported","true"]],"Plugins":{"Volume":["local"],"Network":["bridge","host","macvlan","null","overlay"],"Authorization":null,"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","logentries","splunk","syslog"]},"MemoryLimit":true,"SwapLimit":true,"KernelMemory":true,"CpuCfsPeriod":true,"CpuCfsQuota":true,"CPUShares":true,"CPUSet":true,"PidsLimit":false,"IPv4Forwarding":true,"BridgeNfIptables":true,"BridgeNfIp6tables":true,"Debug":true,"NFd":33,"OomKillDisable":true,"NGoroutines":135,"SystemTime":"2017-08-24T17:44:34.077811894Z","LoggingDriver":"json-file","CgroupDriver":"cgroupfs","NEventsListener":0,"KernelVersion":"4.4.0-87-generic","OperatingSystem":"Ubuntu 16.04.3 LTS","OSVersion":"","OSType":"linux","Architecture":"x86_64","IndexServerAddress":"https://index.docker.io/v1/","RegistryConfig":{"AllowNondistributableArtifactsCIDRs":null,"AllowNondistributableArtifactsHostnames":null,"InsecureRegistryCIDRs":["127.0.0.0/8"],"IndexConfigs":{"docker.io":{"Name":"docker.io","Mirrors":null,"Secure":true,"Official":true}},"Mirrors":null},"NCPU":2,"MemTotal":2097356800,"GenericResources":null,"DockerRootDir":"/var/lib/docker","HttpProxy":"","HttpsProxy":"","NoProxy":"","Name":"system-sample","Labels":["provider=digitalocean"],"ExperimentalBuild":false,"ServerVersion":"17.06.1-ce","Runtimes":{"runc":{"path":"docker-runc"}},"DefaultRuntime":"runc","Swarm":{"NodeID":"","NodeAddr":"","LocalNodeState":"inactive","ControlAvailable":false,"Error":"","RemoteManagers":null},"LiveRestoreEnabled":false,"Isolation":"","InitBinary":"docker-init","ContainerdCommit":{"ID":"6e23458c129b551d5c9871e5174f6b1b7f6d1170","Expected":"6e23458c129b551d5c9871e5174f6b1b7f6d1170"},"RuncCommit":{"ID":"810190ceaa507aa2727d7ae6f4790c76ec150bd2","Expected":"810190ceaa507aa2727d7ae6f4790c76ec150bd2"},"InitCommit":{"ID":"949e6fa","Expected":"949e6fa"},"SecurityOptions":["name=apparmor","name=seccomp,profile=default"],"DefaultAddressPools":[{"Base":"10.123.0.0/16","Size":24}],"Warnings":["WARNING: No memory limit support","WARNING: No swap limit support","WARNING: No oom kill disable support","WARNING: No cpu cfs quota support","WARNING: No cpu cfs period support","WARNING: No cpu shares support","WARNING: No cpuset support","WARNING: IPv4 forwarding is disabled","WARNING: bridge-nf-call-iptables is disabled","WARNING: bridge-nf-call-ip6tables is disabled"],"ClientInfo":{"Debug":true,"Context":"default","Plugins":[],"Warnings":null}} +{"ID":"EKHL:QDUU:QZ7U:MKGD:VDXK:S27Q:GIPU:24B7:R7VT:DGN6:QCSF:2UBX","Containers":0,"ContainersRunning":0,"ContainersPaused":0,"ContainersStopped":0,"Images":0,"Driver":"aufs","DriverStatus":[["Root Dir","/var/lib/docker/aufs"],["Backing Filesystem","extfs"],["Dirs","0"],["Dirperm1 Supported","true"]],"Plugins":{"Volume":["local"],"Network":["bridge","host","macvlan","null","overlay"],"Authorization":null,"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","logentries","splunk","syslog"]},"MemoryLimit":true,"SwapLimit":true,"KernelMemory":true,"CpuCfsPeriod":true,"CpuCfsQuota":true,"CPUShares":true,"CPUSet":true,"PidsLimit":false,"IPv4Forwarding":true,"BridgeNfIptables":true,"BridgeNfIp6tables":true,"Debug":true,"NFd":33,"OomKillDisable":true,"NGoroutines":135,"SystemTime":"2017-08-24T17:44:34.077811894Z","LoggingDriver":"json-file","CgroupDriver":"cgroupfs","NEventsListener":0,"KernelVersion":"4.4.0-87-generic","OperatingSystem":"Ubuntu 16.04.3 LTS","OSVersion":"","OSType":"linux","Architecture":"x86_64","IndexServerAddress":"https://index.docker.io/v1/","RegistryConfig":{"AllowNondistributableArtifactsCIDRs":null,"AllowNondistributableArtifactsHostnames":null,"InsecureRegistryCIDRs":["127.0.0.0/8"],"IndexConfigs":{"docker.io":{"Name":"docker.io","Mirrors":null,"Secure":true,"Official":true}},"Mirrors":null},"NCPU":2,"MemTotal":2097356800,"GenericResources":null,"DockerRootDir":"/var/lib/docker","HttpProxy":"","HttpsProxy":"","NoProxy":"","Name":"system-sample","Labels":["provider=digitalocean"],"ExperimentalBuild":false,"ServerVersion":"17.06.1-ce","Runtimes":{"runc":{"path":"docker-runc"}},"DefaultRuntime":"runc","Swarm":{"NodeID":"","NodeAddr":"","LocalNodeState":"inactive","ControlAvailable":false,"Error":"","RemoteManagers":null},"LiveRestoreEnabled":false,"Isolation":"","InitBinary":"docker-init","ContainerdCommit":{"ID":"6e23458c129b551d5c9871e5174f6b1b7f6d1170","Expected":"6e23458c129b551d5c9871e5174f6b1b7f6d1170"},"RuncCommit":{"ID":"810190ceaa507aa2727d7ae6f4790c76ec150bd2","Expected":"810190ceaa507aa2727d7ae6f4790c76ec150bd2"},"InitCommit":{"ID":"949e6fa","Expected":"949e6fa"},"SecurityOptions":["name=apparmor","name=seccomp,profile=default"],"DefaultAddressPools":[{"Base":"10.123.0.0/16","Size":24}],"Warnings":["WARNING: No memory limit support","WARNING: No swap limit support","WARNING: No oom kill disable support","WARNING: No cpu cfs quota support","WARNING: No cpu cfs period support","WARNING: No cpu shares support","WARNING: No cpuset support","WARNING: IPv4 forwarding is disabled","WARNING: bridge-nf-call-iptables is disabled","WARNING: bridge-nf-call-ip6tables is disabled"],"ClientInfo":{"Debug":true,"Platform":{"Name":"Docker Engine - Community"},"Version":"24.0.0","Context":"default","Plugins":[],"Warnings":null}} diff --git a/cli/command/system/testdata/docker-info-legacy-warnings.json.golden b/cli/command/system/testdata/docker-info-legacy-warnings.json.golden index d06446962d..141dbc96b8 100644 --- a/cli/command/system/testdata/docker-info-legacy-warnings.json.golden +++ b/cli/command/system/testdata/docker-info-legacy-warnings.json.golden @@ -1 +1 @@ -{"ID":"EKHL:QDUU:QZ7U:MKGD:VDXK:S27Q:GIPU:24B7:R7VT:DGN6:QCSF:2UBX","Containers":0,"ContainersRunning":0,"ContainersPaused":0,"ContainersStopped":0,"Images":0,"Driver":"aufs","DriverStatus":[["Root Dir","/var/lib/docker/aufs"],["Backing Filesystem","extfs"],["Dirs","0"],["Dirperm1 Supported","true"]],"Plugins":{"Volume":["local"],"Network":["bridge","host","macvlan","null","overlay"],"Authorization":null,"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","logentries","splunk","syslog"]},"MemoryLimit":false,"SwapLimit":false,"CpuCfsPeriod":false,"CpuCfsQuota":false,"CPUShares":false,"CPUSet":false,"PidsLimit":false,"IPv4Forwarding":false,"BridgeNfIptables":false,"BridgeNfIp6tables":false,"Debug":true,"NFd":33,"OomKillDisable":false,"NGoroutines":135,"SystemTime":"2017-08-24T17:44:34.077811894Z","LoggingDriver":"json-file","CgroupDriver":"cgroupfs","NEventsListener":0,"KernelVersion":"4.4.0-87-generic","OperatingSystem":"Ubuntu 16.04.3 LTS","OSVersion":"","OSType":"linux","Architecture":"x86_64","IndexServerAddress":"https://index.docker.io/v1/","RegistryConfig":{"AllowNondistributableArtifactsCIDRs":null,"AllowNondistributableArtifactsHostnames":null,"InsecureRegistryCIDRs":["127.0.0.0/8"],"IndexConfigs":{"docker.io":{"Name":"docker.io","Mirrors":null,"Secure":true,"Official":true}},"Mirrors":null},"NCPU":2,"MemTotal":2097356800,"GenericResources":null,"DockerRootDir":"/var/lib/docker","HttpProxy":"","HttpsProxy":"","NoProxy":"","Name":"system-sample","Labels":["provider=digitalocean"],"ExperimentalBuild":false,"ServerVersion":"17.06.1-ce","Runtimes":{"runc":{"path":"docker-runc"}},"DefaultRuntime":"runc","Swarm":{"NodeID":"","NodeAddr":"","LocalNodeState":"inactive","ControlAvailable":false,"Error":"","RemoteManagers":null},"LiveRestoreEnabled":false,"Isolation":"","InitBinary":"docker-init","ContainerdCommit":{"ID":"6e23458c129b551d5c9871e5174f6b1b7f6d1170","Expected":"6e23458c129b551d5c9871e5174f6b1b7f6d1170"},"RuncCommit":{"ID":"810190ceaa507aa2727d7ae6f4790c76ec150bd2","Expected":"810190ceaa507aa2727d7ae6f4790c76ec150bd2"},"InitCommit":{"ID":"949e6fa","Expected":"949e6fa"},"SecurityOptions":["name=apparmor","name=seccomp,profile=default"],"DefaultAddressPools":[{"Base":"10.123.0.0/16","Size":24}],"Warnings":null,"ClientInfo":{"Debug":true,"Context":"default","Plugins":[],"Warnings":null}} +{"ID":"EKHL:QDUU:QZ7U:MKGD:VDXK:S27Q:GIPU:24B7:R7VT:DGN6:QCSF:2UBX","Containers":0,"ContainersRunning":0,"ContainersPaused":0,"ContainersStopped":0,"Images":0,"Driver":"aufs","DriverStatus":[["Root Dir","/var/lib/docker/aufs"],["Backing Filesystem","extfs"],["Dirs","0"],["Dirperm1 Supported","true"]],"Plugins":{"Volume":["local"],"Network":["bridge","host","macvlan","null","overlay"],"Authorization":null,"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","logentries","splunk","syslog"]},"MemoryLimit":false,"SwapLimit":false,"CpuCfsPeriod":false,"CpuCfsQuota":false,"CPUShares":false,"CPUSet":false,"PidsLimit":false,"IPv4Forwarding":false,"BridgeNfIptables":false,"BridgeNfIp6tables":false,"Debug":true,"NFd":33,"OomKillDisable":false,"NGoroutines":135,"SystemTime":"2017-08-24T17:44:34.077811894Z","LoggingDriver":"json-file","CgroupDriver":"cgroupfs","NEventsListener":0,"KernelVersion":"4.4.0-87-generic","OperatingSystem":"Ubuntu 16.04.3 LTS","OSVersion":"","OSType":"linux","Architecture":"x86_64","IndexServerAddress":"https://index.docker.io/v1/","RegistryConfig":{"AllowNondistributableArtifactsCIDRs":null,"AllowNondistributableArtifactsHostnames":null,"InsecureRegistryCIDRs":["127.0.0.0/8"],"IndexConfigs":{"docker.io":{"Name":"docker.io","Mirrors":null,"Secure":true,"Official":true}},"Mirrors":null},"NCPU":2,"MemTotal":2097356800,"GenericResources":null,"DockerRootDir":"/var/lib/docker","HttpProxy":"","HttpsProxy":"","NoProxy":"","Name":"system-sample","Labels":["provider=digitalocean"],"ExperimentalBuild":false,"ServerVersion":"17.06.1-ce","Runtimes":{"runc":{"path":"docker-runc"}},"DefaultRuntime":"runc","Swarm":{"NodeID":"","NodeAddr":"","LocalNodeState":"inactive","ControlAvailable":false,"Error":"","RemoteManagers":null},"LiveRestoreEnabled":false,"Isolation":"","InitBinary":"docker-init","ContainerdCommit":{"ID":"6e23458c129b551d5c9871e5174f6b1b7f6d1170","Expected":"6e23458c129b551d5c9871e5174f6b1b7f6d1170"},"RuncCommit":{"ID":"810190ceaa507aa2727d7ae6f4790c76ec150bd2","Expected":"810190ceaa507aa2727d7ae6f4790c76ec150bd2"},"InitCommit":{"ID":"949e6fa","Expected":"949e6fa"},"SecurityOptions":["name=apparmor","name=seccomp,profile=default"],"DefaultAddressPools":[{"Base":"10.123.0.0/16","Size":24}],"Warnings":null,"ClientInfo":{"Debug":true,"Platform":{"Name":"Docker Engine - Community"},"Version":"24.0.0","Context":"default","Plugins":[],"Warnings":null}} diff --git a/cli/command/system/testdata/docker-info-no-swarm.golden b/cli/command/system/testdata/docker-info-no-swarm.golden index 60c4d56ee1..7a86abf10d 100644 --- a/cli/command/system/testdata/docker-info-no-swarm.golden +++ b/cli/command/system/testdata/docker-info-no-swarm.golden @@ -1,4 +1,5 @@ -Client: +Client: Docker Engine - Community + Version: 24.0.0 Context: default Debug Mode: true diff --git a/cli/command/system/testdata/docker-info-no-swarm.json.golden b/cli/command/system/testdata/docker-info-no-swarm.json.golden index d11ef2c2db..a29f944587 100644 --- a/cli/command/system/testdata/docker-info-no-swarm.json.golden +++ b/cli/command/system/testdata/docker-info-no-swarm.json.golden @@ -1 +1 @@ -{"ID":"EKHL:QDUU:QZ7U:MKGD:VDXK:S27Q:GIPU:24B7:R7VT:DGN6:QCSF:2UBX","Containers":0,"ContainersRunning":0,"ContainersPaused":0,"ContainersStopped":0,"Images":0,"Driver":"aufs","DriverStatus":[["Root Dir","/var/lib/docker/aufs"],["Backing Filesystem","extfs"],["Dirs","0"],["Dirperm1 Supported","true"]],"Plugins":{"Volume":["local"],"Network":["bridge","host","macvlan","null","overlay"],"Authorization":null,"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","logentries","splunk","syslog"]},"MemoryLimit":true,"SwapLimit":true,"KernelMemory":true,"CpuCfsPeriod":true,"CpuCfsQuota":true,"CPUShares":true,"CPUSet":true,"PidsLimit":false,"IPv4Forwarding":true,"BridgeNfIptables":true,"BridgeNfIp6tables":true,"Debug":true,"NFd":33,"OomKillDisable":true,"NGoroutines":135,"SystemTime":"2017-08-24T17:44:34.077811894Z","LoggingDriver":"json-file","CgroupDriver":"cgroupfs","NEventsListener":0,"KernelVersion":"4.4.0-87-generic","OperatingSystem":"Ubuntu 16.04.3 LTS","OSVersion":"","OSType":"linux","Architecture":"x86_64","IndexServerAddress":"https://index.docker.io/v1/","RegistryConfig":{"AllowNondistributableArtifactsCIDRs":null,"AllowNondistributableArtifactsHostnames":null,"InsecureRegistryCIDRs":["127.0.0.0/8"],"IndexConfigs":{"docker.io":{"Name":"docker.io","Mirrors":null,"Secure":true,"Official":true}},"Mirrors":null},"NCPU":2,"MemTotal":2097356800,"GenericResources":null,"DockerRootDir":"/var/lib/docker","HttpProxy":"","HttpsProxy":"","NoProxy":"","Name":"system-sample","Labels":["provider=digitalocean"],"ExperimentalBuild":false,"ServerVersion":"17.06.1-ce","Runtimes":{"runc":{"path":"docker-runc"}},"DefaultRuntime":"runc","Swarm":{"NodeID":"","NodeAddr":"","LocalNodeState":"inactive","ControlAvailable":false,"Error":"","RemoteManagers":null},"LiveRestoreEnabled":false,"Isolation":"","InitBinary":"docker-init","ContainerdCommit":{"ID":"6e23458c129b551d5c9871e5174f6b1b7f6d1170","Expected":"6e23458c129b551d5c9871e5174f6b1b7f6d1170"},"RuncCommit":{"ID":"810190ceaa507aa2727d7ae6f4790c76ec150bd2","Expected":"810190ceaa507aa2727d7ae6f4790c76ec150bd2"},"InitCommit":{"ID":"949e6fa","Expected":"949e6fa"},"SecurityOptions":["name=apparmor","name=seccomp,profile=default"],"DefaultAddressPools":[{"Base":"10.123.0.0/16","Size":24}],"Warnings":null,"ClientInfo":{"Debug":true,"Context":"default","Plugins":[],"Warnings":null}} +{"ID":"EKHL:QDUU:QZ7U:MKGD:VDXK:S27Q:GIPU:24B7:R7VT:DGN6:QCSF:2UBX","Containers":0,"ContainersRunning":0,"ContainersPaused":0,"ContainersStopped":0,"Images":0,"Driver":"aufs","DriverStatus":[["Root Dir","/var/lib/docker/aufs"],["Backing Filesystem","extfs"],["Dirs","0"],["Dirperm1 Supported","true"]],"Plugins":{"Volume":["local"],"Network":["bridge","host","macvlan","null","overlay"],"Authorization":null,"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","logentries","splunk","syslog"]},"MemoryLimit":true,"SwapLimit":true,"KernelMemory":true,"CpuCfsPeriod":true,"CpuCfsQuota":true,"CPUShares":true,"CPUSet":true,"PidsLimit":false,"IPv4Forwarding":true,"BridgeNfIptables":true,"BridgeNfIp6tables":true,"Debug":true,"NFd":33,"OomKillDisable":true,"NGoroutines":135,"SystemTime":"2017-08-24T17:44:34.077811894Z","LoggingDriver":"json-file","CgroupDriver":"cgroupfs","NEventsListener":0,"KernelVersion":"4.4.0-87-generic","OperatingSystem":"Ubuntu 16.04.3 LTS","OSVersion":"","OSType":"linux","Architecture":"x86_64","IndexServerAddress":"https://index.docker.io/v1/","RegistryConfig":{"AllowNondistributableArtifactsCIDRs":null,"AllowNondistributableArtifactsHostnames":null,"InsecureRegistryCIDRs":["127.0.0.0/8"],"IndexConfigs":{"docker.io":{"Name":"docker.io","Mirrors":null,"Secure":true,"Official":true}},"Mirrors":null},"NCPU":2,"MemTotal":2097356800,"GenericResources":null,"DockerRootDir":"/var/lib/docker","HttpProxy":"","HttpsProxy":"","NoProxy":"","Name":"system-sample","Labels":["provider=digitalocean"],"ExperimentalBuild":false,"ServerVersion":"17.06.1-ce","Runtimes":{"runc":{"path":"docker-runc"}},"DefaultRuntime":"runc","Swarm":{"NodeID":"","NodeAddr":"","LocalNodeState":"inactive","ControlAvailable":false,"Error":"","RemoteManagers":null},"LiveRestoreEnabled":false,"Isolation":"","InitBinary":"docker-init","ContainerdCommit":{"ID":"6e23458c129b551d5c9871e5174f6b1b7f6d1170","Expected":"6e23458c129b551d5c9871e5174f6b1b7f6d1170"},"RuncCommit":{"ID":"810190ceaa507aa2727d7ae6f4790c76ec150bd2","Expected":"810190ceaa507aa2727d7ae6f4790c76ec150bd2"},"InitCommit":{"ID":"949e6fa","Expected":"949e6fa"},"SecurityOptions":["name=apparmor","name=seccomp,profile=default"],"DefaultAddressPools":[{"Base":"10.123.0.0/16","Size":24}],"Warnings":null,"ClientInfo":{"Debug":true,"Platform":{"Name":"Docker Engine - Community"},"Version":"24.0.0","Context":"default","Plugins":[],"Warnings":null}} diff --git a/cli/command/system/version.go b/cli/command/system/version.go index 712f0a934c..a84b93fe34 100644 --- a/cli/command/system/version.go +++ b/cli/command/system/version.go @@ -23,7 +23,7 @@ import ( ) const defaultVersionTemplate = `{{with .Client -}} -Client:{{if ne .Platform.Name ""}} {{.Platform.Name}}{{end}} +Client:{{if ne .Platform nil}}{{if ne .Platform.Name ""}} {{.Platform.Name}}{{end}}{{end}} Version: {{.Version}} API version: {{.APIVersion}}{{if ne .APIVersion .DefaultAPIVersion}} (downgraded from {{.DefaultAPIVersion}}){{end}} Go version: {{.GoVersion}} @@ -33,7 +33,7 @@ Client:{{if ne .Platform.Name ""}} {{.Platform.Name}}{{end}} Context: {{.Context}} {{- end}} -{{- if .ServerOK}}{{with .Server}} +{{- if ne .Server nil}}{{with .Server}} Server:{{if ne .Platform.Name ""}} {{.Platform.Name}}{{end}} {{- range $component := .Components}} @@ -66,24 +66,45 @@ type versionInfo struct { Server *types.Version } -type clientVersion struct { - Platform struct{ Name string } `json:",omitempty"` - - Version string - APIVersion string `json:"ApiVersion"` - DefaultAPIVersion string `json:"DefaultAPIVersion,omitempty"` - GitCommit string - GoVersion string - Os string - Arch string - BuildTime string `json:",omitempty"` - Context string +type platformInfo struct { + Name string `json:"Name,omitempty"` } -// ServerOK returns true when the client could connect to the docker server -// and parse the information received. It returns false otherwise. -func (v versionInfo) ServerOK() bool { - return v.Server != nil +type clientVersion struct { + Platform *platformInfo `json:"Platform,omitempty"` + Version string `json:"Version,omitempty"` + APIVersion string `json:"ApiVersion,omitempty"` + DefaultAPIVersion string `json:"DefaultAPIVersion,omitempty"` + GitCommit string `json:"GitCommit,omitempty"` + GoVersion string `json:"GoVersion,omitempty"` + Os string `json:"Os,omitempty"` + Arch string `json:"Arch,omitempty"` + BuildTime string `json:"BuildTime,omitempty"` + Context string `json:"Context"` +} + +// newClientVersion constructs a new clientVersion. If a dockerCLI is +// passed as argument, additional information is included (API version), +// which may invoke an API connection. Pass nil to omit the additional +// information. +func newClientVersion(contextName string, dockerCli command.Cli) clientVersion { + v := clientVersion{ + Version: version.Version, + GoVersion: runtime.Version(), + GitCommit: version.GitCommit, + BuildTime: reformatDate(version.BuildTime), + Os: runtime.GOOS, + Arch: arch(), + Context: contextName, + } + if version.PlatformName != "" { + v.Platform = &platformInfo{Name: version.PlatformName} + } + if dockerCli != nil { + v.APIVersion = dockerCli.CurrentVersion() + v.DefaultAPIVersion = dockerCli.DefaultVersion() + } + return v } // NewVersionCommand creates a new cobra.Command for `docker version` @@ -133,20 +154,8 @@ func runVersion(dockerCli command.Cli, opts *versionOptions) error { // TODO print error if kubernetes is used? vd := versionInfo{ - Client: clientVersion{ - Platform: struct{ Name string }{version.PlatformName}, - Version: version.Version, - APIVersion: dockerCli.CurrentVersion(), - DefaultAPIVersion: dockerCli.DefaultVersion(), - GoVersion: runtime.Version(), - GitCommit: version.GitCommit, - BuildTime: reformatDate(version.BuildTime), - Os: runtime.GOOS, - Arch: arch(), - Context: dockerCli.CurrentContext(), - }, + Client: newClientVersion(dockerCli.CurrentContext(), dockerCli), } - sv, err := dockerCli.Client().ServerVersion(context.Background()) if err == nil { vd.Server = &sv diff --git a/docs/reference/commandline/info.md b/docs/reference/commandline/info.md index d9668c995b..ead61c62f3 100644 --- a/docs/reference/commandline/info.md +++ b/docs/reference/commandline/info.md @@ -47,7 +47,8 @@ information about the `overlay2` storage driver is shown: ```console $ docker info -Client: +Client: Docker Engine - Community + Version: 24.0.0 Context: default Debug Mode: false Plugins: @@ -126,7 +127,8 @@ Here is a sample output for a daemon running on Windows Server: ```console C:\> docker info -Client: +Client: Docker Engine - Community + Version: 24.0.0 Context: default Debug Mode: false Plugins: diff --git a/man/src/system/info.md b/man/src/system/info.md index a4d4bbb978..ad8ce91d2c 100644 --- a/man/src/system/info.md +++ b/man/src/system/info.md @@ -27,7 +27,8 @@ information about the `overlay2` storage driver is shown: ```console $ docker info -Client: +Client: Docker Engine - Community + Version: 24.0.0 Context: default Debug Mode: false Plugins: