mirror of
https://github.com/docker/cli.git
synced 2026-01-26 15:41:42 +03:00
cli/command/system: define struct for formatting version
The client.ServerVersion method in the moby/client module defines an output struct that's separate from the API response. These output structs are not designed to be marshaled as JSON, but the CLI depended on them defining `json` labels, which it used to format the output as JSON (`docker version --format=json`); as a result, the JSON output changed in docker v29, as it would now use the naming based on the Go struct's fields (`APIVersion` instead of `ApiVersion`). In future, we should consider having a `--raw` (or similar) option for the CLI to print API responses as-is, instead of using client structs or CLI structs for this (this would also make sure the JSON output does not inherit client-side formatting of fields). For now, let's create a struct for formatting the output, similar to what we do for the client-side information. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
@@ -1 +1 @@
|
|||||||
{"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"},"Version":"","APIVersion":"","MinAPIVersion":"","Os":"","Arch":"","Experimental":false,"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"}}]}}
|
{"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"},"Version":"18.99.5-ce","ApiVersion":"1.30","MinAPIVersion":"1.12","Os":"linux","Arch":"amd64","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"}}],"GitCommit":"64ddfa6","GoVersion":"go1.8.7","KernelVersion":"v1.0.0","BuildTime":"Mon Jul 9 23:38:38 2018"}}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"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"},"Version":"","APIVersion":"","MinAPIVersion":"","Os":"","Arch":"","Experimental":false,"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"}}]}}
|
{"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"},"Version":"18.99.5-ce","ApiVersion":"1.30","MinAPIVersion":"1.12","Os":"linux","Arch":"amd64","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"}}],"GitCommit":"64ddfa6","GoVersion":"go1.8.7","KernelVersion":"v1.0.0","BuildTime":"Mon Jul 9 23:38:38 2018"}}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sort"
|
"sort"
|
||||||
|
"strconv"
|
||||||
"text/template"
|
"text/template"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -63,7 +64,7 @@ type versionOptions struct {
|
|||||||
// versionInfo contains version information of both the Client, and Server
|
// versionInfo contains version information of both the Client, and Server
|
||||||
type versionInfo struct {
|
type versionInfo struct {
|
||||||
Client clientVersion
|
Client clientVersion
|
||||||
Server *client.ServerVersionResult
|
Server *serverVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
type platformInfo struct {
|
type platformInfo struct {
|
||||||
@@ -83,6 +84,26 @@ type clientVersion struct {
|
|||||||
Context string `json:"Context"`
|
Context string `json:"Context"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// serverVersion contains information about the Docker server host.
|
||||||
|
// it's the client-side presentation of [client.ServerVersionResult].
|
||||||
|
type serverVersion struct {
|
||||||
|
Platform client.PlatformInfo `json:",omitempty"` // Platform is the platform (product name) the server is running on.
|
||||||
|
Version string `json:"Version"` // Version is the version of the daemon.
|
||||||
|
APIVersion string `json:"ApiVersion"` // APIVersion is the highest API version supported by the server.
|
||||||
|
MinAPIVersion string `json:"MinAPIVersion,omitempty"` // MinAPIVersion is the minimum API version the server supports.
|
||||||
|
Os string `json:"Os"` // Os is the operating system the server runs on.
|
||||||
|
Arch string `json:"Arch"` // Arch is the hardware architecture the server runs on.
|
||||||
|
Components []system.ComponentVersion `json:"Components,omitempty"` // Components contains version information for the components making up the server.
|
||||||
|
|
||||||
|
// The following fields are deprecated, they relate to the Engine component and are kept for backwards compatibility
|
||||||
|
|
||||||
|
GitCommit string `json:"GitCommit,omitempty"`
|
||||||
|
GoVersion string `json:"GoVersion,omitempty"`
|
||||||
|
KernelVersion string `json:"KernelVersion,omitempty"`
|
||||||
|
Experimental bool `json:"Experimental,omitempty"`
|
||||||
|
BuildTime string `json:"BuildTime,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
// newClientVersion constructs a new clientVersion. If a dockerCLI is
|
// newClientVersion constructs a new clientVersion. If a dockerCLI is
|
||||||
// passed as argument, additional information is included (API version),
|
// passed as argument, additional information is included (API version),
|
||||||
// which may invoke an API connection. Pass nil to omit the additional
|
// which may invoke an API connection. Pass nil to omit the additional
|
||||||
@@ -107,6 +128,47 @@ func newClientVersion(contextName string, dockerCli command.Cli) clientVersion {
|
|||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newServerVersion(sv client.ServerVersionResult) *serverVersion {
|
||||||
|
out := &serverVersion{
|
||||||
|
Platform: sv.Platform,
|
||||||
|
Version: sv.Version,
|
||||||
|
APIVersion: sv.APIVersion,
|
||||||
|
MinAPIVersion: sv.MinAPIVersion,
|
||||||
|
Os: sv.Os,
|
||||||
|
Arch: sv.Arch,
|
||||||
|
Experimental: sv.Experimental, //nolint:staticcheck // ignore deprecated field.
|
||||||
|
}
|
||||||
|
foundEngine := false
|
||||||
|
for _, component := range sv.Components {
|
||||||
|
if component.Name == "Engine" {
|
||||||
|
foundEngine = true
|
||||||
|
buildTime, ok := component.Details["BuildTime"]
|
||||||
|
if ok {
|
||||||
|
component.Details["BuildTime"] = reformatDate(buildTime)
|
||||||
|
}
|
||||||
|
out.GitCommit = component.Details["GitCommit"]
|
||||||
|
out.GoVersion = component.Details["GoVersion"]
|
||||||
|
out.KernelVersion = component.Details["KernelVersion"]
|
||||||
|
out.Experimental = func() bool { b, _ := strconv.ParseBool(component.Details["Experimental"]); return b }()
|
||||||
|
out.BuildTime = reformatDate(component.Details["BuildTime"])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !foundEngine {
|
||||||
|
out.Components = append(out.Components, system.ComponentVersion{
|
||||||
|
Name: "Engine",
|
||||||
|
Version: sv.Version,
|
||||||
|
Details: map[string]string{
|
||||||
|
"ApiVersion": sv.APIVersion,
|
||||||
|
"MinAPIVersion": sv.MinAPIVersion,
|
||||||
|
"Os": sv.Os,
|
||||||
|
"Arch": sv.Arch,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// newVersionCommand creates a new cobra.Command for `docker version`
|
// newVersionCommand creates a new cobra.Command for `docker version`
|
||||||
func newVersionCommand(dockerCLI command.Cli) *cobra.Command {
|
func newVersionCommand(dockerCLI command.Cli) *cobra.Command {
|
||||||
var opts versionOptions
|
var opts versionOptions
|
||||||
@@ -138,14 +200,14 @@ func reformatDate(buildTime string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func arch() string {
|
func arch() string {
|
||||||
arch := runtime.GOARCH
|
out := runtime.GOARCH
|
||||||
if rosetta.Enabled() {
|
if rosetta.Enabled() {
|
||||||
arch += " (rosetta)"
|
out += " (rosetta)"
|
||||||
}
|
}
|
||||||
return arch
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
func runVersion(ctx context.Context, dockerCli command.Cli, opts *versionOptions) error {
|
func runVersion(ctx context.Context, dockerCLI command.Cli, opts *versionOptions) error {
|
||||||
var err error
|
var err error
|
||||||
tmpl, err := newVersionTemplate(opts.format)
|
tmpl, err := newVersionTemplate(opts.format)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -153,36 +215,13 @@ func runVersion(ctx context.Context, dockerCli command.Cli, opts *versionOptions
|
|||||||
}
|
}
|
||||||
|
|
||||||
vd := versionInfo{
|
vd := versionInfo{
|
||||||
Client: newClientVersion(dockerCli.CurrentContext(), dockerCli),
|
Client: newClientVersion(dockerCLI.CurrentContext(), dockerCLI),
|
||||||
}
|
}
|
||||||
sv, err := dockerCli.Client().ServerVersion(ctx, client.ServerVersionOptions{})
|
sv, err := dockerCLI.Client().ServerVersion(ctx, client.ServerVersionOptions{})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
vd.Server = &sv
|
vd.Server = newServerVersion(sv)
|
||||||
foundEngine := false
|
|
||||||
for _, component := range sv.Components {
|
|
||||||
if component.Name == "Engine" {
|
|
||||||
foundEngine = true
|
|
||||||
buildTime, ok := component.Details["BuildTime"]
|
|
||||||
if ok {
|
|
||||||
component.Details["BuildTime"] = reformatDate(buildTime)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !foundEngine {
|
|
||||||
vd.Server.Components = append(vd.Server.Components, system.ComponentVersion{
|
|
||||||
Name: "Engine",
|
|
||||||
Version: sv.Version,
|
|
||||||
Details: map[string]string{
|
|
||||||
"ApiVersion": sv.APIVersion,
|
|
||||||
"MinAPIVersion": sv.MinAPIVersion,
|
|
||||||
"Os": sv.Os,
|
|
||||||
"Arch": sv.Arch,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if err2 := prettyPrintVersion(dockerCli.Out(), vd, tmpl); err2 != nil && err == nil {
|
if err2 := prettyPrintVersion(dockerCLI.Out(), vd, tmpl); err2 != nil && err == nil {
|
||||||
err = err2
|
err = err2
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -47,8 +47,18 @@ func TestVersionFormat(t *testing.T) {
|
|||||||
BuildTime: "Wed May 30 22:21:05 2018",
|
BuildTime: "Wed May 30 22:21:05 2018",
|
||||||
Context: "my-context",
|
Context: "my-context",
|
||||||
},
|
},
|
||||||
Server: &client.ServerVersionResult{
|
Server: &serverVersion{
|
||||||
Platform: client.PlatformInfo{Name: "Docker Enterprise Edition (EE) 2.0"},
|
Platform: client.PlatformInfo{Name: "Docker Enterprise Edition (EE) 2.0"},
|
||||||
|
Version: "18.99.5-ce",
|
||||||
|
APIVersion: "1.30",
|
||||||
|
MinAPIVersion: "1.12",
|
||||||
|
Os: "linux",
|
||||||
|
Arch: "amd64",
|
||||||
|
GitCommit: "64ddfa6",
|
||||||
|
GoVersion: "go1.8.7",
|
||||||
|
KernelVersion: "v1.0.0",
|
||||||
|
Experimental: false,
|
||||||
|
BuildTime: "Mon Jul 9 23:38:38 2018",
|
||||||
Components: []system.ComponentVersion{
|
Components: []system.ComponentVersion{
|
||||||
{
|
{
|
||||||
Name: "Engine",
|
Name: "Engine",
|
||||||
|
|||||||
Reference in New Issue
Block a user