From 379122b033774d00b3d223fee8d62b0ed4b917e3 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Wed, 10 May 2023 10:46:48 +0200 Subject: [PATCH] cli/config: remove warning for deprecated ~/.dockercfg file The `~/.dockercfg` file was replaced by `~/.docker/config.json` in 2015 (github.com/docker/docker/commit/18c9b6c6455f116ae59cde8544413b3d7d294a5e). Commit b83bc67136e1edce2bdc225863af83d45d5472c9 (v23.0.0, but backported to v20.10) added a warning if no "current" config file was found but a legacy file was, and if the CLI would fall back to using the deprecated file. Commit ee218fa89e58c7296805fe7396cee959d74ce64b removed support for the legacy file, but kept a warning in place if a legacy file was in place, and now ignored. This patch removes the warning as well, fully deprecating the legacy `~/.dockercfg` file. Signed-off-by: Sebastiaan van Stijn --- cli/config/config.go | 86 +++++++++++---------------------------- cli/config/config_test.go | 30 -------------- docs/deprecated.md | 3 -- 3 files changed, 24 insertions(+), 95 deletions(-) diff --git a/cli/config/config.go b/cli/config/config.go index c3694fadc7..cbcdbc1858 100644 --- a/cli/config/config.go +++ b/cli/config/config.go @@ -19,49 +19,22 @@ const ( // ConfigFileName is the name of config file ConfigFileName = "config.json" configFileDir = ".docker" - oldConfigfile = ".dockercfg" // Deprecated: remove once we stop printing deprecation warning contextsDir = "contexts" ) var ( initConfigDir = new(sync.Once) configDir string - homeDir string ) -// resetHomeDir is used in testing to reset the "homeDir" package variable to -// force re-lookup of the home directory between tests. -func resetHomeDir() { - homeDir = "" -} - -func getHomeDir() string { - if homeDir == "" { - homeDir = homedir.Get() - } - 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 - } - configDir = os.Getenv("DOCKER_CONFIG") - if configDir == "" { - configDir = filepath.Join(getHomeDir(), configFileDir) - } -} - // Dir returns the directory the configuration file is stored in func Dir() string { - initConfigDir.Do(setConfigDir) + initConfigDir.Do(func() { + configDir = os.Getenv("DOCKER_CONFIG") + if configDir == "" { + configDir = filepath.Join(homedir.Get(), configFileDir) + } + }) return configDir } @@ -97,53 +70,42 @@ func LoadFromReader(configData io.Reader) (*configfile.ConfigFile, error) { // Load reads the configuration files in the given directory, and sets up // the auth config information and returns values. func Load(configDir string) (*configfile.ConfigFile, error) { - cfg, _, err := load(configDir) - return cfg, err -} - -// TODO remove this temporary hack, which is used to warn about the deprecated ~/.dockercfg file -// so we can remove the bool return value and collapse this back into `Load` -func load(configDir string) (*configfile.ConfigFile, bool, error) { - printLegacyFileWarning := false - if configDir == "" { configDir = Dir() } + return load(configDir) +} +func load(configDir string) (*configfile.ConfigFile, error) { filename := filepath.Join(configDir, ConfigFileName) configFile := configfile.New(filename) - // Try happy path first - latest config file - if file, err := os.Open(filename); err == nil { - defer file.Close() - err = configFile.LoadFromReader(file) - if err != nil { - err = errors.Wrap(err, filename) + file, err := os.Open(filename) + if err != nil { + if os.IsNotExist(err) { + // + // if file is there but we can't stat it for any reason other + // than it doesn't exist then stop + return configFile, nil } - return configFile, printLegacyFileWarning, err - } else if !os.IsNotExist(err) { // if file is there but we can't stat it for any reason other // than it doesn't exist then stop - return configFile, printLegacyFileWarning, errors.Wrap(err, filename) + return configFile, nil } - - // Can't find latest config file so check for the old one - filename = filepath.Join(getHomeDir(), oldConfigfile) - if _, err := os.Stat(filename); err == nil { - printLegacyFileWarning = true + defer file.Close() + err = configFile.LoadFromReader(file) + if err != nil { + err = errors.Wrap(err, filename) } - return configFile, printLegacyFileWarning, nil + return configFile, err } // LoadDefaultConfigFile attempts to load the default config file and returns // an initialized ConfigFile struct if none is found. func LoadDefaultConfigFile(stderr io.Writer) *configfile.ConfigFile { - configFile, printLegacyFileWarning, err := load(Dir()) + configFile, err := load(Dir()) if err != nil { - fmt.Fprintf(stderr, "WARNING: Error loading config file: %v\n", err) - } - if printLegacyFileWarning { - _, _ = fmt.Fprintln(stderr, "WARNING: Support for the legacy ~/.dockercfg configuration file and file-format has been removed and the configuration file will be ignored") + _, _ = fmt.Fprintf(stderr, "WARNING: Error loading config file: %v\n", err) } if !configFile.ContainsAuth() { configFile.CredentialsStore = credentials.DetectDefaultStore(configFile.CredentialsStore) diff --git a/cli/config/config_test.go b/cli/config/config_test.go index c98017bd59..33c9b83177 100644 --- a/cli/config/config_test.go +++ b/cli/config/config_test.go @@ -5,27 +5,15 @@ import ( "fmt" "os" "path/filepath" - "runtime" "strings" "testing" "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" - -func init() { - if runtime.GOOS == "windows" { - homeKey = "USERPROFILE" - } -} - func setupConfigDir(t *testing.T) string { tmpdir := t.TempDir() oldDir := Dir() @@ -93,24 +81,6 @@ func TestEmptyJSON(t *testing.T) { saveConfigAndValidateNewFormat(t, config, tmpHome) } -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() - 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{} - assert.Assert(t, strings.Contains(buffer.String(), "WARNING: Support for the legacy ~/.dockercfg configuration file and file-format has been removed and the configuration file will be ignored")) - assert.Check(t, is.DeepEqual(expected, configFile)) -} - func TestNewJSON(t *testing.T) { tmpHome := t.TempDir() diff --git a/docs/deprecated.md b/docs/deprecated.md index dd69b278a8..cadb37bbc8 100644 --- a/docs/deprecated.md +++ b/docs/deprecated.md @@ -380,9 +380,6 @@ Given that the old file format encourages insecure storage of credentials Docker v1.7.0 has created this file, support for this file, and its format has been removed. -A warning is printed in situations where the CLI would fall back to the old file, -notifying the user that the legacy file is present, but ignored. - ### Configuration options for experimental CLI features **Deprecated in Release: v19.03**