Beispiel #1
0
func getDaemonConfDir() string {
	// TODO: update for Windows daemon
	if runtime.GOOS == "windows" {
		return filepath.Join(homedir.Get(), ".docker")
	}
	return "/etc/docker"
}
Beispiel #2
0
func (cli *DockerCli) LoadConfigFile() (err error) {
	cli.configFile, err = registry.LoadConfig(homedir.Get())
	if err != nil {
		fmt.Fprintf(cli.err, "WARNING: %s\n", err)
	}
	return err
}
Beispiel #3
0
func NewHyperClient(proto, addr string, tlsConfig *tls.Config) *HyperClient {
	var (
		inFd          uintptr
		outFd         uintptr
		isTerminalIn  = false
		isTerminalOut = false
	)

	clifile, err := cliconfig.Load(filepath.Join(homedir.Get(), ".docker"))
	if err != nil {
		fmt.Fprintf(os.Stdout, "WARNING: Error loading config file %v\n", err)
	}

	inFd, isTerminalIn = term.GetFdInfo(os.Stdin)
	outFd, isTerminalOut = term.GetFdInfo(os.Stdout)

	return &HyperClient{
		client:        api.NewClient(proto, addr, tlsConfig),
		in:            os.Stdin,
		out:           os.Stdout,
		err:           os.Stdout,
		inFd:          inFd,
		outFd:         outFd,
		isTerminalIn:  isTerminalIn,
		isTerminalOut: isTerminalOut,
		configFile:    clifile,
	}
}
Beispiel #4
0
func TestOldInvalidsAuth(t *testing.T) {
	invalids := map[string]string{
		`username = test`: "The Auth config file is empty",
		`username
password`: "Invalid Auth config file",
		`username = test
email`: "Invalid auth configuration file",
	}

	tmpHome, err := ioutil.TempDir("", "config-test")
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(tmpHome)

	homeKey := homedir.Key()
	homeVal := homedir.Get()

	defer func() { os.Setenv(homeKey, homeVal) }()
	os.Setenv(homeKey, tmpHome)

	for content, expectedError := range invalids {
		fn := filepath.Join(tmpHome, oldConfigfile)
		if err := ioutil.WriteFile(fn, []byte(content), 0600); err != nil {
			t.Fatal(err)
		}

		config, err := Load(tmpHome)
		// Use Contains instead of == since the file name will change each time
		if err == nil || !strings.Contains(err.Error(), expectedError) {
			t.Fatalf("Should have failed\nConfig: %v\nGot: %v\nExpected: %v", config, err, expectedError)
		}

	}
}
Beispiel #5
0
// preload initializes any global options and configuration
// before the main or sub commands are run
func preload(c *cli.Context) (err error) {
	if c.GlobalBool("debug") {
		logrus.SetLevel(logrus.DebugLevel)
	}

	defaultGPGKey = c.GlobalString("keyid")

	home := homedir.Get()
	homeShort := homedir.GetShortcutString()

	// set the filestore variable
	filestore = strings.Replace(c.GlobalString("file"), homeShort, home, 1)

	// set gpg path variables
	gpgPath = strings.Replace(c.GlobalString("gpgpath"), homeShort, home, 1)
	publicKeyring = filepath.Join(gpgPath, "pubring.gpg")
	secretKeyring = filepath.Join(gpgPath, "secring.gpg")

	// if they passed an arguement, run the prechecks
	// TODO(jfrazelle): this will run even if the command they issue
	// does not exist, which is kinda shitty
	if len(c.Args()) > 0 {
		preChecks()
	}

	// we need to read the secrets file for all commands
	// might as well be dry about it
	s, err = readSecretsFile(filestore)
	if err != nil {
		logrus.Fatal(err)
	}

	return nil
}
Beispiel #6
0
func TestOldJSONInvalid(t *testing.T) {
	tmpHome, err := ioutil.TempDir("", "config-test")
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(tmpHome)

	homeKey := homedir.Key()
	homeVal := homedir.Get()

	defer func() { os.Setenv(homeKey, homeVal) }()
	os.Setenv(homeKey, tmpHome)

	fn := filepath.Join(tmpHome, oldConfigfile)
	js := `{"https://index.docker.io/v1/":{"auth":"test","email":"*****@*****.**"}}`
	if err := ioutil.WriteFile(fn, []byte(js), 0600); err != nil {
		t.Fatal(err)
	}

	config, err := Load(tmpHome)
	// Use Contains instead of == since the file name will change each time
	if err == nil || !strings.Contains(err.Error(), "Invalid auth configuration file") {
		t.Fatalf("Expected an error got : %v, %v", config, err)
	}
}
Beispiel #7
0
// PrintDefaults prints, to standard error unless configured
// otherwise, the default values of all defined flags in the set.
func (f *FlagSet) PrintDefaults() {
	writer := tabwriter.NewWriter(f.Out(), 20, 1, 3, ' ', 0)
	home := homedir.Get()

	// Don't substitute when HOME is /
	if runtime.GOOS != "windows" && home == "/" {
		home = ""
	}
	f.VisitAll(func(flag *Flag) {
		format := "  -%s=%s"
		names := []string{}
		for _, name := range flag.Names {
			if name[0] != '#' {
				names = append(names, name)
			}
		}
		if len(names) > 0 {
			val := flag.DefValue

			if home != "" && strings.HasPrefix(val, home) {
				val = homedir.GetShortcutString() + val[len(home):]
			}

			fmt.Fprintf(writer, format, strings.Join(names, ", -"), val)
			for i, line := range strings.Split(flag.Usage, "\n") {
				if i != 0 {
					line = "  " + line
				}
				fmt.Fprintln(writer, "\t", line)
			}
		}
	})
	writer.Flush()
}
func (s *executor) getAuthConfig(imageName string) (docker.AuthConfiguration, error) {
	homeDir := homedir.Get()
	if s.Shell().User != "" {
		u, err := user.Lookup(s.Shell().User)
		if err != nil {
			return docker.AuthConfiguration{}, err
		}
		homeDir = u.HomeDir
	}
	if homeDir == "" {
		return docker.AuthConfiguration{}, fmt.Errorf("Failed to get home directory")
	}

	indexName, _ := docker_helpers.SplitDockerImageName(imageName)

	authConfigs, err := docker_helpers.ReadDockerAuthConfigs(homeDir)
	if err != nil {
		// ignore doesn't exist errors
		if os.IsNotExist(err) {
			err = nil
		}
		return docker.AuthConfiguration{}, err
	}

	authConfig := docker_helpers.ResolveDockerAuthConfig(indexName, authConfigs)
	if authConfig != nil {
		s.Debugln("Using", authConfig.Username, "to connect to", authConfig.ServerAddress, "in order to resolve", imageName, "...")
		return *authConfig, nil
	}

	return docker.AuthConfiguration{}, fmt.Errorf("No credentials found for %v", indexName)
}
Beispiel #9
0
func getDockerEnv() (*dockerEnv, error) {
	dockerHost := os.Getenv("DOCKER_HOST")
	var err error
	if dockerHost == "" {
		dockerHost, err = getDefaultDockerHost()
		if err != nil {
			return nil, err
		}
	}
	dockerTLSVerify := os.Getenv("DOCKER_TLS_VERIFY") != ""
	var dockerCertPath string
	if dockerTLSVerify {
		dockerCertPath = os.Getenv("DOCKER_CERT_PATH")
		if dockerCertPath == "" {
			home := homedir.Get()
			if home == "" {
				return nil, errors.New("environment variable HOME must be set if DOCKER_CERT_PATH is not set")
			}
			dockerCertPath = filepath.Join(home, ".docker")
			dockerCertPath, err = filepath.Abs(dockerCertPath)
			if err != nil {
				return nil, err
			}
		}
	}
	return &dockerEnv{
		dockerHost:      dockerHost,
		dockerTLSVerify: dockerTLSVerify,
		dockerCertPath:  dockerCertPath,
	}, nil
}
Beispiel #10
0
func setDefaultConfFlag(flag *string, def string) {
	if *flag == "" {
		if *flDaemon {
			*flag = filepath.Join(getDaemonConfDir(), def)
		} else {
			*flag = filepath.Join(homedir.Get(), ".docker", def)
		}
	}
}
Beispiel #11
0
// CreateClient creates a docker client based on the specified options.
func CreateClient(c ClientOpts) (*dockerclient.Client, error) {
	if c.TLSOptions.CAFile == "" {
		c.TLSOptions.CAFile = filepath.Join(dockerCertPath, defaultCaFile)
	}
	if c.TLSOptions.CertFile == "" {
		c.TLSOptions.CertFile = filepath.Join(dockerCertPath, defaultCertFile)
	}
	if c.TLSOptions.KeyFile == "" {
		c.TLSOptions.KeyFile = filepath.Join(dockerCertPath, defaultKeyFile)
	}

	if c.Host == "" {
		defaultHost := os.Getenv("DOCKER_HOST")
		if defaultHost == "" {
			if runtime.GOOS != "windows" {
				// If we do not have a host, default to unix socket
				defaultHost = fmt.Sprintf("unix://%s", opts.DefaultUnixSocket)
			} else {
				// If we do not have a host, default to TCP socket on Windows
				defaultHost = fmt.Sprintf("tcp://%s:%d", opts.DefaultHTTPHost, opts.DefaultHTTPPort)
			}
		}
		defaultHost, err := opts.ValidateHost(defaultHost)
		if err != nil {
			return nil, err
		}
		c.Host = defaultHost
	}

	if c.TrustKey == "" {
		c.TrustKey = filepath.Join(homedir.Get(), ".docker", defaultTrustKeyFile)
	}

	if c.TLSVerify {
		c.TLS = true
	}

	if c.TLS {
		c.TLSOptions.InsecureSkipVerify = !c.TLSVerify
	}

	apiVersion := c.APIVersion
	if apiVersion == "" {
		apiVersion = DefaultAPIVersion
	}
	if c.TLS {
		client, err := dockerclient.NewVersionedTLSClient(c.Host, c.TLSOptions.CertFile, c.TLSOptions.KeyFile, c.TLSOptions.CAFile, apiVersion)
		if err != nil {
			return nil, err
		}
		if c.TLSOptions.InsecureSkipVerify {
			client.TLSConfig.InsecureSkipVerify = true
		}
		return client, nil
	}
	return dockerclient.NewVersionedClient(c.Host, apiVersion)
}
Beispiel #12
0
// NewGpg returns a new Gpg instance
func NewGpg(conf *config.Configuration) (KeyManager, error) {
	home := homedir.Get()
	publicKeyring := filepath.Join(home, defaultGPGPath, "pubring.gpg")
	privateKeyring := filepath.Join(home, defaultGPGPath, "secring.gpg")
	return &Gpg{
		PublicKeyring:  publicKeyring,
		PrivateKeyring: privateKeyring,
		Email:          conf.Gpg.Email,
	}, nil
}
Beispiel #13
0
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(confDir); err != nil {
		if os.IsNotExist(err) {
			return filepath.Join(homedir.GetWithSudoUser(), confFile)
		}
	}
	return confDir
}
Beispiel #14
0
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,
	}
}
// CreateClient creates a docker client based on the specified options.
func CreateClient(c ClientOpts) (dockerclient.Client, error) {
	if c.TLSOptions.CAFile == "" {
		c.TLSOptions.CAFile = filepath.Join(dockerCertPath, defaultCaFile)
	}
	if c.TLSOptions.CertFile == "" {
		c.TLSOptions.CertFile = filepath.Join(dockerCertPath, defaultCertFile)
	}
	if c.TLSOptions.KeyFile == "" {
		c.TLSOptions.KeyFile = filepath.Join(dockerCertPath, defaultKeyFile)
	}

	if c.Host == "" {
		defaultHost := os.Getenv("DOCKER_HOST")
		if defaultHost == "" {
			if runtime.GOOS != "windows" {
				// If we do not have a host, default to unix socket
				defaultHost = fmt.Sprintf("unix://%s", opts.DefaultUnixSocket)
			} else {
				// If we do not have a host, default to TCP socket on Windows
				defaultHost = fmt.Sprintf("tcp://%s:%d", opts.DefaultHTTPHost, opts.DefaultHTTPPort)
			}
		}
		defaultHost, err := opts.ValidateHost(defaultHost)
		if err != nil {
			return nil, err
		}
		c.Host = defaultHost
	}

	if c.TrustKey == "" {
		c.TrustKey = filepath.Join(homedir.Get(), ".docker", defaultTrustKeyFile)
	}

	if c.TLSVerify {
		c.TLS = true
	}

	if c.TLS {
		c.TLSOptions.InsecureSkipVerify = !c.TLSVerify
	}

	var tlsConfig *tls.Config

	if c.TLS {
		var err error
		tlsConfig, err = tlsconfig.Client(c.TLSOptions)
		if err != nil {
			return nil, err
		}
	}

	return dockerclient.NewDockerClient(c.Host, tlsConfig)
}
Beispiel #16
0
// NewDockerCli returns a DockerCli instance with IO output and error streams set by in, out and err.
// The key file, protocol (i.e. unix) and address are passed in as strings, along with the tls.Config. If the tls.Config
// is set the client scheme will be set to https.
// The client will be given a 32-second timeout (see https://github.com/docker/docker/pull/8035).
func NewDockerCli(in io.ReadCloser, out, err io.Writer, keyFile string, proto, addr string, tlsConfig *tls.Config) *DockerCli {
	var (
		inFd          uintptr
		outFd         uintptr
		isTerminalIn  = false
		isTerminalOut = false
		scheme        = "http"
	)

	if tlsConfig != nil {
		scheme = "https"
	}
	if in != nil {
		inFd, isTerminalIn = term.GetFdInfo(in)
	}

	if out != nil {
		outFd, isTerminalOut = term.GetFdInfo(out)
	}

	if err == nil {
		err = out
	}

	// The transport is created here for reuse during the client session.
	tr := &http.Transport{
		TLSClientConfig: tlsConfig,
	}
	utils.ConfigureTCPTransport(tr, proto, addr)

	configFile, e := cliconfig.Load(filepath.Join(homedir.Get(), ".docker"))
	if e != nil {
		fmt.Fprintf(err, "WARNING: Error loading config file:%v\n", e)
	}

	return &DockerCli{
		proto:         proto,
		addr:          addr,
		configFile:    configFile,
		in:            in,
		out:           out,
		err:           err,
		keyFile:       keyFile,
		inFd:          inFd,
		outFd:         outFd,
		isTerminalIn:  isTerminalIn,
		isTerminalOut: isTerminalOut,
		tlsConfig:     tlsConfig,
		scheme:        scheme,
		transport:     tr,
	}
}
func (s *DockerSuite) TestConfigHttpHeader(c *check.C) {
	testRequires(c, UnixCli) // Can't set/unset HOME on windows right now
	// We either need a level of Go that supports Unsetenv (for cases
	// when HOME/USERPROFILE isn't set), or we need to be able to use
	// os/user but user.Current() only works if we aren't statically compiling

	var headers map[string][]string

	server := httptest.NewServer(http.HandlerFunc(
		func(w http.ResponseWriter, r *http.Request) {
			headers = r.Header
		}))
	defer server.Close()

	homeKey := homedir.Key()
	homeVal := homedir.Get()
	tmpDir, err := ioutil.TempDir("", "fake-home")
	c.Assert(err, check.IsNil)
	defer os.RemoveAll(tmpDir)

	dotDocker := filepath.Join(tmpDir, ".docker")
	os.Mkdir(dotDocker, 0600)
	tmpCfg := filepath.Join(dotDocker, "config.json")

	defer func() { os.Setenv(homeKey, homeVal) }()
	os.Setenv(homeKey, tmpDir)

	data := `{
		"HttpHeaders": { "MyHeader": "MyValue" }
	}`

	err = ioutil.WriteFile(tmpCfg, []byte(data), 0600)
	if err != nil {
		c.Fatalf("Err creating file(%s): %v", tmpCfg, err)
	}

	cmd := exec.Command(dockerBinary, "-H="+server.URL[7:], "ps")
	out, _, _ := runCommandWithOutput(cmd)

	if headers["User-Agent"] == nil {
		c.Fatalf("Missing User-Agent: %q\nout:%v", headers, out)
	}

	if headers["User-Agent"][0] != "Docker-Client/"+dockerversion.VERSION+" ("+runtime.GOOS+")" {
		c.Fatalf("Badly formatted User-Agent: %q\nout:%v", headers, out)
	}

	if headers["Myheader"] == nil || headers["Myheader"][0] != "MyValue" {
		c.Fatalf("Missing/bad header: %q\nout:%v", headers, out)
	}
}
Beispiel #18
0
// LoadCerts loads the certificates into c.Config, if TLS is enabled.
func (c *TLSConfig) LoadCerts() error {
	if !c.IsEnabled() {
		return nil
	}

	dockerCertPath := os.Getenv("DOCKER_CERT_PATH")
	if dockerCertPath == "" {
		dockerCertPath = filepath.Join(homedir.Get(), ".docker")
	}

	if c.CACert == "" {
		c.CACert = filepath.Join(dockerCertPath, defaultCaFile)
	}
	if c.Cert == "" {
		c.Cert = filepath.Join(dockerCertPath, defaultCertFile)
	}
	if c.Key == "" {
		c.Key = filepath.Join(dockerCertPath, defaultKeyFile)
	}

	tlsConfig := &tls.Config{
		NextProtos: []string{"http/1.1"},
		// Avoid fallback on insecure SSL protocols
		MinVersion: tls.VersionTLS10,
	}

	if c.Verify {
		certPool := x509.NewCertPool()
		file, err := ioutil.ReadFile(c.CACert)
		if err != nil {
			return fmt.Errorf("Couldn't read CA certificate: %v", err)
		}
		certPool.AppendCertsFromPEM(file)
		tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert
		tlsConfig.ClientCAs = certPool
	}

	_, errCert := os.Stat(c.Cert)
	_, errKey := os.Stat(c.Key)
	if errCert == nil && errKey == nil {
		cert, err := tls.LoadX509KeyPair(c.Cert, c.Key)
		if err != nil {
			return fmt.Errorf("Couldn't load X509 key pair: %q. Make sure the key is encrypted", err)
		}
		tlsConfig.Certificates = []tls.Certificate{cert}
	}

	c.Config = tlsConfig
	return nil
}
Beispiel #19
0
func (d *Driver) setupSharedDirs() error {
	shareDir := homedir.Get()
	shareName := "Home"

	if _, err := os.Stat(shareDir); err != nil && !os.IsNotExist(err) {
		return err
	} else if !os.IsNotExist(err) {
		// add shared folder, create mountpoint and mount it.
		vmrun("-gu", B2DUser, "-gp", B2DPass, "addSharedFolder", d.vmxPath(), shareName, shareDir)
		vmrun("-gu", B2DUser, "-gp", B2DPass, "runScriptInGuest", d.vmxPath(), "/bin/sh", "sudo mkdir -p "+shareDir+" && sudo mount -t vmhgfs .host:/"+shareName+" "+shareDir)
	}

	return nil
}
Beispiel #20
0
func TestOldValidAuth(t *testing.T) {
	tmpHome, err := ioutil.TempDir("", "config-test")
	if err != nil {
		t.Fatal(err)
	}
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(tmpHome)

	homeKey := homedir.Key()
	homeVal := homedir.Get()

	defer func() { os.Setenv(homeKey, homeVal) }()
	os.Setenv(homeKey, tmpHome)

	fn := filepath.Join(tmpHome, oldConfigfile)
	js := `username = am9lam9lOmhlbGxv
	email = [email protected]`
	if err := ioutil.WriteFile(fn, []byte(js), 0600); err != nil {
		t.Fatal(err)
	}

	config, err := Load(tmpHome)
	if err != nil {
		t.Fatal(err)
	}

	// defaultIndexserver is https://index.docker.io/v1/
	ac := config.AuthConfigs["https://index.docker.io/v1/"]
	if 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
	configStr := saveConfigAndValidateNewFormat(t, config, tmpHome)

	expConfStr := `{
	"auths": {
		"https://index.docker.io/v1/": {
			"auth": "am9lam9lOmhlbGxv"
		}
	}
}`

	if configStr != expConfStr {
		t.Fatalf("Should have save in new form: \n%s\n not \n%s", configStr, expConfStr)
	}
}
Beispiel #21
0
func (s *DockerSuite) TestConfigHTTPHeader(c *check.C) {
	testRequires(c, UnixCli) // Can't set/unset HOME on windows right now
	// We either need a level of Go that supports Unsetenv (for cases
	// when HOME/USERPROFILE isn't set), or we need to be able to use
	// os/user but user.Current() only works if we aren't statically compiling

	var headers map[string][]string

	server := httptest.NewServer(http.HandlerFunc(
		func(w http.ResponseWriter, r *http.Request) {
			w.Header().Set("API-Version", api.DefaultVersion)
			headers = r.Header
		}))
	defer server.Close()

	homeKey := homedir.Key()
	homeVal := homedir.Get()
	tmpDir, err := ioutil.TempDir("", "fake-home")
	c.Assert(err, checker.IsNil)
	defer os.RemoveAll(tmpDir)

	dotDocker := filepath.Join(tmpDir, ".docker")
	os.Mkdir(dotDocker, 0600)
	tmpCfg := filepath.Join(dotDocker, "config.json")

	defer func() { os.Setenv(homeKey, homeVal) }()
	os.Setenv(homeKey, tmpDir)

	data := `{
		"HttpHeaders": { "MyHeader": "MyValue" }
	}`

	err = ioutil.WriteFile(tmpCfg, []byte(data), 0600)
	c.Assert(err, checker.IsNil)

	result := icmd.RunCommand(dockerBinary, "-H="+server.URL[7:], "ps")
	result.Assert(c, icmd.Expected{
		ExitCode: 1,
		Error:    "exit status 1",
	})

	c.Assert(headers["User-Agent"], checker.NotNil, check.Commentf("Missing User-Agent"))

	c.Assert(headers["User-Agent"][0], checker.Equals, "Docker-Client/"+dockerversion.Version+" ("+runtime.GOOS+")", check.Commentf("Badly formatted User-Agent,out:%v", result.Combined()))

	c.Assert(headers["Myheader"], checker.NotNil)
	c.Assert(headers["Myheader"][0], checker.Equals, "MyValue", check.Commentf("Missing/bad header,out:%v", result.Combined()))

}
Beispiel #22
0
// Load reads the configuration files in the given directory, and sets up
// the auth config information and return values.
// FIXME: use the internal golang config parser
func Load(configDir string) (*ConfigFile, error) {
	if configDir == "" {
		configDir = ConfigDir()
	}

	configFile := ConfigFile{
		AuthConfigs: make(map[string]types.AuthConfig),
		filename:    filepath.Join(configDir, ConfigFileName),
	}

	// 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, fmt.Errorf("%s - %v", configFile.filename, err)
		}
		defer file.Close()
		err = configFile.LoadFromReader(file)
		if err != nil {
			err = fmt.Errorf("%s - %v", configFile.filename, err)
		}
		return &configFile, err
	} 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, fmt.Errorf("%s - %v", configFile.filename, err)
	}

	// Can't find latest config file so check for the old one
	confFile := filepath.Join(homedir.Get(), oldConfigfile)
	if _, err := os.Stat(confFile); err != nil {
		return &configFile, nil //missing file is not an error
	}
	file, err := os.Open(confFile)
	if err != nil {
		return &configFile, fmt.Errorf("%s - %v", confFile, err)
	}
	defer file.Close()
	err = configFile.LegacyLoadFromReader(file)
	if err != nil {
		return &configFile, fmt.Errorf("%s - %v", confFile, err)
	}

	if configFile.HTTPHeaders == nil {
		configFile.HTTPHeaders = map[string]string{}
	}
	return &configFile, nil
}
Beispiel #23
0
// PrintDefaults prints, to standard error unless configured
// otherwise, the default values of all defined flags in the set.
func (fs *FlagSet) PrintDefaults() {
	writer := tabwriter.NewWriter(fs.Out(), 20, 1, 3, ' ', 0)
	home := homedir.Get()

	// Don't substitute when HOME is /
	if runtime.GOOS != "windows" && home == "/" {
		home = ""
	}

	// Add a blank line between cmd description and list of options
	if fs.FlagCount() > 0 {
		fmt.Fprintln(writer, "")
	}

	fs.VisitAll(func(flag *Flag) {
		names := []string{}
		for _, name := range flag.Names {
			if name[0] != '#' {
				names = append(names, name)
			}
		}
		if len(names) > 0 && len(flag.Usage) > 0 {
			val := flag.DefValue

			if home != "" && strings.HasPrefix(val, home) {
				val = homedir.GetShortcutString() + val[len(home):]
			}

			if isZeroValue(val) {
				format := "  -%s"
				fmt.Fprintf(writer, format, strings.Join(names, ", -"))
			} else {
				format := "  -%s=%s"
				fmt.Fprintf(writer, format, strings.Join(names, ", -"), val)
			}
			for i, line := range strings.Split(flag.Usage, "\n") {
				if i != 0 {
					line = "  " + line
				}
				fmt.Fprintln(writer, "\t", line)
			}
		}
	})
	writer.Flush()
}
func FixHOME(app *cli.App) {
	appBefore := app.Before

	app.Before = func(c *cli.Context) error {
		// Fix home
		if key := homedir.Key(); os.Getenv(key) == "" {
			value := homedir.Get()
			if value == "" {
				return fmt.Errorf("the %q is not set", key)
			}
			os.Setenv(key, value)
		}

		if appBefore != nil {
			return appBefore(c)
		}
		return nil
	}
}
Beispiel #25
0
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))
	}
}
Beispiel #26
0
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 {
				logrus.Warnf("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)
		}

		logrus.Infof("Migrated key from %s to %s", oldPath, newPath)
	}

	return nil
}
Beispiel #27
0
func TestOldInvalidsAuth(t *testing.T) {
	invalids := map[string]string{
		`username = test`: "The Auth config file is empty",
		`username
password
email`: "Invalid Auth config file",
		`username = test
email`: "Invalid auth configuration file",
		`username = am9lam9lOmhlbGxv
email`: "Invalid Auth config file",
	}

	tmpHome, err := ioutil.TempDir("", "config-test")
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(tmpHome)

	homeKey := homedir.Key()
	homeVal := homedir.Get()

	defer func() { os.Setenv(homeKey, homeVal) }()
	os.Setenv(homeKey, tmpHome)

	for content, expectedError := range invalids {
		fn := filepath.Join(tmpHome, oldConfigfile)
		if err := ioutil.WriteFile(fn, []byte(content), 0600); err != nil {
			t.Fatal(err)
		}

		config, err := Load(tmpHome)
		if err == nil || err.Error() != expectedError {
			t.Fatalf("Should have failed, got: %q, %q", config, err)
		}

	}
}
Beispiel #28
0
func TestOldJson(t *testing.T) {
	tmpHome, err := ioutil.TempDir("", "config-test")
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(tmpHome)

	homeKey := homedir.Key()
	homeVal := homedir.Get()

	defer func() { os.Setenv(homeKey, homeVal) }()
	os.Setenv(homeKey, tmpHome)

	fn := filepath.Join(tmpHome, oldConfigfile)
	js := `{"https://index.docker.io/v1/":{"auth":"am9lam9lOmhlbGxv","email":"*****@*****.**"}}`
	if err := ioutil.WriteFile(fn, []byte(js), 0600); err != nil {
		t.Fatal(err)
	}

	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
	configStr := saveConfigAndValidateNewFormat(t, config, tmpHome)

	if !strings.Contains(configStr, "*****@*****.**") {
		t.Fatalf("Should have save in new form: %s", configStr)
	}
}
// TestRunDetach checks attaching and detaching with the detach flags, making sure it overrides config file
func (s *DockerSuite) TestRunAttachDetachKeysOverrideConfig(c *check.C) {
	keyCtrlA := []byte{1}
	keyA := []byte{97}

	// Setup config
	homeKey := homedir.Key()
	homeVal := homedir.Get()
	tmpDir, err := ioutil.TempDir("", "fake-home")
	c.Assert(err, checker.IsNil)
	defer os.RemoveAll(tmpDir)

	dotDocker := filepath.Join(tmpDir, ".docker")
	os.Mkdir(dotDocker, 0600)
	tmpCfg := filepath.Join(dotDocker, "config.json")

	defer func() { os.Setenv(homeKey, homeVal) }()
	os.Setenv(homeKey, tmpDir)

	data := `{
		"detachKeys": "ctrl-e,e"
	}`

	err = ioutil.WriteFile(tmpCfg, []byte(data), 0600)
	c.Assert(err, checker.IsNil)

	// Then do the work
	name := "attach-detach"
	dockerCmd(c, "run", "--name", name, "-itd", "busybox", "cat")

	cmd := exec.Command(dockerBinary, "attach", "--detach-keys='ctrl-a,a'", name)
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		c.Fatal(err)
	}
	cpty, tty, err := pty.Open()
	if err != nil {
		c.Fatal(err)
	}
	defer cpty.Close()
	cmd.Stdin = tty
	if err := cmd.Start(); err != nil {
		c.Fatal(err)
	}
	c.Assert(waitRun(name), check.IsNil)

	if _, err := cpty.Write([]byte("hello\n")); err != nil {
		c.Fatal(err)
	}

	out, err := bufio.NewReader(stdout).ReadString('\n')
	if err != nil {
		c.Fatal(err)
	}
	if strings.TrimSpace(out) != "hello" {
		c.Fatalf("expected 'hello', got %q", out)
	}

	// escape sequence
	if _, err := cpty.Write(keyCtrlA); err != nil {
		c.Fatal(err)
	}
	time.Sleep(100 * time.Millisecond)
	if _, err := cpty.Write(keyA); err != nil {
		c.Fatal(err)
	}

	ch := make(chan struct{})
	go func() {
		cmd.Wait()
		ch <- struct{}{}
	}()

	select {
	case <-ch:
	case <-time.After(10 * time.Second):
		c.Fatal("timed out waiting for container to exit")
	}

	running := inspectField(c, name, "State.Running")
	c.Assert(running, checker.Equals, "true", check.Commentf("expected container to still be running"))
}
Beispiel #30
0
// Load reads the configuration files in the given directory, and sets up
// the auth config information and return values.
// FIXME: use the internal golang config parser
func Load(configDir string) (*ConfigFile, error) {
	if configDir == "" {
		configDir = ConfigDir()
	}

	configFile := ConfigFile{
		AuthConfigs: make(map[string]AuthConfig),
		filename:    filepath.Join(configDir, ConfigFileName),
	}

	// 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(), oldConfigfile)
	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 = defaultIndexserver
		configFile.AuthConfigs[defaultIndexserver] = 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
}