| package system |
| |
| import ( |
| "fmt" |
| "runtime" |
| "time" |
| |
| "golang.org/x/net/context" |
| |
| "github.com/docker/docker/api/types" |
| "github.com/docker/docker/cli" |
| "github.com/docker/docker/cli/command" |
| "github.com/docker/docker/dockerversion" |
| "github.com/docker/docker/utils/templates" |
| "github.com/spf13/cobra" |
| ) |
| |
| var versionTemplate = `Client: |
| Version: {{.Client.Version}} |
| API version: {{.Client.APIVersion}} |
| Go version: {{.Client.GoVersion}} |
| Git commit: {{.Client.GitCommit}} |
| Built: {{.Client.BuildTime}} |
| OS/Arch: {{.Client.Os}}/{{.Client.Arch}}{{if .ServerOK}} |
| |
| 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}}` |
| |
| type versionOptions struct { |
| format string |
| } |
| |
| // NewVersionCommand creates a new cobra.Command for `docker version` |
| func NewVersionCommand(dockerCli *command.DockerCli) *cobra.Command { |
| var opts versionOptions |
| |
| cmd := &cobra.Command{ |
| Use: "version [OPTIONS]", |
| Short: "Show the Docker version information", |
| Args: cli.NoArgs, |
| RunE: func(cmd *cobra.Command, args []string) error { |
| return runVersion(dockerCli, &opts) |
| }, |
| } |
| |
| flags := cmd.Flags() |
| |
| flags.StringVarP(&opts.format, "format", "f", "", "Format the output using the given Go template") |
| |
| return cmd |
| } |
| |
| func runVersion(dockerCli *command.DockerCli, opts *versionOptions) error { |
| ctx := context.Background() |
| |
| templateFormat := versionTemplate |
| if opts.format != "" { |
| templateFormat = opts.format |
| } |
| |
| tmpl, err := templates.Parse(templateFormat) |
| if err != nil { |
| return cli.StatusError{StatusCode: 64, |
| Status: "Template parsing error: " + err.Error()} |
| } |
| |
| APIVersion := dockerCli.Client().ClientVersion() |
| if defaultAPIVersion := dockerCli.DefaultVersion(); APIVersion != defaultAPIVersion { |
| APIVersion = fmt.Sprintf("%s (downgraded from %s)", APIVersion, defaultAPIVersion) |
| } |
| |
| vd := types.VersionResponse{ |
| Client: &types.Version{ |
| Version: dockerversion.Version, |
| APIVersion: APIVersion, |
| GoVersion: runtime.Version(), |
| GitCommit: dockerversion.GitCommit, |
| BuildTime: dockerversion.BuildTime, |
| Os: runtime.GOOS, |
| Arch: runtime.GOARCH, |
| }, |
| } |
| |
| serverVersion, err := dockerCli.Client().ServerVersion(ctx) |
| if err == nil { |
| vd.Server = &serverVersion |
| } |
| |
| // 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) |
| } |
| |
| if vd.ServerOK() { |
| t, errTime = time.Parse(time.RFC3339Nano, vd.Server.BuildTime) |
| if errTime == nil { |
| vd.Server.BuildTime = t.Format(time.ANSIC) |
| } |
| } |
| |
| if err2 := tmpl.Execute(dockerCli.Out(), vd); err2 != nil && err == nil { |
| err = err2 |
| } |
| dockerCli.Out().Write([]byte{'\n'}) |
| return err |
| } |