github.com/ali-iotechsys/cli@v20.10.0+incompatible/cli/config/config.go (about) 1 package config 2 3 import ( 4 "fmt" 5 "io" 6 "os" 7 "path/filepath" 8 "strings" 9 "sync" 10 11 "github.com/docker/cli/cli/config/configfile" 12 "github.com/docker/cli/cli/config/credentials" 13 "github.com/docker/cli/cli/config/types" 14 "github.com/docker/docker/pkg/homedir" 15 "github.com/pkg/errors" 16 ) 17 18 const ( 19 // ConfigFileName is the name of config file 20 ConfigFileName = "config.json" 21 configFileDir = ".docker" 22 oldConfigfile = ".dockercfg" 23 contextsDir = "contexts" 24 ) 25 26 var ( 27 initConfigDir sync.Once 28 configDir string 29 ) 30 31 func setConfigDir() { 32 if configDir != "" { 33 return 34 } 35 configDir = os.Getenv("DOCKER_CONFIG") 36 if configDir == "" { 37 configDir = filepath.Join(homedir.Get(), configFileDir) 38 } 39 } 40 41 // Dir returns the directory the configuration file is stored in 42 func Dir() string { 43 initConfigDir.Do(setConfigDir) 44 return configDir 45 } 46 47 // ContextStoreDir returns the directory the docker contexts are stored in 48 func ContextStoreDir() string { 49 return filepath.Join(Dir(), contextsDir) 50 } 51 52 // SetDir sets the directory the configuration file is stored in 53 func SetDir(dir string) { 54 configDir = filepath.Clean(dir) 55 } 56 57 // Path returns the path to a file relative to the config dir 58 func Path(p ...string) (string, error) { 59 path := filepath.Join(append([]string{Dir()}, p...)...) 60 if !strings.HasPrefix(path, Dir()+string(filepath.Separator)) { 61 return "", errors.Errorf("path %q is outside of root config directory %q", path, Dir()) 62 } 63 return path, nil 64 } 65 66 // LegacyLoadFromReader is a convenience function that creates a ConfigFile object from 67 // a non-nested reader 68 func LegacyLoadFromReader(configData io.Reader) (*configfile.ConfigFile, error) { 69 configFile := configfile.ConfigFile{ 70 AuthConfigs: make(map[string]types.AuthConfig), 71 } 72 err := configFile.LegacyLoadFromReader(configData) 73 return &configFile, err 74 } 75 76 // LoadFromReader is a convenience function that creates a ConfigFile object from 77 // a reader 78 func LoadFromReader(configData io.Reader) (*configfile.ConfigFile, error) { 79 configFile := configfile.ConfigFile{ 80 AuthConfigs: make(map[string]types.AuthConfig), 81 } 82 err := configFile.LoadFromReader(configData) 83 return &configFile, err 84 } 85 86 // Load reads the configuration files in the given directory, and sets up 87 // the auth config information and returns values. 88 // FIXME: use the internal golang config parser 89 func Load(configDir string) (*configfile.ConfigFile, error) { 90 if configDir == "" { 91 configDir = Dir() 92 } 93 94 filename := filepath.Join(configDir, ConfigFileName) 95 configFile := configfile.New(filename) 96 97 // Try happy path first - latest config file 98 if file, err := os.Open(filename); err == nil { 99 defer file.Close() 100 err = configFile.LoadFromReader(file) 101 if err != nil { 102 err = errors.Wrap(err, filename) 103 } 104 return configFile, err 105 } else if !os.IsNotExist(err) { 106 // if file is there but we can't stat it for any reason other 107 // than it doesn't exist then stop 108 return configFile, errors.Wrap(err, filename) 109 } 110 111 // Can't find latest config file so check for the old one 112 home, err := os.UserHomeDir() 113 if err != nil { 114 return configFile, errors.Wrap(err, oldConfigfile) 115 } 116 filename = filepath.Join(home, oldConfigfile) 117 if file, err := os.Open(filename); err == nil { 118 defer file.Close() 119 if err := configFile.LegacyLoadFromReader(file); err != nil { 120 return configFile, errors.Wrap(err, filename) 121 } 122 } 123 return configFile, nil 124 } 125 126 // LoadDefaultConfigFile attempts to load the default config file and returns 127 // an initialized ConfigFile struct if none is found. 128 func LoadDefaultConfigFile(stderr io.Writer) *configfile.ConfigFile { 129 configFile, err := Load(Dir()) 130 if err != nil { 131 fmt.Fprintf(stderr, "WARNING: Error loading config file: %v\n", err) 132 } 133 if !configFile.ContainsAuth() { 134 configFile.CredentialsStore = credentials.DetectDefaultStore(configFile.CredentialsStore) 135 } 136 return configFile 137 }