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  }