소스 검색

Implement docker version with standalone client lib.

Use Go template definitions for default format.

Signed-off-by: David Calavera <david.calavera@gmail.com>
David Calavera 9 년 전
부모
커밋
1fe912151b
2개의 변경된 파일66개의 추가작업 그리고 51개의 파일을 삭제
  1. 50 0
      api/client/lib/version.go
  2. 16 51
      api/client/version.go

+ 50 - 0
api/client/lib/version.go

@@ -0,0 +1,50 @@
+package lib
+
+import (
+	"encoding/json"
+	"runtime"
+
+	"github.com/docker/docker/api"
+	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/dockerversion"
+	"github.com/docker/docker/utils"
+)
+
+// VersionResponse holds version information for the client and the server
+type VersionResponse struct {
+	Client *types.Version
+	Server *types.Version
+}
+
+// ServerOK return true when the client could connect to the docker server
+// and parse the information received. It returns false otherwise.
+func (v VersionResponse) ServerOK() bool {
+	return v.Server == nil
+}
+
+// SystemVersion returns information of the docker client and server host.
+func (cli *Client) SystemVersion() (VersionResponse, error) {
+	client := &types.Version{
+		Version:      dockerversion.Version,
+		APIVersion:   api.Version,
+		GoVersion:    runtime.Version(),
+		GitCommit:    dockerversion.GitCommit,
+		BuildTime:    dockerversion.BuildTime,
+		Os:           runtime.GOOS,
+		Arch:         runtime.GOARCH,
+		Experimental: utils.ExperimentalBuild(),
+	}
+
+	resp, err := cli.GET("/version", nil, nil)
+	if err != nil {
+		return VersionResponse{Client: client}, err
+	}
+	defer ensureReaderClosed(resp)
+
+	var server types.Version
+	err = json.NewDecoder(resp.body).Decode(&server)
+	if err != nil {
+		return VersionResponse{Client: client}, err
+	}
+	return types.VersionResponse{Client: client, Server: &server}, nil
+}

+ 16 - 51
api/client/version.go

@@ -1,17 +1,11 @@
 package client
 
 import (
-	"encoding/json"
-	"runtime"
 	"text/template"
 	"time"
 
-	"github.com/docker/docker/api"
-	"github.com/docker/docker/api/types"
 	Cli "github.com/docker/docker/cli"
-	"github.com/docker/docker/dockerversion"
 	flag "github.com/docker/docker/pkg/mflag"
-	"github.com/docker/docker/utils"
 )
 
 var versionTemplate = `Client:
@@ -32,12 +26,6 @@ Server:
  OS/Arch:      {{.Server.Os}}/{{.Server.Arch}}{{if .Server.Experimental}}
  Experimental: {{.Server.Experimental}}{{end}}{{end}}`
 
-type versionData struct {
-	Client   types.Version
-	ServerOK bool
-	Server   types.Version
-}
-
 // 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.
@@ -49,59 +37,36 @@ func (cli *DockerCli) CmdVersion(args ...string) (err error) {
 	cmd.Require(flag.Exact, 0)
 
 	cmd.ParseFlags(args, true)
-	if *tmplStr == "" {
-		*tmplStr = versionTemplate
+
+	templateFormat := versionTemplate
+	if *tmplStr != "" {
+		templateFormat = *tmplStr
 	}
 
 	var tmpl *template.Template
-	if tmpl, err = template.New("").Funcs(funcMap).Parse(*tmplStr); err != nil {
+	if tmpl, err = template.New("").Funcs(funcMap).Parse(templateFormat); err != nil {
 		return Cli.StatusError{StatusCode: 64,
 			Status: "Template parsing error: " + err.Error()}
 	}
 
-	vd := versionData{
-		Client: types.Version{
-			Version:      dockerversion.Version,
-			APIVersion:   api.Version,
-			GoVersion:    runtime.Version(),
-			GitCommit:    dockerversion.GitCommit,
-			BuildTime:    dockerversion.BuildTime,
-			Os:           runtime.GOOS,
-			Arch:         runtime.GOARCH,
-			Experimental: utils.ExperimentalBuild(),
-		},
+	vd, err := cli.client.SystemVersion()
+
+	// 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)
 	}
 
-	defer func() {
-		// 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'})
-	}()
-
-	serverResp, err := cli.call("GET", "/version", nil, nil)
-	if err != nil {
-		return err
 	}
 
-	defer serverResp.body.Close()
-
-	if err = json.NewDecoder(serverResp.body).Decode(&vd.Server); err != nil {
-		return Cli.StatusError{StatusCode: 1,
-			Status: "Error reading remote version: " + err.Error()}
+	if err2 := tmpl.Execute(cli.out, vd); err2 != nil && err == nil {
+		err = err2
 	}
-
-	vd.ServerOK = true
-
-	return
+	cli.out.Write([]byte{'\n'})
+	return err
 }