func NewHyperClient(proto, addr string, tlsConfig *tls.Config) *HyperClient { var ( inFd uintptr outFd uintptr isTerminalIn = false isTerminalOut = false scheme = "http" ) if tlsConfig != nil { scheme = "https" } // The transport is created here for reuse during the client session tran := &http.Transport{ TLSClientConfig: tlsConfig, } // Why 32? See issue 8035 timeout := 32 * time.Second if proto == "unix" { // no need in compressing for local communications tran.DisableCompression = true tran.Dial = func(_, _ string) (net.Conn, error) { return net.DialTimeout(proto, addr, timeout) } } else { tran.Proxy = http.ProxyFromEnvironment tran.Dial = (&net.Dialer{Timeout: timeout}).Dial } inFd, isTerminalIn = term.GetFdInfo(os.Stdin) outFd, isTerminalOut = term.GetFdInfo(os.Stdout) clifile, err := cliconfig.Load(filepath.Join(homedir.Get(), ".docker")) if err != nil { fmt.Fprintf(os.Stdout, "WARNING: Error loading config file %v\n", err) } return &HyperClient{ proto: proto, addr: addr, configFile: clifile, in: os.Stdin, out: os.Stdout, err: os.Stdout, inFd: inFd, outFd: outFd, isTerminalIn: isTerminalIn, isTerminalOut: isTerminalOut, scheme: scheme, transport: tran, } }
func TestOldJson(t *testing.T) { if runtime.GOOS == "windows" { return } tmpHome, _ := ioutil.TempDir("", "config-test") defer os.RemoveAll(tmpHome) homeKey := homedir.Key() homeVal := homedir.Get() defer func() { os.Setenv(homeKey, homeVal) }() os.Setenv(homeKey, tmpHome) fn := filepath.Join(tmpHome, OLD_CONFIGFILE) js := `{"https://index.docker.io/v1/":{"auth":"am9lam9lOmhlbGxv","email":"*****@*****.**"}}` ioutil.WriteFile(fn, []byte(js), 0600) config, err := Load(tmpHome) if err != nil { t.Fatalf("Failed loading on empty json file: %q", err) } ac := config.AuthConfigs["https://index.docker.io/v1/"] if ac.Email != "*****@*****.**" || ac.Username != "joejoe" || ac.Password != "hello" { t.Fatalf("Missing data from parsing:\n%q", config) } // Now save it and make sure it shows up in new form err = config.Save() if err != nil { t.Fatalf("Failed to save: %q", err) } buf, err := ioutil.ReadFile(filepath.Join(tmpHome, CONFIGFILE)) if !strings.Contains(string(buf), `"auths":`) || !strings.Contains(string(buf), "*****@*****.**") { t.Fatalf("Should have save in new form: %s", string(buf)) } }
func migrateKey() (err error) { // Migrate trust key if exists at ~/.docker/key.json and owned by current user oldPath := filepath.Join(homedir.Get(), ".docker", defaultTrustKeyFile) newPath := filepath.Join(getDaemonConfDir(), defaultTrustKeyFile) if _, statErr := os.Stat(newPath); os.IsNotExist(statErr) && currentUserIsOwner(oldPath) { defer func() { // Ensure old path is removed if no error occurred if err == nil { err = os.Remove(oldPath) } else { glog.Warningf("Key migration failed, key file not removed at %s", oldPath) } }() if err := os.MkdirAll(getDaemonConfDir(), os.FileMode(0644)); err != nil { return fmt.Errorf("Unable to create daemon configuration directory: %s", err) } newFile, err := os.OpenFile(newPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600) if err != nil { return fmt.Errorf("error creating key file %q: %s", newPath, err) } defer newFile.Close() oldFile, err := os.Open(oldPath) if err != nil { return fmt.Errorf("error opening key file %q: %s", oldPath, err) } defer oldFile.Close() if _, err := io.Copy(newFile, oldFile); err != nil { return fmt.Errorf("error copying key: %s", err) } glog.Infof("Migrated key from %s to %s", oldPath, newPath) } return nil }
// load up the auth config information and return values // FIXME: use the internal golang config parser func Load(configDir string) (*ConfigFile, error) { if configDir == "" { configDir = filepath.Join(homedir.Get(), ".docker") } configFile := ConfigFile{ AuthConfigs: make(map[string]AuthConfig), filename: filepath.Join(configDir, CONFIGFILE), } // Try happy path first - latest config file if _, err := os.Stat(configFile.filename); err == nil { file, err := os.Open(configFile.filename) if err != nil { return &configFile, err } defer file.Close() if err := json.NewDecoder(file).Decode(&configFile); err != nil { return &configFile, err } for addr, ac := range configFile.AuthConfigs { ac.Username, ac.Password, err = DecodeAuth(ac.Auth) if err != nil { return &configFile, err } ac.Auth = "" ac.ServerAddress = addr configFile.AuthConfigs[addr] = ac } return &configFile, nil } 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, err } // Can't find latest config file so check for the old one confFile := filepath.Join(homedir.Get(), OLD_CONFIGFILE) if _, err := os.Stat(confFile); err != nil { return &configFile, nil //missing file is not an error } b, err := ioutil.ReadFile(confFile) if err != nil { return &configFile, err } if err := json.Unmarshal(b, &configFile.AuthConfigs); err != nil { arr := strings.Split(string(b), "\n") if len(arr) < 2 { return &configFile, fmt.Errorf("The Auth config file is empty") } authConfig := AuthConfig{} origAuth := strings.Split(arr[0], " = ") if len(origAuth) != 2 { return &configFile, fmt.Errorf("Invalid Auth config file") } authConfig.Username, authConfig.Password, err = DecodeAuth(origAuth[1]) if err != nil { return &configFile, err } origEmail := strings.Split(arr[1], " = ") if len(origEmail) != 2 { return &configFile, fmt.Errorf("Invalid Auth config file") } authConfig.Email = origEmail[1] authConfig.ServerAddress = DEFAULT_INDEXSERVER configFile.AuthConfigs[DEFAULT_INDEXSERVER] = authConfig } else { for k, authConfig := range configFile.AuthConfigs { authConfig.Username, authConfig.Password, err = DecodeAuth(authConfig.Auth) if err != nil { return &configFile, err } authConfig.Auth = "" authConfig.ServerAddress = k configFile.AuthConfigs[k] = authConfig } } return &configFile, nil }