diff --git a/cliconfig/config.go b/cliconfig/config.go index f5b2be8a40..710dca7a2d 100644 --- a/cliconfig/config.go +++ b/cliconfig/config.go @@ -29,9 +29,20 @@ var ( configDir = os.Getenv("DOCKER_CONFIG") ) +func getDefaultConfigDir(confFile string) string { + confDir := filepath.Join(homedir.Get(), confFile) + // if the directory doesn't exist, maybe we called docker with sudo + if _, err := os.Stat(configDir); err != nil { + if os.IsNotExist(err) { + return filepath.Join(homedir.GetWithSudoUser(), confFile) + } + } + return confDir +} + func init() { if configDir == "" { - configDir = filepath.Join(homedir.Get(), ".docker") + configDir = getDefaultConfigDir(".docker") } } @@ -178,7 +189,7 @@ func Load(configDir string) (*ConfigFile, error) { } // Can't find latest config file so check for the old one - confFile := filepath.Join(homedir.Get(), oldConfigfile) + confFile := getDefaultConfigDir(oldConfigfile) if _, err := os.Stat(confFile); err != nil { return &configFile, nil //missing file is not an error } diff --git a/docs/reference/commandline/cli.md b/docs/reference/commandline/cli.md index 96486d73d9..95a3c07bb6 100644 --- a/docs/reference/commandline/cli.md +++ b/docs/reference/commandline/cli.md @@ -78,6 +78,9 @@ For example: Instructs Docker to use the configuration files in your `~/testconfigs/` directory when running the `ps` command. +> **Note**: If you run docker commands with `sudo`, Docker first looks for a configuration +> file in `/root/.docker/`, before looking in `~/.docker/` for the user that did the sudo call. + Docker manages most of the files in the configuration directory and you should not modify them. However, you *can modify* the `config.json` file to control certain aspects of how the `docker` diff --git a/image/v1/imagev1.go b/image/v1/imagev1.go index cc76fbfeec..1e45b62bd9 100644 --- a/image/v1/imagev1.go +++ b/image/v1/imagev1.go @@ -142,7 +142,7 @@ func rawJSON(value interface{}) *json.RawMessage { // ValidateID checks whether an ID string is a valid image ID. func ValidateID(id string) error { if ok := validHex.MatchString(id); !ok { - return fmt.Errorf("image ID '%s' is invalid ", id) + return fmt.Errorf("image ID %q is invalid", id) } return nil } diff --git a/pkg/homedir/homedir.go b/pkg/homedir/homedir.go index 8154e83f0c..b8d9a93c9b 100644 --- a/pkg/homedir/homedir.go +++ b/pkg/homedir/homedir.go @@ -29,6 +29,19 @@ func Get() string { return home } +// GetWithSudoUser returns the home directory of the user who called sudo (if +// available, retrieved from $SUDO_USER). It fallbacks to Get if any error occurs. +// Returned path should be used with "path/filepath" to form new paths. +func GetWithSudoUser() string { + sudoUser := os.Getenv("SUDO_USER") + if sudoUser != "" { + if user, err := user.LookupUser(sudoUser); err == nil { + return user.Home + } + } + return Get() +} + // GetShortcutString returns the string that is shortcut to user's home directory // in the native shell of the platform running on. func GetShortcutString() string {