version.go 3.1 KB

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