github.com/sld880311/docker@v0.0.0-20200524143708-d5593973a475/cli/command/system/version.go (about)

     1  package system
     2  
     3  import (
     4  	"fmt"
     5  	"runtime"
     6  	"time"
     7  
     8  	"golang.org/x/net/context"
     9  
    10  	"github.com/docker/docker/api/types"
    11  	"github.com/docker/docker/cli"
    12  	"github.com/docker/docker/cli/command"
    13  	"github.com/docker/docker/dockerversion"
    14  	"github.com/docker/docker/utils/templates"
    15  	"github.com/spf13/cobra"
    16  )
    17  
    18  var versionTemplate = `Client:
    19   Version:      {{.Client.Version}}
    20   API version:  {{.Client.APIVersion}}
    21   Go version:   {{.Client.GoVersion}}
    22   Git commit:   {{.Client.GitCommit}}
    23   Built:        {{.Client.BuildTime}}
    24   OS/Arch:      {{.Client.Os}}/{{.Client.Arch}}{{if .ServerOK}}
    25  
    26  Server:
    27   Version:      {{.Server.Version}}
    28   API version:  {{.Server.APIVersion}} (minimum version {{.Server.MinAPIVersion}})
    29   Go version:   {{.Server.GoVersion}}
    30   Git commit:   {{.Server.GitCommit}}
    31   Built:        {{.Server.BuildTime}}
    32   OS/Arch:      {{.Server.Os}}/{{.Server.Arch}}
    33   Experimental: {{.Server.Experimental}}{{end}}`
    34  
    35  type versionOptions struct {
    36  	format string
    37  }
    38  
    39  // NewVersionCommand creates a new cobra.Command for `docker version`
    40  func NewVersionCommand(dockerCli *command.DockerCli) *cobra.Command {
    41  	var opts versionOptions
    42  
    43  	cmd := &cobra.Command{
    44  		Use:   "version [OPTIONS]",
    45  		Short: "Show the Docker version information",
    46  		Args:  cli.NoArgs,
    47  		RunE: func(cmd *cobra.Command, args []string) error {
    48  			return runVersion(dockerCli, &opts)
    49  		},
    50  	}
    51  
    52  	flags := cmd.Flags()
    53  
    54  	flags.StringVarP(&opts.format, "format", "f", "", "Format the output using the given Go template")
    55  
    56  	return cmd
    57  }
    58  
    59  func runVersion(dockerCli *command.DockerCli, opts *versionOptions) error {
    60  	ctx := context.Background()
    61  
    62  	templateFormat := versionTemplate
    63  	if opts.format != "" {
    64  		templateFormat = opts.format
    65  	}
    66  
    67  	tmpl, err := templates.Parse(templateFormat)
    68  	if err != nil {
    69  		return cli.StatusError{StatusCode: 64,
    70  			Status: "Template parsing error: " + err.Error()}
    71  	}
    72  
    73  	APIVersion := dockerCli.Client().ClientVersion()
    74  	if defaultAPIVersion := dockerCli.DefaultVersion(); APIVersion != defaultAPIVersion {
    75  		APIVersion = fmt.Sprintf("%s (downgraded from %s)", APIVersion, defaultAPIVersion)
    76  	}
    77  
    78  	vd := types.VersionResponse{
    79  		Client: &types.Version{
    80  			Version:    dockerversion.Version,
    81  			APIVersion: APIVersion,
    82  			GoVersion:  runtime.Version(),
    83  			GitCommit:  dockerversion.GitCommit,
    84  			BuildTime:  dockerversion.BuildTime,
    85  			Os:         runtime.GOOS,
    86  			Arch:       runtime.GOARCH,
    87  		},
    88  	}
    89  
    90  	serverVersion, err := dockerCli.Client().ServerVersion(ctx)
    91  	if err == nil {
    92  		vd.Server = &serverVersion
    93  	}
    94  
    95  	// first we need to make BuildTime more human friendly
    96  	t, errTime := time.Parse(time.RFC3339Nano, vd.Client.BuildTime)
    97  	if errTime == nil {
    98  		vd.Client.BuildTime = t.Format(time.ANSIC)
    99  	}
   100  
   101  	if vd.ServerOK() {
   102  		t, errTime = time.Parse(time.RFC3339Nano, vd.Server.BuildTime)
   103  		if errTime == nil {
   104  			vd.Server.BuildTime = t.Format(time.ANSIC)
   105  		}
   106  	}
   107  
   108  	if err2 := tmpl.Execute(dockerCli.Out(), vd); err2 != nil && err == nil {
   109  		err = err2
   110  	}
   111  	dockerCli.Out().Write([]byte{'\n'})
   112  	return err
   113  }