// CmdVersion shows Docker version information. // // Available version information is shown for: client Docker version, client API version, client Go version, client Git commit, client OS/Arch, server Docker version, server API version, server Go version, server Git commit, and server OS/Arch. // // Usage: docker version func (cli *DockerCli) CmdVersion(args ...string) (err error) { cmd := Cli.Subcmd("version", nil, Cli.DockerCommands["version"].Description, true) tmplStr := cmd.String([]string{"f", "#format", "-format"}, "", "Format the output using the given go template") cmd.Require(flag.Exact, 0) cmd.ParseFlags(args, true) templateFormat := versionTemplate if *tmplStr != "" { templateFormat = *tmplStr } var tmpl *template.Template if tmpl, err = template.New("").Funcs(funcMap).Parse(templateFormat); err != nil { return Cli.StatusError{StatusCode: 64, Status: "Template parsing error: " + err.Error()} } vd := types.VersionResponse{ Client: &types.Version{ Version: dockerversion.Version, APIVersion: version.Version(cli.client.ClientVersion()), GoVersion: runtime.Version(), GitCommit: dockerversion.GitCommit, BuildTime: dockerversion.BuildTime, Os: runtime.GOOS, Arch: runtime.GOARCH, Experimental: utils.ExperimentalBuild(), }, } serverVersion, err := cli.client.ServerVersion() 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(cli.out, vd); err2 != nil && err == nil { err = err2 } cli.out.Write([]byte{'\n'}) return err }
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 }