diff --git a/cli/config/config.go b/cli/config/config.go index 98147e270a..3f208f9c88 100644 --- a/cli/config/config.go +++ b/cli/config/config.go @@ -24,12 +24,12 @@ const ( ) var ( - initConfigDir sync.Once + initConfigDir = new(sync.Once) configDir string homeDir string ) -// resetHomeDir is used in testing to resets the "homeDir" package variable to +// resetHomeDir is used in testing to reset the "homeDir" package variable to // force re-lookup of the home directory between tests. func resetHomeDir() { homeDir = "" @@ -42,6 +42,13 @@ func getHomeDir() string { return homeDir } +// resetConfigDir is used in testing to reset the "configDir" package variable +// and its sync.Once to force re-lookup between tests. +func resetConfigDir() { + configDir = "" + initConfigDir = new(sync.Once) +} + func setConfigDir() { if configDir != "" { return @@ -97,10 +104,20 @@ func LoadFromReader(configData io.Reader) (*configfile.ConfigFile, error) { return &configFile, err } +// TODO remove this temporary hack, which is used to warn about the deprecated ~/.dockercfg file +var ( + mutex sync.RWMutex + printLegacyFileWarning bool +) + // Load reads the configuration files in the given directory, and sets up // the auth config information and returns values. // FIXME: use the internal golang config parser func Load(configDir string) (*configfile.ConfigFile, error) { + mutex.Lock() + printLegacyFileWarning = false + mutex.Unlock() + if configDir == "" { configDir = Dir() } @@ -125,6 +142,9 @@ func Load(configDir string) (*configfile.ConfigFile, error) { // Can't find latest config file so check for the old one filename = filepath.Join(getHomeDir(), oldConfigfile) if file, err := os.Open(filename); err == nil { + mutex.Lock() + printLegacyFileWarning = true + mutex.Unlock() defer file.Close() if err := configFile.LegacyLoadFromReader(file); err != nil { return configFile, errors.Wrap(err, filename) @@ -140,6 +160,11 @@ func LoadDefaultConfigFile(stderr io.Writer) *configfile.ConfigFile { if err != nil { fmt.Fprintf(stderr, "WARNING: Error loading config file: %v\n", err) } + mutex.RLock() + defer mutex.RUnlock() + if printLegacyFileWarning { + _, _ = fmt.Fprintln(stderr, "WARNING: Support for the legacy ~/.dockercfg configuration file and file-format is deprecated and will be removed in an upcoming release") + } if !configFile.ContainsAuth() { configFile.CredentialsStore = credentials.DetectDefaultStore(configFile.CredentialsStore) } diff --git a/cli/config/config_test.go b/cli/config/config_test.go index c7787bb5d1..26197454e6 100644 --- a/cli/config/config_test.go +++ b/cli/config/config_test.go @@ -12,9 +12,11 @@ import ( "github.com/docker/cli/cli/config/configfile" "github.com/docker/cli/cli/config/credentials" + "github.com/docker/cli/cli/config/types" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" "gotest.tools/v3/env" + "gotest.tools/v3/fs" ) var homeKey = "HOME" @@ -223,6 +225,31 @@ func TestOldJSON(t *testing.T) { } } +func TestOldJSONFallbackDeprecationWarning(t *testing.T) { + js := `{"https://index.docker.io/v1/":{"auth":"am9lam9lOmhlbGxv","email":"user@example.com"}}` + tmpHome := fs.NewDir(t, t.Name(), fs.WithFile(oldConfigfile, js)) + defer tmpHome.Remove() + defer env.PatchAll(t, map[string]string{homeKey: tmpHome.Path(), "DOCKER_CONFIG": ""})() + + // reset the homeDir, configDir, and its sync.Once, to force them being resolved again + resetHomeDir() + resetConfigDir() + + buffer := new(bytes.Buffer) + configFile := LoadDefaultConfigFile(buffer) + expected := configfile.New(tmpHome.Join(configFileDir, ConfigFileName)) + expected.AuthConfigs = map[string]types.AuthConfig{ + "https://index.docker.io/v1/": { + Username: "joejoe", + Password: "hello", + Email: "user@example.com", + ServerAddress: "https://index.docker.io/v1/", + }, + } + assert.Assert(t, strings.Contains(buffer.String(), "WARNING: Support for the legacy ~/.dockercfg configuration file and file-format is deprecated and will be removed in an upcoming release")) + assert.Check(t, is.DeepEqual(expected, configFile)) +} + func TestNewJSON(t *testing.T) { tmpHome, err := ioutil.TempDir("", "config-test") assert.NilError(t, err) diff --git a/cmd/docker/docker_test.go b/cmd/docker/docker_test.go index 388eb2af85..0acca1b6b1 100644 --- a/cmd/docker/docker_test.go +++ b/cmd/docker/docker_test.go @@ -17,7 +17,9 @@ import ( func TestClientDebugEnabled(t *testing.T) { defer debug.Disable() - tcmd := newDockerCommand(&command.DockerCli{}) + cli, err := command.NewDockerCli() + assert.NilError(t, err) + tcmd := newDockerCommand(cli) tcmd.SetFlag("debug", "true") cmd, _, err := tcmd.HandleGlobalFlags() assert.NilError(t, err)