version.go 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. package client
  2. import (
  3. "runtime"
  4. "text/template"
  5. "time"
  6. Cli "github.com/docker/docker/cli"
  7. "github.com/docker/docker/dockerversion"
  8. flag "github.com/docker/docker/pkg/mflag"
  9. "github.com/docker/docker/utils"
  10. "github.com/docker/engine-api/types"
  11. )
  12. var versionTemplate = `Client:
  13. Version: {{.Client.Version}}
  14. API version: {{.Client.APIVersion}}
  15. Go version: {{.Client.GoVersion}}
  16. Git commit: {{.Client.GitCommit}}
  17. Built: {{.Client.BuildTime}}
  18. OS/Arch: {{.Client.Os}}/{{.Client.Arch}}{{if .Client.Experimental}}
  19. Experimental: {{.Client.Experimental}}{{end}}{{if .ServerOK}}
  20. Server:
  21. Version: {{.Server.Version}}
  22. API version: {{.Server.APIVersion}}
  23. Go version: {{.Server.GoVersion}}
  24. Git commit: {{.Server.GitCommit}}
  25. Built: {{.Server.BuildTime}}
  26. OS/Arch: {{.Server.Os}}/{{.Server.Arch}}{{if .Server.Experimental}}
  27. Experimental: {{.Server.Experimental}}{{end}}{{end}}`
  28. // CmdVersion shows Docker version information.
  29. //
  30. // 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.
  31. //
  32. // Usage: docker version
  33. func (cli *DockerCli) CmdVersion(args ...string) (err error) {
  34. cmd := Cli.Subcmd("version", nil, Cli.DockerCommands["version"].Description, true)
  35. tmplStr := cmd.String([]string{"f", "#format", "-format"}, "", "Format the output using the given go template")
  36. cmd.Require(flag.Exact, 0)
  37. cmd.ParseFlags(args, true)
  38. templateFormat := versionTemplate
  39. if *tmplStr != "" {
  40. templateFormat = *tmplStr
  41. }
  42. var tmpl *template.Template
  43. if tmpl, err = template.New("").Funcs(funcMap).Parse(templateFormat); err != nil {
  44. return Cli.StatusError{StatusCode: 64,
  45. Status: "Template parsing error: " + err.Error()}
  46. }
  47. vd := types.VersionResponse{
  48. Client: &types.Version{
  49. Version: dockerversion.Version,
  50. APIVersion: cli.client.ClientVersion(),
  51. GoVersion: runtime.Version(),
  52. GitCommit: dockerversion.GitCommit,
  53. BuildTime: dockerversion.BuildTime,
  54. Os: runtime.GOOS,
  55. Arch: runtime.GOARCH,
  56. Experimental: utils.ExperimentalBuild(),
  57. },
  58. }
  59. serverVersion, err := cli.client.ServerVersion()
  60. if err == nil {
  61. vd.Server = &serverVersion
  62. }
  63. // first we need to make BuildTime more human friendly
  64. t, errTime := time.Parse(time.RFC3339Nano, vd.Client.BuildTime)
  65. if errTime == nil {
  66. vd.Client.BuildTime = t.Format(time.ANSIC)
  67. }
  68. if vd.ServerOK() {
  69. t, errTime = time.Parse(time.RFC3339Nano, vd.Server.BuildTime)
  70. if errTime == nil {
  71. vd.Server.BuildTime = t.Format(time.ANSIC)
  72. }
  73. }
  74. if err2 := tmpl.Execute(cli.out, vd); err2 != nil && err == nil {
  75. err = err2
  76. }
  77. cli.out.Write([]byte{'\n'})
  78. return err
  79. }