Browse code

Merge pull request #31830 from dnephin/refactor-cli-state

Small cleanup now that we have multiple details about the server stored on the cli

Sebastiaan van Stijn authored on 2017/03/29 20:36:32
Showing 2 changed files
... ...
@@ -44,28 +44,17 @@ type Cli interface {
44 44
 // DockerCli is an instance the docker command line client.
45 45
 // Instances of the client can be returned from NewDockerCli.
46 46
 type DockerCli struct {
47
-	configFile      *configfile.ConfigFile
48
-	in              *InStream
49
-	out             *OutStream
50
-	err             io.Writer
51
-	keyFile         string
52
-	client          client.APIClient
53
-	hasExperimental bool
54
-	osType          string
55
-	defaultVersion  string
47
+	configFile     *configfile.ConfigFile
48
+	in             *InStream
49
+	out            *OutStream
50
+	err            io.Writer
51
+	keyFile        string
52
+	client         client.APIClient
53
+	defaultVersion string
54
+	server         ServerInfo
56 55
 }
57 56
 
58
-// HasExperimental returns true if experimental features are accessible.
59
-func (cli *DockerCli) HasExperimental() bool {
60
-	return cli.hasExperimental
61
-}
62
-
63
-// OSType returns the operating system the daemon is running on.
64
-func (cli *DockerCli) OSType() string {
65
-	return cli.osType
66
-}
67
-
68
-// DefaultVersion returns api.defaultVersion of DOCKER_API_VERSION if specified.
57
+// DefaultVersion returns api.defaultVersion or DOCKER_API_VERSION if specified.
69 58
 func (cli *DockerCli) DefaultVersion() string {
70 59
 	return cli.defaultVersion
71 60
 }
... ...
@@ -102,6 +91,12 @@ func (cli *DockerCli) ConfigFile() *configfile.ConfigFile {
102 102
 	return cli.configFile
103 103
 }
104 104
 
105
+// ServerInfo returns the server version details for the host this client is
106
+// connected to
107
+func (cli *DockerCli) ServerInfo() ServerInfo {
108
+	return cli.server
109
+}
110
+
105 111
 // GetAllCredentials returns all of the credentials stored in all of the
106 112
 // configured credential stores.
107 113
 func (cli *DockerCli) GetAllCredentials() (map[string]types.AuthConfig, error) {
... ...
@@ -161,7 +156,6 @@ func (cli *DockerCli) Initialize(opts *cliflags.ClientOptions) error {
161 161
 	if err != nil {
162 162
 		return err
163 163
 	}
164
-
165 164
 	cli.defaultVersion = cli.client.ClientVersion()
166 165
 
167 166
 	if opts.Common.TrustKey == "" {
... ...
@@ -171,8 +165,10 @@ func (cli *DockerCli) Initialize(opts *cliflags.ClientOptions) error {
171 171
 	}
172 172
 
173 173
 	if ping, err := cli.client.Ping(context.Background()); err == nil {
174
-		cli.hasExperimental = ping.Experimental
175
-		cli.osType = ping.OSType
174
+		cli.server = ServerInfo{
175
+			HasExperimental: ping.Experimental,
176
+			OSType:          ping.OSType,
177
+		}
176 178
 
177 179
 		// since the new header was added in 1.25, assume server is 1.24 if header is not present.
178 180
 		if ping.APIVersion == "" {
... ...
@@ -184,9 +180,17 @@ func (cli *DockerCli) Initialize(opts *cliflags.ClientOptions) error {
184 184
 			cli.client.UpdateClientVersion(ping.APIVersion)
185 185
 		}
186 186
 	}
187
+
187 188
 	return nil
188 189
 }
189 190
 
191
+// ServerInfo stores details about the supported features and platform of the
192
+// server
193
+type ServerInfo struct {
194
+	HasExperimental bool
195
+	OSType          string
196
+}
197
+
190 198
 // NewDockerCli returns a DockerCli instance with IO output and error streams set by in, out and err.
191 199
 func NewDockerCli(in io.ReadCloser, out, err io.Writer) *DockerCli {
192 200
 	return &DockerCli{in: NewInStream(in), out: NewOutStream(out), err: err}
... ...
@@ -14,6 +14,7 @@ import (
14 14
 	cliconfig "github.com/docker/docker/cli/config"
15 15
 	"github.com/docker/docker/cli/debug"
16 16
 	cliflags "github.com/docker/docker/cli/flags"
17
+	"github.com/docker/docker/client"
17 18
 	"github.com/docker/docker/dockerversion"
18 19
 	"github.com/docker/docker/pkg/term"
19 20
 	"github.com/spf13/cobra"
... ...
@@ -49,7 +50,7 @@ func newDockerCommand(dockerCli *command.DockerCli) *cobra.Command {
49 49
 			if err := dockerCli.Initialize(opts); err != nil {
50 50
 				return err
51 51
 			}
52
-			return isSupported(cmd, dockerCli.Client().ClientVersion(), dockerCli.OSType(), dockerCli.HasExperimental())
52
+			return isSupported(cmd, dockerCli)
53 53
 		},
54 54
 	}
55 55
 	cli.SetupRootCommand(cmd)
... ...
@@ -80,7 +81,7 @@ func setFlagErrorFunc(dockerCli *command.DockerCli, cmd *cobra.Command, flags *p
80 80
 	flagErrorFunc := cmd.FlagErrorFunc()
81 81
 	cmd.SetFlagErrorFunc(func(cmd *cobra.Command, err error) error {
82 82
 		initializeDockerCli(dockerCli, flags, opts)
83
-		if err := isSupported(cmd, dockerCli.Client().ClientVersion(), dockerCli.OSType(), dockerCli.HasExperimental()); err != nil {
83
+		if err := isSupported(cmd, dockerCli); err != nil {
84 84
 			return err
85 85
 		}
86 86
 		return flagErrorFunc(cmd, err)
... ...
@@ -90,12 +91,12 @@ func setFlagErrorFunc(dockerCli *command.DockerCli, cmd *cobra.Command, flags *p
90 90
 func setHelpFunc(dockerCli *command.DockerCli, cmd *cobra.Command, flags *pflag.FlagSet, opts *cliflags.ClientOptions) {
91 91
 	cmd.SetHelpFunc(func(ccmd *cobra.Command, args []string) {
92 92
 		initializeDockerCli(dockerCli, flags, opts)
93
-		if err := isSupported(ccmd, dockerCli.Client().ClientVersion(), dockerCli.OSType(), dockerCli.HasExperimental()); err != nil {
93
+		if err := isSupported(ccmd, dockerCli); err != nil {
94 94
 			ccmd.Println(err)
95 95
 			return
96 96
 		}
97 97
 
98
-		hideUnsupportedFeatures(ccmd, dockerCli.Client().ClientVersion(), dockerCli.OSType(), dockerCli.HasExperimental())
98
+		hideUnsupportedFeatures(ccmd, dockerCli)
99 99
 
100 100
 		if err := ccmd.Help(); err != nil {
101 101
 			ccmd.Println(err)
... ...
@@ -122,7 +123,7 @@ func setValidateArgs(dockerCli *command.DockerCli, cmd *cobra.Command, flags *pf
122 122
 		cmdArgs := ccmd.Args
123 123
 		ccmd.Args = func(cmd *cobra.Command, args []string) error {
124 124
 			initializeDockerCli(dockerCli, flags, opts)
125
-			if err := isSupported(cmd, dockerCli.Client().ClientVersion(), dockerCli.OSType(), dockerCli.HasExperimental()); err != nil {
125
+			if err := isSupported(cmd, dockerCli); err != nil {
126 126
 				return err
127 127
 			}
128 128
 			return cmdArgs(cmd, args)
... ...
@@ -198,7 +199,16 @@ func dockerPreRun(opts *cliflags.ClientOptions) {
198 198
 	}
199 199
 }
200 200
 
201
-func hideUnsupportedFeatures(cmd *cobra.Command, clientVersion, osType string, hasExperimental bool) {
201
+type versionDetails interface {
202
+	Client() client.APIClient
203
+	ServerInfo() command.ServerInfo
204
+}
205
+
206
+func hideUnsupportedFeatures(cmd *cobra.Command, details versionDetails) {
207
+	clientVersion := details.Client().ClientVersion()
208
+	osType := details.ServerInfo().OSType
209
+	hasExperimental := details.ServerInfo().HasExperimental
210
+
202 211
 	cmd.Flags().VisitAll(func(f *pflag.Flag) {
203 212
 		// hide experimental flags
204 213
 		if !hasExperimental {
... ...
@@ -228,7 +238,11 @@ func hideUnsupportedFeatures(cmd *cobra.Command, clientVersion, osType string, h
228 228
 	}
229 229
 }
230 230
 
231
-func isSupported(cmd *cobra.Command, clientVersion, osType string, hasExperimental bool) error {
231
+func isSupported(cmd *cobra.Command, details versionDetails) error {
232
+	clientVersion := details.Client().ClientVersion()
233
+	osType := details.ServerInfo().OSType
234
+	hasExperimental := details.ServerInfo().HasExperimental
235
+
232 236
 	// Check recursively so that, e.g., `docker stack ls` returns the same output as `docker stack`
233 237
 	for curr := cmd; curr != nil; curr = curr.Parent() {
234 238
 		if cmdVersion, ok := curr.Tags["version"]; ok && versions.LessThan(clientVersion, cmdVersion) {