Преглед на файлове

Merge pull request #22372 from dnephin/cli_cleanup

Reorganize client and cli packages
David Calavera преди 9 години
родител
ревизия
90dfb3dacc

+ 4 - 3
api/client/cli.go

@@ -9,8 +9,9 @@ import (
 	"runtime"
 	"runtime"
 
 
 	"github.com/docker/docker/api"
 	"github.com/docker/docker/api"
-	"github.com/docker/docker/cli"
+	cliflags "github.com/docker/docker/cli/flags"
 	"github.com/docker/docker/cliconfig"
 	"github.com/docker/docker/cliconfig"
+	"github.com/docker/docker/cliconfig/configfile"
 	"github.com/docker/docker/cliconfig/credentials"
 	"github.com/docker/docker/cliconfig/credentials"
 	"github.com/docker/docker/dockerversion"
 	"github.com/docker/docker/dockerversion"
 	"github.com/docker/docker/opts"
 	"github.com/docker/docker/opts"
@@ -27,7 +28,7 @@ type DockerCli struct {
 	init func() error
 	init func() error
 
 
 	// configFile has the client configuration file
 	// configFile has the client configuration file
-	configFile *cliconfig.ConfigFile
+	configFile *configfile.ConfigFile
 	// in holds the input stream and closer (io.ReadCloser) for the client.
 	// in holds the input stream and closer (io.ReadCloser) for the client.
 	in io.ReadCloser
 	in io.ReadCloser
 	// out holds the output stream (io.Writer) for the client.
 	// out holds the output stream (io.Writer) for the client.
@@ -112,7 +113,7 @@ func (cli *DockerCli) restoreTerminal(in io.Closer) error {
 // The key file, protocol (i.e. unix) and address are passed in as strings, along with the tls.Config. If the tls.Config
 // The key file, protocol (i.e. unix) and address are passed in as strings, along with the tls.Config. If the tls.Config
 // is set the client scheme will be set to https.
 // is set the client scheme will be set to https.
 // The client will be given a 32-second timeout (see https://github.com/docker/docker/pull/8035).
 // The client will be given a 32-second timeout (see https://github.com/docker/docker/pull/8035).
-func NewDockerCli(in io.ReadCloser, out, err io.Writer, clientFlags *cli.ClientFlags) *DockerCli {
+func NewDockerCli(in io.ReadCloser, out, err io.Writer, clientFlags *cliflags.ClientFlags) *DockerCli {
 	cli := &DockerCli{
 	cli := &DockerCli{
 		in:      in,
 		in:      in,
 		out:     out,
 		out:     out,

+ 6 - 6
api/client/login.go

@@ -11,7 +11,7 @@ import (
 	"golang.org/x/net/context"
 	"golang.org/x/net/context"
 
 
 	Cli "github.com/docker/docker/cli"
 	Cli "github.com/docker/docker/cli"
-	"github.com/docker/docker/cliconfig"
+	"github.com/docker/docker/cliconfig/configfile"
 	"github.com/docker/docker/cliconfig/credentials"
 	"github.com/docker/docker/cliconfig/credentials"
 	flag "github.com/docker/docker/pkg/mflag"
 	flag "github.com/docker/docker/pkg/mflag"
 	"github.com/docker/docker/pkg/term"
 	"github.com/docker/docker/pkg/term"
@@ -143,33 +143,33 @@ func readInput(in io.Reader, out io.Writer) string {
 
 
 // getCredentials loads the user credentials from a credentials store.
 // getCredentials loads the user credentials from a credentials store.
 // The store is determined by the config file settings.
 // The store is determined by the config file settings.
-func getCredentials(c *cliconfig.ConfigFile, serverAddress string) (types.AuthConfig, error) {
+func getCredentials(c *configfile.ConfigFile, serverAddress string) (types.AuthConfig, error) {
 	s := loadCredentialsStore(c)
 	s := loadCredentialsStore(c)
 	return s.Get(serverAddress)
 	return s.Get(serverAddress)
 }
 }
 
 
-func getAllCredentials(c *cliconfig.ConfigFile) (map[string]types.AuthConfig, error) {
+func getAllCredentials(c *configfile.ConfigFile) (map[string]types.AuthConfig, error) {
 	s := loadCredentialsStore(c)
 	s := loadCredentialsStore(c)
 	return s.GetAll()
 	return s.GetAll()
 }
 }
 
 
 // storeCredentials saves the user credentials in a credentials store.
 // storeCredentials saves the user credentials in a credentials store.
 // The store is determined by the config file settings.
 // The store is determined by the config file settings.
-func storeCredentials(c *cliconfig.ConfigFile, auth types.AuthConfig) error {
+func storeCredentials(c *configfile.ConfigFile, auth types.AuthConfig) error {
 	s := loadCredentialsStore(c)
 	s := loadCredentialsStore(c)
 	return s.Store(auth)
 	return s.Store(auth)
 }
 }
 
 
 // eraseCredentials removes the user credentials from a credentials store.
 // eraseCredentials removes the user credentials from a credentials store.
 // The store is determined by the config file settings.
 // The store is determined by the config file settings.
-func eraseCredentials(c *cliconfig.ConfigFile, serverAddress string) error {
+func eraseCredentials(c *configfile.ConfigFile, serverAddress string) error {
 	s := loadCredentialsStore(c)
 	s := loadCredentialsStore(c)
 	return s.Erase(serverAddress)
 	return s.Erase(serverAddress)
 }
 }
 
 
 // loadCredentialsStore initializes a new credentials store based
 // loadCredentialsStore initializes a new credentials store based
 // in the settings provided in the configuration file.
 // in the settings provided in the configuration file.
-func loadCredentialsStore(c *cliconfig.ConfigFile) credentials.Store {
+func loadCredentialsStore(c *configfile.ConfigFile) credentials.Store {
 	if c.CredentialsStore != "" {
 	if c.CredentialsStore != "" {
 		return credentials.NewNativeStore(c)
 		return credentials.NewNativeStore(c)
 	}
 	}

+ 1 - 1
cli/client.go → cli/flags/client.go

@@ -1,4 +1,4 @@
-package cli
+package flags
 
 
 import flag "github.com/docker/docker/pkg/mflag"
 import flag "github.com/docker/docker/pkg/mflag"
 
 

+ 17 - 4
cli/flags/common.go

@@ -6,7 +6,6 @@ import (
 	"path/filepath"
 	"path/filepath"
 
 
 	"github.com/Sirupsen/logrus"
 	"github.com/Sirupsen/logrus"
-	"github.com/docker/docker/cli"
 	"github.com/docker/docker/cliconfig"
 	"github.com/docker/docker/cliconfig"
 	"github.com/docker/docker/opts"
 	"github.com/docker/docker/opts"
 	flag "github.com/docker/docker/pkg/mflag"
 	flag "github.com/docker/docker/pkg/mflag"
@@ -31,9 +30,23 @@ var (
 	dockerTLSVerify = os.Getenv("DOCKER_TLS_VERIFY") != ""
 	dockerTLSVerify = os.Getenv("DOCKER_TLS_VERIFY") != ""
 )
 )
 
 
+// CommonFlags are flags common to both the client and the daemon.
+type CommonFlags struct {
+	FlagSet   *flag.FlagSet
+	PostParse func()
+
+	Debug      bool
+	Hosts      []string
+	LogLevel   string
+	TLS        bool
+	TLSVerify  bool
+	TLSOptions *tlsconfig.Options
+	TrustKey   string
+}
+
 // InitCommonFlags initializes flags common to both client and daemon
 // InitCommonFlags initializes flags common to both client and daemon
-func InitCommonFlags() *cli.CommonFlags {
-	var commonFlags = &cli.CommonFlags{FlagSet: new(flag.FlagSet)}
+func InitCommonFlags() *CommonFlags {
+	var commonFlags = &CommonFlags{FlagSet: new(flag.FlagSet)}
 
 
 	if dockerCertPath == "" {
 	if dockerCertPath == "" {
 		dockerCertPath = cliconfig.ConfigDir()
 		dockerCertPath = cliconfig.ConfigDir()
@@ -60,7 +73,7 @@ func InitCommonFlags() *cli.CommonFlags {
 	return commonFlags
 	return commonFlags
 }
 }
 
 
-func postParseCommon(commonFlags *cli.CommonFlags) {
+func postParseCommon(commonFlags *CommonFlags) {
 	cmd := commonFlags.FlagSet
 	cmd := commonFlags.FlagSet
 
 
 	SetDaemonLogLevel(commonFlags.LogLevel)
 	SetDaemonLogLevel(commonFlags.LogLevel)

+ 3 - 21
cli/common.go → cli/usage.go

@@ -1,31 +1,13 @@
 package cli
 package cli
 
 
-import (
-	flag "github.com/docker/docker/pkg/mflag"
-	"github.com/docker/go-connections/tlsconfig"
-)
-
-// CommonFlags represents flags that are common to both the client and the daemon.
-type CommonFlags struct {
-	FlagSet   *flag.FlagSet
-	PostParse func()
-
-	Debug      bool
-	Hosts      []string
-	LogLevel   string
-	TLS        bool
-	TLSVerify  bool
-	TLSOptions *tlsconfig.Options
-	TrustKey   string
-}
-
 // Command is the struct containing the command name and description
 // Command is the struct containing the command name and description
 type Command struct {
 type Command struct {
 	Name        string
 	Name        string
 	Description string
 	Description string
 }
 }
 
 
-var dockerCommands = []Command{
+// DockerCommandUsage lists the top level docker commands and their short usage
+var DockerCommandUsage = []Command{
 	{"attach", "Attach to a running container"},
 	{"attach", "Attach to a running container"},
 	{"build", "Build an image from a Dockerfile"},
 	{"build", "Build an image from a Dockerfile"},
 	{"commit", "Create a new image from a container's changes"},
 	{"commit", "Create a new image from a container's changes"},
@@ -74,7 +56,7 @@ var dockerCommands = []Command{
 var DockerCommands = make(map[string]Command)
 var DockerCommands = make(map[string]Command)
 
 
 func init() {
 func init() {
-	for _, cmd := range dockerCommands {
+	for _, cmd := range DockerCommandUsage {
 		DockerCommands[cmd.Name] = cmd
 		DockerCommands[cmd.Name] = cmd
 	}
 	}
 }
 }

+ 16 - 180
cliconfig/config.go

@@ -1,15 +1,12 @@
 package cliconfig
 package cliconfig
 
 
 import (
 import (
-	"encoding/base64"
-	"encoding/json"
 	"fmt"
 	"fmt"
 	"io"
 	"io"
-	"io/ioutil"
 	"os"
 	"os"
 	"path/filepath"
 	"path/filepath"
-	"strings"
 
 
+	"github.com/docker/docker/cliconfig/configfile"
 	"github.com/docker/docker/pkg/homedir"
 	"github.com/docker/docker/pkg/homedir"
 	"github.com/docker/engine-api/types"
 	"github.com/docker/engine-api/types"
 )
 )
@@ -46,94 +43,19 @@ func SetConfigDir(dir string) {
 	configDir = dir
 	configDir = dir
 }
 }
 
 
-// ConfigFile ~/.docker/config.json file info
-type ConfigFile struct {
-	AuthConfigs      map[string]types.AuthConfig `json:"auths"`
-	HTTPHeaders      map[string]string           `json:"HttpHeaders,omitempty"`
-	PsFormat         string                      `json:"psFormat,omitempty"`
-	ImagesFormat     string                      `json:"imagesFormat,omitempty"`
-	DetachKeys       string                      `json:"detachKeys,omitempty"`
-	CredentialsStore string                      `json:"credsStore,omitempty"`
-	filename         string                      // Note: not serialized - for internal use only
-}
-
 // NewConfigFile initializes an empty configuration file for the given filename 'fn'
 // NewConfigFile initializes an empty configuration file for the given filename 'fn'
-func NewConfigFile(fn string) *ConfigFile {
-	return &ConfigFile{
+func NewConfigFile(fn string) *configfile.ConfigFile {
+	return &configfile.ConfigFile{
 		AuthConfigs: make(map[string]types.AuthConfig),
 		AuthConfigs: make(map[string]types.AuthConfig),
 		HTTPHeaders: make(map[string]string),
 		HTTPHeaders: make(map[string]string),
-		filename:    fn,
-	}
-}
-
-// LegacyLoadFromReader reads the non-nested configuration data given and sets up the
-// auth config information with given directory and populates the receiver object
-func (configFile *ConfigFile) LegacyLoadFromReader(configData io.Reader) error {
-	b, err := ioutil.ReadAll(configData)
-	if err != nil {
-		return err
-	}
-
-	if err := json.Unmarshal(b, &configFile.AuthConfigs); err != nil {
-		arr := strings.Split(string(b), "\n")
-		if len(arr) < 2 {
-			return fmt.Errorf("The Auth config file is empty")
-		}
-		authConfig := types.AuthConfig{}
-		origAuth := strings.Split(arr[0], " = ")
-		if len(origAuth) != 2 {
-			return fmt.Errorf("Invalid Auth config file")
-		}
-		authConfig.Username, authConfig.Password, err = decodeAuth(origAuth[1])
-		if err != nil {
-			return err
-		}
-		authConfig.ServerAddress = defaultIndexserver
-		configFile.AuthConfigs[defaultIndexserver] = authConfig
-	} else {
-		for k, authConfig := range configFile.AuthConfigs {
-			authConfig.Username, authConfig.Password, err = decodeAuth(authConfig.Auth)
-			if err != nil {
-				return err
-			}
-			authConfig.Auth = ""
-			authConfig.ServerAddress = k
-			configFile.AuthConfigs[k] = authConfig
-		}
+		Filename:    fn,
 	}
 	}
-	return nil
-}
-
-// LoadFromReader reads the configuration data given and sets up the auth config
-// information with given directory and populates the receiver object
-func (configFile *ConfigFile) LoadFromReader(configData io.Reader) error {
-	if err := json.NewDecoder(configData).Decode(&configFile); err != nil {
-		return err
-	}
-	var err error
-	for addr, ac := range configFile.AuthConfigs {
-		ac.Username, ac.Password, err = decodeAuth(ac.Auth)
-		if err != nil {
-			return err
-		}
-		ac.Auth = ""
-		ac.ServerAddress = addr
-		configFile.AuthConfigs[addr] = ac
-	}
-	return nil
-}
-
-// ContainsAuth returns whether there is authentication configured
-// in this file or not.
-func (configFile *ConfigFile) ContainsAuth() bool {
-	return configFile.CredentialsStore != "" ||
-		(configFile.AuthConfigs != nil && len(configFile.AuthConfigs) > 0)
 }
 }
 
 
 // LegacyLoadFromReader is a convenience function that creates a ConfigFile object from
 // LegacyLoadFromReader is a convenience function that creates a ConfigFile object from
 // a non-nested reader
 // a non-nested reader
-func LegacyLoadFromReader(configData io.Reader) (*ConfigFile, error) {
-	configFile := ConfigFile{
+func LegacyLoadFromReader(configData io.Reader) (*configfile.ConfigFile, error) {
+	configFile := configfile.ConfigFile{
 		AuthConfigs: make(map[string]types.AuthConfig),
 		AuthConfigs: make(map[string]types.AuthConfig),
 	}
 	}
 	err := configFile.LegacyLoadFromReader(configData)
 	err := configFile.LegacyLoadFromReader(configData)
@@ -142,8 +64,8 @@ func LegacyLoadFromReader(configData io.Reader) (*ConfigFile, error) {
 
 
 // LoadFromReader is a convenience function that creates a ConfigFile object from
 // LoadFromReader is a convenience function that creates a ConfigFile object from
 // a reader
 // a reader
-func LoadFromReader(configData io.Reader) (*ConfigFile, error) {
-	configFile := ConfigFile{
+func LoadFromReader(configData io.Reader) (*configfile.ConfigFile, error) {
+	configFile := configfile.ConfigFile{
 		AuthConfigs: make(map[string]types.AuthConfig),
 		AuthConfigs: make(map[string]types.AuthConfig),
 	}
 	}
 	err := configFile.LoadFromReader(configData)
 	err := configFile.LoadFromReader(configData)
@@ -153,32 +75,32 @@ func LoadFromReader(configData io.Reader) (*ConfigFile, error) {
 // Load reads the configuration files in the given directory, and sets up
 // Load reads the configuration files in the given directory, and sets up
 // the auth config information and returns values.
 // the auth config information and returns values.
 // FIXME: use the internal golang config parser
 // FIXME: use the internal golang config parser
-func Load(configDir string) (*ConfigFile, error) {
+func Load(configDir string) (*configfile.ConfigFile, error) {
 	if configDir == "" {
 	if configDir == "" {
 		configDir = ConfigDir()
 		configDir = ConfigDir()
 	}
 	}
 
 
-	configFile := ConfigFile{
+	configFile := configfile.ConfigFile{
 		AuthConfigs: make(map[string]types.AuthConfig),
 		AuthConfigs: make(map[string]types.AuthConfig),
-		filename:    filepath.Join(configDir, ConfigFileName),
+		Filename:    filepath.Join(configDir, ConfigFileName),
 	}
 	}
 
 
 	// Try happy path first - latest config file
 	// Try happy path first - latest config file
-	if _, err := os.Stat(configFile.filename); err == nil {
-		file, err := os.Open(configFile.filename)
+	if _, err := os.Stat(configFile.Filename); err == nil {
+		file, err := os.Open(configFile.Filename)
 		if err != nil {
 		if err != nil {
-			return &configFile, fmt.Errorf("%s - %v", configFile.filename, err)
+			return &configFile, fmt.Errorf("%s - %v", configFile.Filename, err)
 		}
 		}
 		defer file.Close()
 		defer file.Close()
 		err = configFile.LoadFromReader(file)
 		err = configFile.LoadFromReader(file)
 		if err != nil {
 		if err != nil {
-			err = fmt.Errorf("%s - %v", configFile.filename, err)
+			err = fmt.Errorf("%s - %v", configFile.Filename, err)
 		}
 		}
 		return &configFile, err
 		return &configFile, err
 	} else if !os.IsNotExist(err) {
 	} else if !os.IsNotExist(err) {
 		// if file is there but we can't stat it for any reason other
 		// if file is there but we can't stat it for any reason other
 		// than it doesn't exist then stop
 		// than it doesn't exist then stop
-		return &configFile, fmt.Errorf("%s - %v", configFile.filename, err)
+		return &configFile, fmt.Errorf("%s - %v", configFile.Filename, err)
 	}
 	}
 
 
 	// Can't find latest config file so check for the old one
 	// Can't find latest config file so check for the old one
@@ -201,89 +123,3 @@ func Load(configDir string) (*ConfigFile, error) {
 	}
 	}
 	return &configFile, nil
 	return &configFile, nil
 }
 }
-
-// SaveToWriter encodes and writes out all the authorization information to
-// the given writer
-func (configFile *ConfigFile) SaveToWriter(writer io.Writer) error {
-	// Encode sensitive data into a new/temp struct
-	tmpAuthConfigs := make(map[string]types.AuthConfig, len(configFile.AuthConfigs))
-	for k, authConfig := range configFile.AuthConfigs {
-		authCopy := authConfig
-		// encode and save the authstring, while blanking out the original fields
-		authCopy.Auth = encodeAuth(&authCopy)
-		authCopy.Username = ""
-		authCopy.Password = ""
-		authCopy.ServerAddress = ""
-		tmpAuthConfigs[k] = authCopy
-	}
-
-	saveAuthConfigs := configFile.AuthConfigs
-	configFile.AuthConfigs = tmpAuthConfigs
-	defer func() { configFile.AuthConfigs = saveAuthConfigs }()
-
-	data, err := json.MarshalIndent(configFile, "", "\t")
-	if err != nil {
-		return err
-	}
-	_, err = writer.Write(data)
-	return err
-}
-
-// Save encodes and writes out all the authorization information
-func (configFile *ConfigFile) Save() error {
-	if configFile.Filename() == "" {
-		return fmt.Errorf("Can't save config with empty filename")
-	}
-
-	if err := os.MkdirAll(filepath.Dir(configFile.filename), 0700); err != nil {
-		return err
-	}
-	f, err := os.OpenFile(configFile.filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
-	if err != nil {
-		return err
-	}
-	defer f.Close()
-	return configFile.SaveToWriter(f)
-}
-
-// Filename returns the name of the configuration file
-func (configFile *ConfigFile) Filename() string {
-	return configFile.filename
-}
-
-// encodeAuth creates a base64 encoded string to containing authorization information
-func encodeAuth(authConfig *types.AuthConfig) string {
-	if authConfig.Username == "" && authConfig.Password == "" {
-		return ""
-	}
-
-	authStr := authConfig.Username + ":" + authConfig.Password
-	msg := []byte(authStr)
-	encoded := make([]byte, base64.StdEncoding.EncodedLen(len(msg)))
-	base64.StdEncoding.Encode(encoded, msg)
-	return string(encoded)
-}
-
-// decodeAuth decodes a base64 encoded string and returns username and password
-func decodeAuth(authStr string) (string, string, error) {
-	if authStr == "" {
-		return "", "", nil
-	}
-
-	decLen := base64.StdEncoding.DecodedLen(len(authStr))
-	decoded := make([]byte, decLen)
-	authByte := []byte(authStr)
-	n, err := base64.StdEncoding.Decode(decoded, authByte)
-	if err != nil {
-		return "", "", err
-	}
-	if n > decLen {
-		return "", "", fmt.Errorf("Something went wrong decoding auth config")
-	}
-	arr := strings.SplitN(string(decoded), ":", 2)
-	if len(arr) != 2 {
-		return "", "", fmt.Errorf("Invalid auth configuration file")
-	}
-	password := strings.Trim(arr[1], "\x00")
-	return arr[0], password, nil
-}

+ 6 - 26
cliconfig/config_test.go

@@ -7,8 +7,8 @@ import (
 	"strings"
 	"strings"
 	"testing"
 	"testing"
 
 
+	"github.com/docker/docker/cliconfig/configfile"
 	"github.com/docker/docker/pkg/homedir"
 	"github.com/docker/docker/pkg/homedir"
-	"github.com/docker/engine-api/types"
 )
 )
 
 
 func TestEmptyConfigDir(t *testing.T) {
 func TestEmptyConfigDir(t *testing.T) {
@@ -26,8 +26,8 @@ func TestEmptyConfigDir(t *testing.T) {
 	}
 	}
 
 
 	expectedConfigFilename := filepath.Join(tmpHome, ConfigFileName)
 	expectedConfigFilename := filepath.Join(tmpHome, ConfigFileName)
-	if config.Filename() != expectedConfigFilename {
-		t.Fatalf("Expected config filename %s, got %s", expectedConfigFilename, config.Filename())
+	if config.Filename != expectedConfigFilename {
+		t.Fatalf("Expected config filename %s, got %s", expectedConfigFilename, config.Filename)
 	}
 	}
 
 
 	// Now save it and make sure it shows up in new form
 	// Now save it and make sure it shows up in new form
@@ -377,7 +377,7 @@ func TestJsonWithPsFormat(t *testing.T) {
 }
 }
 
 
 // Save it and make sure it shows up in new form
 // Save it and make sure it shows up in new form
-func saveConfigAndValidateNewFormat(t *testing.T, config *ConfigFile, homeFolder string) string {
+func saveConfigAndValidateNewFormat(t *testing.T, config *configfile.ConfigFile, homeFolder string) string {
 	if err := config.Save(); err != nil {
 	if err := config.Save(); err != nil {
 		t.Fatalf("Failed to save: %q", err)
 		t.Fatalf("Failed to save: %q", err)
 	}
 	}
@@ -415,8 +415,8 @@ func TestConfigFile(t *testing.T) {
 	configFilename := "configFilename"
 	configFilename := "configFilename"
 	configFile := NewConfigFile(configFilename)
 	configFile := NewConfigFile(configFilename)
 
 
-	if configFile.Filename() != configFilename {
-		t.Fatalf("Expected %s, got %s", configFilename, configFile.Filename())
+	if configFile.Filename != configFilename {
+		t.Fatalf("Expected %s, got %s", configFilename, configFile.Filename)
 	}
 	}
 }
 }
 
 
@@ -543,23 +543,3 @@ func TestLegacyJsonSaveWithNoFile(t *testing.T) {
 		t.Fatalf("Should have save in new form: \n%s\n not \n%s", string(buf), expConfStr)
 		t.Fatalf("Should have save in new form: \n%s\n not \n%s", string(buf), expConfStr)
 	}
 	}
 }
 }
-
-func TestEncodeAuth(t *testing.T) {
-	newAuthConfig := &types.AuthConfig{Username: "ken", Password: "test"}
-	authStr := encodeAuth(newAuthConfig)
-	decAuthConfig := &types.AuthConfig{}
-	var err error
-	decAuthConfig.Username, decAuthConfig.Password, err = decodeAuth(authStr)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if newAuthConfig.Username != decAuthConfig.Username {
-		t.Fatal("Encode Username doesn't match decoded Username")
-	}
-	if newAuthConfig.Password != decAuthConfig.Password {
-		t.Fatal("Encode Password doesn't match decoded Password")
-	}
-	if authStr != "a2VuOnRlc3Q=" {
-		t.Fatal("AuthString encoding isn't correct.")
-	}
-}

+ 177 - 0
cliconfig/configfile/file.go

@@ -0,0 +1,177 @@
+package configfile
+
+import (
+	"encoding/base64"
+	"encoding/json"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"strings"
+
+	"github.com/docker/engine-api/types"
+)
+
+const (
+	// This constant is only used for really old config files when the
+	// URL wasn't saved as part of the config file and it was just
+	// assumed to be this value.
+	defaultIndexserver = "https://index.docker.io/v1/"
+)
+
+// ConfigFile ~/.docker/config.json file info
+type ConfigFile struct {
+	AuthConfigs      map[string]types.AuthConfig `json:"auths"`
+	HTTPHeaders      map[string]string           `json:"HttpHeaders,omitempty"`
+	PsFormat         string                      `json:"psFormat,omitempty"`
+	ImagesFormat     string                      `json:"imagesFormat,omitempty"`
+	DetachKeys       string                      `json:"detachKeys,omitempty"`
+	CredentialsStore string                      `json:"credsStore,omitempty"`
+	Filename         string                      `json:"-"` // Note: for internal use only
+}
+
+// LegacyLoadFromReader reads the non-nested configuration data given and sets up the
+// auth config information with given directory and populates the receiver object
+func (configFile *ConfigFile) LegacyLoadFromReader(configData io.Reader) error {
+	b, err := ioutil.ReadAll(configData)
+	if err != nil {
+		return err
+	}
+
+	if err := json.Unmarshal(b, &configFile.AuthConfigs); err != nil {
+		arr := strings.Split(string(b), "\n")
+		if len(arr) < 2 {
+			return fmt.Errorf("The Auth config file is empty")
+		}
+		authConfig := types.AuthConfig{}
+		origAuth := strings.Split(arr[0], " = ")
+		if len(origAuth) != 2 {
+			return fmt.Errorf("Invalid Auth config file")
+		}
+		authConfig.Username, authConfig.Password, err = decodeAuth(origAuth[1])
+		if err != nil {
+			return err
+		}
+		authConfig.ServerAddress = defaultIndexserver
+		configFile.AuthConfigs[defaultIndexserver] = authConfig
+	} else {
+		for k, authConfig := range configFile.AuthConfigs {
+			authConfig.Username, authConfig.Password, err = decodeAuth(authConfig.Auth)
+			if err != nil {
+				return err
+			}
+			authConfig.Auth = ""
+			authConfig.ServerAddress = k
+			configFile.AuthConfigs[k] = authConfig
+		}
+	}
+	return nil
+}
+
+// LoadFromReader reads the configuration data given and sets up the auth config
+// information with given directory and populates the receiver object
+func (configFile *ConfigFile) LoadFromReader(configData io.Reader) error {
+	if err := json.NewDecoder(configData).Decode(&configFile); err != nil {
+		return err
+	}
+	var err error
+	for addr, ac := range configFile.AuthConfigs {
+		ac.Username, ac.Password, err = decodeAuth(ac.Auth)
+		if err != nil {
+			return err
+		}
+		ac.Auth = ""
+		ac.ServerAddress = addr
+		configFile.AuthConfigs[addr] = ac
+	}
+	return nil
+}
+
+// ContainsAuth returns whether there is authentication configured
+// in this file or not.
+func (configFile *ConfigFile) ContainsAuth() bool {
+	return configFile.CredentialsStore != "" ||
+		(configFile.AuthConfigs != nil && len(configFile.AuthConfigs) > 0)
+}
+
+// SaveToWriter encodes and writes out all the authorization information to
+// the given writer
+func (configFile *ConfigFile) SaveToWriter(writer io.Writer) error {
+	// Encode sensitive data into a new/temp struct
+	tmpAuthConfigs := make(map[string]types.AuthConfig, len(configFile.AuthConfigs))
+	for k, authConfig := range configFile.AuthConfigs {
+		authCopy := authConfig
+		// encode and save the authstring, while blanking out the original fields
+		authCopy.Auth = encodeAuth(&authCopy)
+		authCopy.Username = ""
+		authCopy.Password = ""
+		authCopy.ServerAddress = ""
+		tmpAuthConfigs[k] = authCopy
+	}
+
+	saveAuthConfigs := configFile.AuthConfigs
+	configFile.AuthConfigs = tmpAuthConfigs
+	defer func() { configFile.AuthConfigs = saveAuthConfigs }()
+
+	data, err := json.MarshalIndent(configFile, "", "\t")
+	if err != nil {
+		return err
+	}
+	_, err = writer.Write(data)
+	return err
+}
+
+// Save encodes and writes out all the authorization information
+func (configFile *ConfigFile) Save() error {
+	if configFile.Filename == "" {
+		return fmt.Errorf("Can't save config with empty filename")
+	}
+
+	if err := os.MkdirAll(filepath.Dir(configFile.Filename), 0700); err != nil {
+		return err
+	}
+	f, err := os.OpenFile(configFile.Filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
+	if err != nil {
+		return err
+	}
+	defer f.Close()
+	return configFile.SaveToWriter(f)
+}
+
+// encodeAuth creates a base64 encoded string to containing authorization information
+func encodeAuth(authConfig *types.AuthConfig) string {
+	if authConfig.Username == "" && authConfig.Password == "" {
+		return ""
+	}
+
+	authStr := authConfig.Username + ":" + authConfig.Password
+	msg := []byte(authStr)
+	encoded := make([]byte, base64.StdEncoding.EncodedLen(len(msg)))
+	base64.StdEncoding.Encode(encoded, msg)
+	return string(encoded)
+}
+
+// decodeAuth decodes a base64 encoded string and returns username and password
+func decodeAuth(authStr string) (string, string, error) {
+	if authStr == "" {
+		return "", "", nil
+	}
+
+	decLen := base64.StdEncoding.DecodedLen(len(authStr))
+	decoded := make([]byte, decLen)
+	authByte := []byte(authStr)
+	n, err := base64.StdEncoding.Decode(decoded, authByte)
+	if err != nil {
+		return "", "", err
+	}
+	if n > decLen {
+		return "", "", fmt.Errorf("Something went wrong decoding auth config")
+	}
+	arr := strings.SplitN(string(decoded), ":", 2)
+	if len(arr) != 2 {
+		return "", "", fmt.Errorf("Invalid auth configuration file")
+	}
+	password := strings.Trim(arr[1], "\x00")
+	return arr[0], password, nil
+}

+ 27 - 0
cliconfig/configfile/file_test.go

@@ -0,0 +1,27 @@
+package configfile
+
+import (
+	"testing"
+
+	"github.com/docker/engine-api/types"
+)
+
+func TestEncodeAuth(t *testing.T) {
+	newAuthConfig := &types.AuthConfig{Username: "ken", Password: "test"}
+	authStr := encodeAuth(newAuthConfig)
+	decAuthConfig := &types.AuthConfig{}
+	var err error
+	decAuthConfig.Username, decAuthConfig.Password, err = decodeAuth(authStr)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if newAuthConfig.Username != decAuthConfig.Username {
+		t.Fatal("Encode Username doesn't match decoded Username")
+	}
+	if newAuthConfig.Password != decAuthConfig.Password {
+		t.Fatal("Encode Password doesn't match decoded Password")
+	}
+	if authStr != "a2VuOnRlc3Q=" {
+		t.Fatal("AuthString encoding isn't correct.")
+	}
+}

+ 2 - 2
cliconfig/credentials/default_store.go

@@ -3,12 +3,12 @@ package credentials
 import (
 import (
 	"os/exec"
 	"os/exec"
 
 
-	"github.com/docker/docker/cliconfig"
+	"github.com/docker/docker/cliconfig/configfile"
 )
 )
 
 
 // DetectDefaultStore sets the default credentials store
 // DetectDefaultStore sets the default credentials store
 // if the host includes the default store helper program.
 // if the host includes the default store helper program.
-func DetectDefaultStore(c *cliconfig.ConfigFile) {
+func DetectDefaultStore(c *configfile.ConfigFile) {
 	if c.CredentialsStore != "" {
 	if c.CredentialsStore != "" {
 		// user defined
 		// user defined
 		return
 		return

+ 3 - 3
cliconfig/credentials/file_store.go

@@ -3,18 +3,18 @@ package credentials
 import (
 import (
 	"strings"
 	"strings"
 
 
-	"github.com/docker/docker/cliconfig"
+	"github.com/docker/docker/cliconfig/configfile"
 	"github.com/docker/engine-api/types"
 	"github.com/docker/engine-api/types"
 )
 )
 
 
 // fileStore implements a credentials store using
 // fileStore implements a credentials store using
 // the docker configuration file to keep the credentials in plain text.
 // the docker configuration file to keep the credentials in plain text.
 type fileStore struct {
 type fileStore struct {
-	file *cliconfig.ConfigFile
+	file *configfile.ConfigFile
 }
 }
 
 
 // NewFileStore creates a new file credentials store.
 // NewFileStore creates a new file credentials store.
-func NewFileStore(file *cliconfig.ConfigFile) Store {
+func NewFileStore(file *configfile.ConfigFile) Store {
 	return &fileStore{
 	return &fileStore{
 		file: file,
 		file: file,
 	}
 	}

+ 2 - 1
cliconfig/credentials/file_store_test.go

@@ -5,10 +5,11 @@ import (
 	"testing"
 	"testing"
 
 
 	"github.com/docker/docker/cliconfig"
 	"github.com/docker/docker/cliconfig"
+	"github.com/docker/docker/cliconfig/configfile"
 	"github.com/docker/engine-api/types"
 	"github.com/docker/engine-api/types"
 )
 )
 
 
-func newConfigFile(auths map[string]types.AuthConfig) *cliconfig.ConfigFile {
+func newConfigFile(auths map[string]types.AuthConfig) *configfile.ConfigFile {
 	tmp, _ := ioutil.TempFile("", "docker-test")
 	tmp, _ := ioutil.TempFile("", "docker-test")
 	name := tmp.Name()
 	name := tmp.Name()
 	tmp.Close()
 	tmp.Close()

+ 2 - 2
cliconfig/credentials/native_store.go

@@ -9,7 +9,7 @@ import (
 	"strings"
 	"strings"
 
 
 	"github.com/Sirupsen/logrus"
 	"github.com/Sirupsen/logrus"
-	"github.com/docker/docker/cliconfig"
+	"github.com/docker/docker/cliconfig/configfile"
 	"github.com/docker/engine-api/types"
 	"github.com/docker/engine-api/types"
 )
 )
 
 
@@ -52,7 +52,7 @@ type nativeStore struct {
 
 
 // NewNativeStore creates a new native store that
 // NewNativeStore creates a new native store that
 // uses a remote helper program to manage credentials.
 // uses a remote helper program to manage credentials.
-func NewNativeStore(file *cliconfig.ConfigFile) Store {
+func NewNativeStore(file *configfile.ConfigFile) Store {
 	return &nativeStore{
 	return &nativeStore{
 		commandFn: shellCommandFn(file.CredentialsStore),
 		commandFn: shellCommandFn(file.CredentialsStore),
 		fileStore: NewFileStore(file),
 		fileStore: NewFileStore(file),

+ 0 - 38
cmd/docker/client.go

@@ -1,38 +0,0 @@
-package main
-
-import (
-	"path/filepath"
-
-	"github.com/docker/docker/cli"
-	cliflags "github.com/docker/docker/cli/flags"
-	"github.com/docker/docker/cliconfig"
-	flag "github.com/docker/docker/pkg/mflag"
-	"github.com/docker/docker/utils"
-)
-
-var (
-	commonFlags = cliflags.InitCommonFlags()
-	clientFlags = &cli.ClientFlags{FlagSet: new(flag.FlagSet), Common: commonFlags}
-)
-
-func init() {
-
-	client := clientFlags.FlagSet
-	client.StringVar(&clientFlags.ConfigDir, []string{"-config"}, cliconfig.ConfigDir(), "Location of client config files")
-
-	clientFlags.PostParse = func() {
-		clientFlags.Common.PostParse()
-
-		if clientFlags.ConfigDir != "" {
-			cliconfig.SetConfigDir(clientFlags.ConfigDir)
-		}
-
-		if clientFlags.Common.TrustKey == "" {
-			clientFlags.Common.TrustKey = filepath.Join(cliconfig.ConfigDir(), cliflags.DefaultTrustKeyFile)
-		}
-
-		if clientFlags.Common.Debug {
-			utils.EnableDebug()
-		}
-	}
-}

+ 34 - 0
cmd/docker/docker.go

@@ -3,16 +3,26 @@ package main
 import (
 import (
 	"fmt"
 	"fmt"
 	"os"
 	"os"
+	"path/filepath"
 
 
 	"github.com/Sirupsen/logrus"
 	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api/client"
 	"github.com/docker/docker/api/client"
 	"github.com/docker/docker/cli"
 	"github.com/docker/docker/cli"
+	cliflags "github.com/docker/docker/cli/flags"
+	"github.com/docker/docker/cliconfig"
 	"github.com/docker/docker/dockerversion"
 	"github.com/docker/docker/dockerversion"
 	flag "github.com/docker/docker/pkg/mflag"
 	flag "github.com/docker/docker/pkg/mflag"
 	"github.com/docker/docker/pkg/term"
 	"github.com/docker/docker/pkg/term"
 	"github.com/docker/docker/utils"
 	"github.com/docker/docker/utils"
 )
 )
 
 
+var (
+	commonFlags = cliflags.InitCommonFlags()
+	clientFlags = initClientFlags(commonFlags)
+	flHelp      = flag.Bool([]string{"h", "-help"}, false, "Print usage")
+	flVersion   = flag.Bool([]string{"v", "-version"}, false, "Print version information and quit")
+)
+
 func main() {
 func main() {
 	// Set terminal emulation based on platform as required.
 	// Set terminal emulation based on platform as required.
 	stdin, stdout, stderr := term.StdStreams()
 	stdin, stdout, stderr := term.StdStreams()
@@ -30,6 +40,7 @@ func main() {
 
 
 		help := "\nCommands:\n"
 		help := "\nCommands:\n"
 
 
+		dockerCommands := sortCommands(cli.DockerCommandUsage)
 		for _, cmd := range dockerCommands {
 		for _, cmd := range dockerCommands {
 			help += fmt.Sprintf("    %-10.10s%s\n", cmd.Name, cmd.Description)
 			help += fmt.Sprintf("    %-10.10s%s\n", cmd.Name, cmd.Description)
 		}
 		}
@@ -75,3 +86,26 @@ func showVersion() {
 		fmt.Printf("Docker version %s, build %s\n", dockerversion.Version, dockerversion.GitCommit)
 		fmt.Printf("Docker version %s, build %s\n", dockerversion.Version, dockerversion.GitCommit)
 	}
 	}
 }
 }
+
+func initClientFlags(commonFlags *cliflags.CommonFlags) *cliflags.ClientFlags {
+	clientFlags := &cliflags.ClientFlags{FlagSet: new(flag.FlagSet), Common: commonFlags}
+	client := clientFlags.FlagSet
+	client.StringVar(&clientFlags.ConfigDir, []string{"-config"}, cliconfig.ConfigDir(), "Location of client config files")
+
+	clientFlags.PostParse = func() {
+		clientFlags.Common.PostParse()
+
+		if clientFlags.ConfigDir != "" {
+			cliconfig.SetConfigDir(clientFlags.ConfigDir)
+		}
+
+		if clientFlags.Common.TrustKey == "" {
+			clientFlags.Common.TrustKey = filepath.Join(cliconfig.ConfigDir(), cliflags.DefaultTrustKeyFile)
+		}
+
+		if clientFlags.Common.Debug {
+			utils.EnableDebug()
+		}
+	}
+	return clientFlags
+}

+ 0 - 0
cmd/docker/client_test.go → cmd/docker/docker_test.go


+ 4 - 12
cmd/docker/flags.go → cmd/docker/usage.go

@@ -4,12 +4,6 @@ import (
 	"sort"
 	"sort"
 
 
 	"github.com/docker/docker/cli"
 	"github.com/docker/docker/cli"
-	flag "github.com/docker/docker/pkg/mflag"
-)
-
-var (
-	flHelp    = flag.Bool([]string{"h", "-help"}, false, "Print usage")
-	flVersion = flag.Bool([]string{"v", "-version"}, false, "Print version information and quit")
 )
 )
 
 
 type byName []cli.Command
 type byName []cli.Command
@@ -18,13 +12,11 @@ func (a byName) Len() int           { return len(a) }
 func (a byName) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
 func (a byName) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
 func (a byName) Less(i, j int) bool { return a[i].Name < a[j].Name }
 func (a byName) Less(i, j int) bool { return a[i].Name < a[j].Name }
 
 
-var dockerCommands []cli.Command
-
 // TODO(tiborvass): do not show 'daemon' on client-only binaries
 // TODO(tiborvass): do not show 'daemon' on client-only binaries
 
 
-func init() {
-	for _, cmd := range cli.DockerCommands {
-		dockerCommands = append(dockerCommands, cmd)
-	}
+func sortCommands(commands []cli.Command) []cli.Command {
+	dockerCommands := make([]cli.Command, len(commands))
+	copy(dockerCommands, commands)
 	sort.Sort(byName(dockerCommands))
 	sort.Sort(byName(dockerCommands))
+	return dockerCommands
 }
 }

+ 3 - 1
cmd/docker/flags_test.go → cmd/docker/usage_test.go

@@ -3,11 +3,13 @@ package main
 import (
 import (
 	"sort"
 	"sort"
 	"testing"
 	"testing"
+
+	"github.com/docker/docker/cli"
 )
 )
 
 
 // Tests if the subcommands of docker are sorted
 // Tests if the subcommands of docker are sorted
 func TestDockerSubcommandsAreSorted(t *testing.T) {
 func TestDockerSubcommandsAreSorted(t *testing.T) {
-	if !sort.IsSorted(byName(dockerCommands)) {
+	if !sort.IsSorted(byName(cli.DockerCommandUsage)) {
 		t.Fatal("Docker subcommands are not in sorted order")
 		t.Fatal("Docker subcommands are not in sorted order")
 	}
 	}
 }
 }

+ 2 - 3
cmd/dockerd/daemon.go

@@ -23,7 +23,6 @@ import (
 	systemrouter "github.com/docker/docker/api/server/router/system"
 	systemrouter "github.com/docker/docker/api/server/router/system"
 	"github.com/docker/docker/api/server/router/volume"
 	"github.com/docker/docker/api/server/router/volume"
 	"github.com/docker/docker/builder/dockerfile"
 	"github.com/docker/docker/builder/dockerfile"
-	"github.com/docker/docker/cli"
 	cliflags "github.com/docker/docker/cli/flags"
 	cliflags "github.com/docker/docker/cli/flags"
 	"github.com/docker/docker/cliconfig"
 	"github.com/docker/docker/cliconfig"
 	"github.com/docker/docker/daemon"
 	"github.com/docker/docker/daemon"
@@ -51,7 +50,7 @@ const (
 // DaemonCli represents the daemon CLI.
 // DaemonCli represents the daemon CLI.
 type DaemonCli struct {
 type DaemonCli struct {
 	*daemon.Config
 	*daemon.Config
-	commonFlags *cli.CommonFlags
+	commonFlags *cliflags.CommonFlags
 	configFile  *string
 	configFile  *string
 
 
 	api *apiserver.Server
 	api *apiserver.Server
@@ -346,7 +345,7 @@ func shutdownDaemon(d *daemon.Daemon, timeout time.Duration) {
 	}
 	}
 }
 }
 
 
-func loadDaemonCliConfig(config *daemon.Config, flags *flag.FlagSet, commonConfig *cli.CommonFlags, configFile string) (*daemon.Config, error) {
+func loadDaemonCliConfig(config *daemon.Config, flags *flag.FlagSet, commonConfig *cliflags.CommonFlags, configFile string) (*daemon.Config, error) {
 	config.Debug = commonConfig.Debug
 	config.Debug = commonConfig.Debug
 	config.Hosts = commonConfig.Hosts
 	config.Hosts = commonConfig.Hosts
 	config.LogLevel = commonConfig.LogLevel
 	config.LogLevel = commonConfig.LogLevel

+ 10 - 10
cmd/dockerd/daemon_test.go

@@ -7,7 +7,7 @@ import (
 	"testing"
 	"testing"
 
 
 	"github.com/Sirupsen/logrus"
 	"github.com/Sirupsen/logrus"
-	"github.com/docker/docker/cli"
+	cliflags "github.com/docker/docker/cli/flags"
 	"github.com/docker/docker/daemon"
 	"github.com/docker/docker/daemon"
 	"github.com/docker/docker/opts"
 	"github.com/docker/docker/opts"
 	"github.com/docker/docker/pkg/mflag"
 	"github.com/docker/docker/pkg/mflag"
@@ -16,7 +16,7 @@ import (
 
 
 func TestLoadDaemonCliConfigWithoutOverriding(t *testing.T) {
 func TestLoadDaemonCliConfigWithoutOverriding(t *testing.T) {
 	c := &daemon.Config{}
 	c := &daemon.Config{}
-	common := &cli.CommonFlags{
+	common := &cliflags.CommonFlags{
 		Debug: true,
 		Debug: true,
 	}
 	}
 
 
@@ -35,7 +35,7 @@ func TestLoadDaemonCliConfigWithoutOverriding(t *testing.T) {
 
 
 func TestLoadDaemonCliConfigWithTLS(t *testing.T) {
 func TestLoadDaemonCliConfigWithTLS(t *testing.T) {
 	c := &daemon.Config{}
 	c := &daemon.Config{}
-	common := &cli.CommonFlags{
+	common := &cliflags.CommonFlags{
 		TLS: true,
 		TLS: true,
 		TLSOptions: &tlsconfig.Options{
 		TLSOptions: &tlsconfig.Options{
 			CAFile: "/tmp/ca.pem",
 			CAFile: "/tmp/ca.pem",
@@ -57,7 +57,7 @@ func TestLoadDaemonCliConfigWithTLS(t *testing.T) {
 
 
 func TestLoadDaemonCliConfigWithConflicts(t *testing.T) {
 func TestLoadDaemonCliConfigWithConflicts(t *testing.T) {
 	c := &daemon.Config{}
 	c := &daemon.Config{}
-	common := &cli.CommonFlags{}
+	common := &cliflags.CommonFlags{}
 	f, err := ioutil.TempFile("", "docker-config-")
 	f, err := ioutil.TempFile("", "docker-config-")
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
@@ -93,7 +93,7 @@ func TestLoadDaemonCliConfigWithConflicts(t *testing.T) {
 
 
 func TestLoadDaemonCliConfigWithTLSVerify(t *testing.T) {
 func TestLoadDaemonCliConfigWithTLSVerify(t *testing.T) {
 	c := &daemon.Config{}
 	c := &daemon.Config{}
-	common := &cli.CommonFlags{
+	common := &cliflags.CommonFlags{
 		TLSOptions: &tlsconfig.Options{
 		TLSOptions: &tlsconfig.Options{
 			CAFile: "/tmp/ca.pem",
 			CAFile: "/tmp/ca.pem",
 		},
 		},
@@ -126,7 +126,7 @@ func TestLoadDaemonCliConfigWithTLSVerify(t *testing.T) {
 
 
 func TestLoadDaemonCliConfigWithExplicitTLSVerifyFalse(t *testing.T) {
 func TestLoadDaemonCliConfigWithExplicitTLSVerifyFalse(t *testing.T) {
 	c := &daemon.Config{}
 	c := &daemon.Config{}
-	common := &cli.CommonFlags{
+	common := &cliflags.CommonFlags{
 		TLSOptions: &tlsconfig.Options{
 		TLSOptions: &tlsconfig.Options{
 			CAFile: "/tmp/ca.pem",
 			CAFile: "/tmp/ca.pem",
 		},
 		},
@@ -159,7 +159,7 @@ func TestLoadDaemonCliConfigWithExplicitTLSVerifyFalse(t *testing.T) {
 
 
 func TestLoadDaemonCliConfigWithoutTLSVerify(t *testing.T) {
 func TestLoadDaemonCliConfigWithoutTLSVerify(t *testing.T) {
 	c := &daemon.Config{}
 	c := &daemon.Config{}
-	common := &cli.CommonFlags{
+	common := &cliflags.CommonFlags{
 		TLSOptions: &tlsconfig.Options{
 		TLSOptions: &tlsconfig.Options{
 			CAFile: "/tmp/ca.pem",
 			CAFile: "/tmp/ca.pem",
 		},
 		},
@@ -191,7 +191,7 @@ func TestLoadDaemonCliConfigWithoutTLSVerify(t *testing.T) {
 
 
 func TestLoadDaemonCliConfigWithLogLevel(t *testing.T) {
 func TestLoadDaemonCliConfigWithLogLevel(t *testing.T) {
 	c := &daemon.Config{}
 	c := &daemon.Config{}
-	common := &cli.CommonFlags{}
+	common := &cliflags.CommonFlags{}
 
 
 	f, err := ioutil.TempFile("", "docker-config-")
 	f, err := ioutil.TempFile("", "docker-config-")
 	if err != nil {
 	if err != nil {
@@ -223,7 +223,7 @@ func TestLoadDaemonCliConfigWithLogLevel(t *testing.T) {
 
 
 func TestLoadDaemonConfigWithEmbeddedOptions(t *testing.T) {
 func TestLoadDaemonConfigWithEmbeddedOptions(t *testing.T) {
 	c := &daemon.Config{}
 	c := &daemon.Config{}
-	common := &cli.CommonFlags{}
+	common := &cliflags.CommonFlags{}
 
 
 	flags := mflag.NewFlagSet("test", mflag.ContinueOnError)
 	flags := mflag.NewFlagSet("test", mflag.ContinueOnError)
 	flags.String([]string{"-tlscacert"}, "", "")
 	flags.String([]string{"-tlscacert"}, "", "")
@@ -256,7 +256,7 @@ func TestLoadDaemonConfigWithEmbeddedOptions(t *testing.T) {
 
 
 func TestLoadDaemonConfigWithRegistryOptions(t *testing.T) {
 func TestLoadDaemonConfigWithRegistryOptions(t *testing.T) {
 	c := &daemon.Config{}
 	c := &daemon.Config{}
-	common := &cli.CommonFlags{}
+	common := &cliflags.CommonFlags{}
 	flags := mflag.NewFlagSet("test", mflag.ContinueOnError)
 	flags := mflag.NewFlagSet("test", mflag.ContinueOnError)
 	c.ServiceOptions.InstallCliFlags(flags, absentFromHelp)
 	c.ServiceOptions.InstallCliFlags(flags, absentFromHelp)
 
 

+ 6 - 6
cmd/dockerd/daemon_unix_test.go

@@ -6,7 +6,7 @@ import (
 	"io/ioutil"
 	"io/ioutil"
 	"testing"
 	"testing"
 
 
-	"github.com/docker/docker/cli"
+	cliflags "github.com/docker/docker/cli/flags"
 	"github.com/docker/docker/daemon"
 	"github.com/docker/docker/daemon"
 	"github.com/docker/docker/opts"
 	"github.com/docker/docker/opts"
 	"github.com/docker/docker/pkg/mflag"
 	"github.com/docker/docker/pkg/mflag"
@@ -14,7 +14,7 @@ import (
 
 
 func TestLoadDaemonCliConfigWithDaemonFlags(t *testing.T) {
 func TestLoadDaemonCliConfigWithDaemonFlags(t *testing.T) {
 	c := &daemon.Config{}
 	c := &daemon.Config{}
-	common := &cli.CommonFlags{
+	common := &cliflags.CommonFlags{
 		Debug:    true,
 		Debug:    true,
 		LogLevel: "info",
 		LogLevel: "info",
 	}
 	}
@@ -61,7 +61,7 @@ func TestLoadDaemonCliConfigWithDaemonFlags(t *testing.T) {
 
 
 func TestLoadDaemonConfigWithNetwork(t *testing.T) {
 func TestLoadDaemonConfigWithNetwork(t *testing.T) {
 	c := &daemon.Config{}
 	c := &daemon.Config{}
-	common := &cli.CommonFlags{}
+	common := &cliflags.CommonFlags{}
 	flags := mflag.NewFlagSet("test", mflag.ContinueOnError)
 	flags := mflag.NewFlagSet("test", mflag.ContinueOnError)
 	flags.String([]string{"-bip"}, "", "")
 	flags.String([]string{"-bip"}, "", "")
 	flags.String([]string{"-ip"}, "", "")
 	flags.String([]string{"-ip"}, "", "")
@@ -92,7 +92,7 @@ func TestLoadDaemonConfigWithNetwork(t *testing.T) {
 
 
 func TestLoadDaemonConfigWithMapOptions(t *testing.T) {
 func TestLoadDaemonConfigWithMapOptions(t *testing.T) {
 	c := &daemon.Config{}
 	c := &daemon.Config{}
-	common := &cli.CommonFlags{}
+	common := &cliflags.CommonFlags{}
 	flags := mflag.NewFlagSet("test", mflag.ContinueOnError)
 	flags := mflag.NewFlagSet("test", mflag.ContinueOnError)
 
 
 	flags.Var(opts.NewNamedMapOpts("cluster-store-opts", c.ClusterOpts, nil), []string{"-cluster-store-opt"}, "")
 	flags.Var(opts.NewNamedMapOpts("cluster-store-opts", c.ClusterOpts, nil), []string{"-cluster-store-opt"}, "")
@@ -136,7 +136,7 @@ func TestLoadDaemonConfigWithMapOptions(t *testing.T) {
 
 
 func TestLoadDaemonConfigWithTrueDefaultValues(t *testing.T) {
 func TestLoadDaemonConfigWithTrueDefaultValues(t *testing.T) {
 	c := &daemon.Config{}
 	c := &daemon.Config{}
-	common := &cli.CommonFlags{}
+	common := &cliflags.CommonFlags{}
 	flags := mflag.NewFlagSet("test", mflag.ContinueOnError)
 	flags := mflag.NewFlagSet("test", mflag.ContinueOnError)
 	flags.BoolVar(&c.EnableUserlandProxy, []string{"-userland-proxy"}, true, "")
 	flags.BoolVar(&c.EnableUserlandProxy, []string{"-userland-proxy"}, true, "")
 
 
@@ -181,7 +181,7 @@ func TestLoadDaemonConfigWithTrueDefaultValues(t *testing.T) {
 
 
 func TestLoadDaemonConfigWithTrueDefaultValuesLeaveDefaults(t *testing.T) {
 func TestLoadDaemonConfigWithTrueDefaultValuesLeaveDefaults(t *testing.T) {
 	c := &daemon.Config{}
 	c := &daemon.Config{}
-	common := &cli.CommonFlags{}
+	common := &cliflags.CommonFlags{}
 	flags := mflag.NewFlagSet("test", mflag.ContinueOnError)
 	flags := mflag.NewFlagSet("test", mflag.ContinueOnError)
 	flags.BoolVar(&c.EnableUserlandProxy, []string{"-userland-proxy"}, true, "")
 	flags.BoolVar(&c.EnableUserlandProxy, []string{"-userland-proxy"}, true, "")