diff --git a/cli/command/system/version.go b/cli/command/system/version.go index 9cca599fe3..d063045d5c 100644 --- a/cli/command/system/version.go +++ b/cli/command/system/version.go @@ -1,34 +1,52 @@ package system import ( + "fmt" "runtime" + "sort" + "text/template" "time" - "golang.org/x/net/context" - "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" "github.com/docker/cli/templates" "github.com/docker/docker/api/types" "github.com/spf13/cobra" + "golang.org/x/net/context" ) -var versionTemplate = `Client: - Version: {{.Client.Version}} - API version: {{.Client.APIVersion}}{{if ne .Client.APIVersion .Client.DefaultAPIVersion}} (downgraded from {{.Client.DefaultAPIVersion}}){{end}} - Go version: {{.Client.GoVersion}} - Git commit: {{.Client.GitCommit}} - Built: {{.Client.BuildTime}} - OS/Arch: {{.Client.Os}}/{{.Client.Arch}}{{if .ServerOK}} +var versionTemplate = `{{with .Client -}} +Client:{{if ne .Platform.Name ""}} {{.Platform.Name}}{{end}} + Version: {{.Version}} + API version: {{.APIVersion}}{{if ne .APIVersion .DefaultAPIVersion}} (downgraded from {{.DefaultAPIVersion}}){{end}} + Go version: {{.GoVersion}} + Git commit: {{.GitCommit}} + Built: {{.BuildTime}} + OS/Arch: {{.Os}}/{{.Arch}} +{{- end}} -Server: - Version: {{.Server.Version}} - API version: {{.Server.APIVersion}} (minimum version {{.Server.MinAPIVersion}}) - Go version: {{.Server.GoVersion}} - Git commit: {{.Server.GitCommit}} - Built: {{.Server.BuildTime}} - OS/Arch: {{.Server.Os}}/{{.Server.Arch}} - Experimental: {{.Server.Experimental}}{{end}}` +{{- if .ServerOK}}{{with .Server}} + +Server:{{if ne .Platform.Name ""}} {{.Platform.Name}}{{end}} + {{- range $component := .Components}} + {{$component.Name}}: + {{- if eq $component.Name "Engine" }} + Version: {{.Version}} + API version: {{index .Details "ApiVersion"}} (minimum version {{index .Details "MinAPIVersion"}}) + Go version: {{index .Details "GoVersion"}} + Git commit: {{index .Details "GitCommit"}} + Built: {{index .Details "BuildTime"}} + OS/Arch: {{index .Details "Os"}}/{{index .Details "Arch"}} + Experimental: {{index .Details "Experimental"}} + {{- else }} + Version: {{$component.Version}} + {{- $detailsOrder := getDetailsOrder $component}} + {{- range $key := $detailsOrder}} + {{$key}}: {{index $component.Details $key}} + {{- end}} + {{- end}} + {{- end}} +{{- end}}{{end}}` type versionOptions struct { format string @@ -41,6 +59,8 @@ type versionInfo struct { } type clientVersion struct { + Platform struct{ Name string } `json:",omitempty"` + Version string APIVersion string `json:"ApiVersion"` DefaultAPIVersion string `json:"DefaultAPIVersion,omitempty"` @@ -77,15 +97,27 @@ func NewVersionCommand(dockerCli *command.DockerCli) *cobra.Command { return cmd } +func reformatDate(buildTime string) string { + t, errTime := time.Parse(time.RFC3339Nano, buildTime) + if errTime == nil { + return t.Format(time.ANSIC) + } + return buildTime +} + func runVersion(dockerCli *command.DockerCli, opts *versionOptions) error { ctx := context.Background() templateFormat := versionTemplate + tmpl := templates.New("version") if opts.format != "" { templateFormat = opts.format + } else { + tmpl = tmpl.Funcs(template.FuncMap{"getDetailsOrder": getDetailsOrder}) } - tmpl, err := templates.Parse(templateFormat) + var err error + tmpl, err = tmpl.Parse(templateFormat) if err != nil { return cli.StatusError{StatusCode: 64, Status: "Template parsing error: " + err.Error()} @@ -103,22 +135,41 @@ func runVersion(dockerCli *command.DockerCli, opts *versionOptions) error { Arch: runtime.GOARCH, }, } - - serverVersion, err := dockerCli.Client().ServerVersion(ctx) - if err == nil { - vd.Server = &serverVersion - } + vd.Client.Platform.Name = cli.PlatformName // first we need to make BuildTime more human friendly - t, errTime := time.Parse(time.RFC3339Nano, vd.Client.BuildTime) - if errTime == nil { - vd.Client.BuildTime = t.Format(time.ANSIC) - } + vd.Client.BuildTime = reformatDate(vd.Client.BuildTime) - if vd.ServerOK() { - t, errTime = time.Parse(time.RFC3339Nano, vd.Server.BuildTime) - if errTime == nil { - vd.Server.BuildTime = t.Format(time.ANSIC) + sv, err := dockerCli.Client().ServerVersion(ctx) + if err == nil { + vd.Server = &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) + } + break + } + } + + if !foundEngine { + vd.Server.Components = append(vd.Server.Components, types.ComponentVersion{ + Name: "Engine", + Version: sv.Version, + Details: map[string]string{ + "ApiVersion": sv.APIVersion, + "MinAPIVersion": sv.MinAPIVersion, + "GitCommit": sv.GitCommit, + "GoVersion": sv.GoVersion, + "Os": sv.Os, + "Arch": sv.Arch, + "BuildTime": reformatDate(vd.Server.BuildTime), + "Experimental": fmt.Sprintf("%t", sv.Experimental), + }, + }) } } @@ -128,3 +179,12 @@ func runVersion(dockerCli *command.DockerCli, opts *versionOptions) error { dockerCli.Out().Write([]byte{'\n'}) return err } + +func getDetailsOrder(v types.ComponentVersion) []string { + out := make([]string, 0, len(v.Details)) + for k := range v.Details { + out = append(out, k) + } + sort.Strings(out) + return out +} diff --git a/cli/version.go b/cli/version.go index bff7ab49ef..91c9ae1878 100644 --- a/cli/version.go +++ b/cli/version.go @@ -3,7 +3,8 @@ package cli // Default build-time variable. // These values are overriding via ldflags var ( - Version = "unknown-version" - GitCommit = "unknown-commit" - BuildTime = "unknown-buildtime" + PlatformName = "" + Version = "unknown-version" + GitCommit = "unknown-commit" + BuildTime = "unknown-buildtime" ) diff --git a/docker.Makefile b/docker.Makefile index f3f9afed4e..04ce309636 100644 --- a/docker.Makefile +++ b/docker.Makefile @@ -10,7 +10,7 @@ CROSS_IMAGE_NAME = docker-cli-cross$(IMAGE_TAG) VALIDATE_IMAGE_NAME = docker-cli-shell-validate$(IMAGE_TAG) MOUNTS = -v "$(CURDIR)":/go/src/github.com/docker/cli VERSION = $(shell cat VERSION) -ENVVARS = -e VERSION=$(VERSION) -e GITCOMMIT +ENVVARS = -e VERSION=$(VERSION) -e GITCOMMIT -e PLATFORM # build docker image (dockerfiles/Dockerfile.build) .PHONY: build_docker_image diff --git a/scripts/build/.variables b/scripts/build/.variables index eb87c38268..208f44c316 100755 --- a/scripts/build/.variables +++ b/scripts/build/.variables @@ -1,15 +1,22 @@ #!/usr/bin/env bash set -eu +PLATFORM=${PLATFORM:-} VERSION=${VERSION:-"unknown-version"} GITCOMMIT=${GITCOMMIT:-$(git rev-parse --short HEAD 2> /dev/null || true)} BUILDTIME=${BUILDTIME:-$(date --utc --rfc-3339 ns 2> /dev/null | sed -e 's/ /T/')} +PLATFORM_LDFLAGS= +if test -n "${PLATFORM}"; then + PLATFORM_LDFLAGS="-X \"github.com/docker/cli/cli.PlatformName=${PLATFORM}\"" +fi + export LDFLAGS="\ -w \ - -X github.com/docker/cli/cli.GitCommit=${GITCOMMIT} \ - -X github.com/docker/cli/cli.BuildTime=${BUILDTIME} \ - -X github.com/docker/cli/cli.Version=${VERSION} \ + ${PLATFORM_LDFLAGS} \ + -X \"github.com/docker/cli/cli.GitCommit=${GITCOMMIT}\" \ + -X \"github.com/docker/cli/cli.BuildTime=${BUILDTIME}\" \ + -X \"github.com/docker/cli/cli.Version=${VERSION}\" \ ${LDFLAGS:-} \ " diff --git a/templates/templates.go b/templates/templates.go index 80cab5ed34..6cc2ec3608 100644 --- a/templates/templates.go +++ b/templates/templates.go @@ -55,10 +55,16 @@ func Parse(format string) (*template.Template, error) { return NewParse("", format) } +// New creates a new empty template with the provided tag and built-in +// template functions. +func New(tag string) *template.Template { + return template.New(tag).Funcs(basicFunctions) +} + // NewParse creates a new tagged template with the basic functions // and parses the given format. func NewParse(tag, format string) (*template.Template, error) { - return template.New(tag).Funcs(basicFunctions).Parse(format) + return New(tag).Parse(format) } // padWithSpace adds whitespace to the input if the input is non-empty diff --git a/vendor.conf b/vendor.conf index 7a9c71d273..16c496d944 100755 --- a/vendor.conf +++ b/vendor.conf @@ -5,7 +5,7 @@ github.com/coreos/etcd v3.2.1 github.com/cpuguy83/go-md2man a65d4d2de4d5f7c74868dfa9b202a3c8be315aaa github.com/davecgh/go-spew 346938d642f2ec3594ed81d874461961cd0faa76 github.com/docker/distribution edc3ab29cdff8694dd6feb85cfeb4b5f1b38ed9c -github.com/docker/docker 5e5fadb3c0201553929d4a6ea8dc8f9d8a1e56fe +github.com/docker/docker a1be987ea9e03e5ebdb1b415a7acdd8d6f0aaa08 github.com/docker/docker-credential-helpers 3c90bd29a46b943b2a9842987b58fb91a7c1819b # the docker/go package contains a customized version of canonical/json diff --git a/vendor/github.com/docker/docker/api/types/types.go b/vendor/github.com/docker/docker/api/types/types.go index f7ac772971..7814e6b934 100644 --- a/vendor/github.com/docker/docker/api/types/types.go +++ b/vendor/github.com/docker/docker/api/types/types.go @@ -107,9 +107,21 @@ type Ping struct { Experimental bool } +// ComponentVersion describes the version information for a specific component. +type ComponentVersion struct { + Name string + Version string + Details map[string]string `json:",omitempty"` +} + // Version contains response of Engine API: // GET "/version" type Version struct { + Platform struct{ Name string } `json:",omitempty"` + Components []ComponentVersion `json:",omitempty"` + + // The following fields are deprecated, they relate to the Engine component and are kept for backwards compatibility + Version string APIVersion string `json:"ApiVersion"` MinAPIVersion string `json:"MinAPIVersion,omitempty"` diff --git a/vendor/github.com/docker/docker/vendor.conf b/vendor/github.com/docker/docker/vendor.conf index 120dd9d378..8c0b15a75f 100644 --- a/vendor/github.com/docker/docker/vendor.conf +++ b/vendor/github.com/docker/docker/vendor.conf @@ -30,7 +30,7 @@ github.com/moby/buildkit aaff9d591ef128560018433fe61beb802e149de8 github.com/tonistiigi/fsutil dea3a0da73aee887fc02142d995be764106ac5e2 #get libnetwork packages -github.com/docker/libnetwork 64ae58878fc8f95e4a167499d654e13fa36abdc7 +github.com/docker/libnetwork 9bca9a4a220b158cc94402e0f8c2c7714eb6f503 github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9 github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80 github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec @@ -42,7 +42,7 @@ github.com/hashicorp/go-multierror fcdddc395df1ddf4247c69bd436e84cfa0733f7e github.com/hashicorp/serf 598c54895cc5a7b1a24a398d635e8c0ea0959870 github.com/docker/libkv 1d8431073ae03cdaedb198a89722f3aab6d418ef github.com/vishvananda/netns 604eaf189ee867d8c147fafc28def2394e878d25 -github.com/vishvananda/netlink bd6d5de5ccef2d66b0a26177928d0d8895d7f969 +github.com/vishvananda/netlink b2de5d10e38ecce8607e6b438b6d174f389a004e github.com/BurntSushi/toml f706d00e3de6abe700c994cdd545a1a4915af060 github.com/samuel/go-zookeeper d0e0d8e11f318e000a8cc434616d69e329edc374 github.com/deckarep/golang-set ef32fa3046d9f249d399f98ebaf9be944430fd1d