version.go 2.8 KB

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