diff --git a/pkg/credentialprovider/config.go b/pkg/credentialprovider/config.go index 582c1ef277..ca0d8b1322 100644 --- a/pkg/credentialprovider/config.go +++ b/pkg/credentialprovider/config.go @@ -74,35 +74,24 @@ func GetPreferredDockercfgPath() string { return preferredPath } -func ReadDockerConfigFile() (cfg DockerConfig, err error) { - // Try happy path first - latest config file - dockerConfigJsonLocations := []string{GetPreferredDockercfgPath(), workingDirPath, homeJsonDirPath, rootJsonDirPath} - for _, configPath := range dockerConfigJsonLocations { - absDockerConfigFileLocation, err := filepath.Abs(filepath.Join(configPath, configJsonFileName)) - if err != nil { - glog.Errorf("while trying to canonicalize %s: %v", configPath, err) - continue - } - glog.V(4).Infof("looking for .docker/config.json at %s", absDockerConfigFileLocation) - contents, err := ioutil.ReadFile(absDockerConfigFileLocation) - if os.IsNotExist(err) { - continue - } - if err != nil { - glog.V(4).Infof("while trying to read %s: %v", absDockerConfigFileLocation, err) - continue - } - cfg, err := readDockerConfigJsonFileFromBytes(contents) - if err == nil { - glog.V(4).Infof("found .docker/config.json at %s", absDockerConfigFileLocation) - return cfg, nil - } - } - glog.V(4).Infof("couldn't find valid .docker/config.json after checking in %v", dockerConfigJsonLocations) +//DefaultDockercfgPaths returns default search paths of .dockercfg +func DefaultDockercfgPaths() []string { + return []string{GetPreferredDockercfgPath(), workingDirPath, homeDirPath, rootDirPath} +} - // Can't find latest config file so check for the old one - dockerConfigFileLocations := []string{GetPreferredDockercfgPath(), workingDirPath, homeDirPath, rootDirPath} - for _, configPath := range dockerConfigFileLocations { +//DefaultDockerConfigJSONPaths returns default search paths of .docker/config.json +func DefaultDockerConfigJSONPaths() []string { + return []string{GetPreferredDockercfgPath(), workingDirPath, homeJsonDirPath, rootJsonDirPath} +} + +// ReadDockercfgFile attempts to read a legacy dockercfg file from the given paths. +// if searchPaths is empty, the default paths are used. +func ReadDockercfgFile(searchPaths []string) (cfg DockerConfig, err error) { + if len(searchPaths) == 0 { + searchPaths = DefaultDockercfgPaths() + } + + for _, configPath := range searchPaths { absDockerConfigFileLocation, err := filepath.Abs(filepath.Join(configPath, configFileName)) if err != nil { glog.Errorf("while trying to canonicalize %s: %v", configPath, err) @@ -123,7 +112,46 @@ func ReadDockerConfigFile() (cfg DockerConfig, err error) { return cfg, nil } } - return nil, fmt.Errorf("couldn't find valid .dockercfg after checking in %v", dockerConfigFileLocations) + return nil, fmt.Errorf("couldn't find valid .dockercfg after checking in %v", searchPaths) +} + +// ReadDockerConfigJSONFile attempts to read a docker config.json file from the given paths. +// if searchPaths is empty, the default paths are used. +func ReadDockerConfigJSONFile(searchPaths []string) (cfg DockerConfig, err error) { + if len(searchPaths) == 0 { + searchPaths = DefaultDockerConfigJSONPaths() + } + + for _, configPath := range searchPaths { + absDockerConfigFileLocation, err := filepath.Abs(filepath.Join(configPath, configJsonFileName)) + if err != nil { + glog.Errorf("while trying to canonicalize %s: %v", configPath, err) + continue + } + glog.V(4).Infof("looking for .docker/config.json at %s", absDockerConfigFileLocation) + contents, err := ioutil.ReadFile(absDockerConfigFileLocation) + if os.IsNotExist(err) { + continue + } + if err != nil { + glog.V(4).Infof("while trying to read %s: %v", absDockerConfigFileLocation, err) + continue + } + cfg, err := readDockerConfigJsonFileFromBytes(contents) + if err == nil { + glog.V(4).Infof("found .docker/config.json at %s", absDockerConfigFileLocation) + return cfg, nil + } + } + return nil, fmt.Errorf("couldn't find valid .docker/config.json after checking in %v", searchPaths) +} + +func ReadDockerConfigFile() (cfg DockerConfig, err error) { + if cfg, err := ReadDockerConfigJSONFile(nil); err == nil { + return cfg, nil + } + // Can't find latest config file so check for the old one + return ReadDockercfgFile(nil) } // HttpError wraps a non-StatusOK error code as an error. diff --git a/pkg/credentialprovider/config_test.go b/pkg/credentialprovider/config_test.go index 9111aab63e..c5f73cafdb 100644 --- a/pkg/credentialprovider/config_test.go +++ b/pkg/credentialprovider/config_test.go @@ -18,10 +18,51 @@ package credentialprovider import ( "encoding/json" + "io/ioutil" + "os" + "path/filepath" "reflect" "testing" ) +func TestReadDockerConfigFile(t *testing.T) { + configJsonFileName := "config.json" + var fileInfo *os.File + preferredPaths := []string{} + + //test dockerconfig json + inputDockerconfigJsonFile := "{ \"auths\": { \"http://foo.example.com\":{\"auth\":\"Zm9vOmJhcgo=\",\"email\":\"foo@example.com\"}}}" + + preferredPath, err := ioutil.TempDir("", "test_foo_bar_dockerconfigjson_") + if err != nil { + t.Fatalf("Creating tmp dir fail: %v", err) + return + } + defer os.RemoveAll(preferredPath) + preferredPaths = append(preferredPaths, preferredPath) + absDockerConfigFileLocation, err := filepath.Abs(filepath.Join(preferredPath, configJsonFileName)) + if err != nil { + t.Fatalf("While trying to canonicalize %s: %v", preferredPath, err) + } + + if _, err := os.Stat(absDockerConfigFileLocation); os.IsNotExist(err) { + //create test cfg file + fileInfo, err = os.OpenFile(absDockerConfigFileLocation, os.O_CREATE|os.O_RDWR, 0664) + if err != nil { + t.Fatalf("While trying to create file %s: %v", absDockerConfigFileLocation, err) + } + defer fileInfo.Close() + } + + fileInfo.WriteString(inputDockerconfigJsonFile) + + orgPreferredPath := GetPreferredDockercfgPath() + SetPreferredDockercfgPath(preferredPath) + defer SetPreferredDockercfgPath(orgPreferredPath) + if _, err := ReadDockerConfigFile(); err != nil { + t.Errorf("Getting docker config file fail : %v preferredPath : %q", err, preferredPath) + } +} func TestDockerConfigJsonJSONDecode(t *testing.T) { input := []byte(`{"auths": {"http://foo.example.com":{"username": "foo", "password": "bar", "email": "foo@example.com"}, "http://bar.example.com":{"username": "bar", "password": "baz", "email": "bar@example.com"}}}`)