mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #12856 from duglin/ConfigLocation
Add support for DOCKER_CONFIG/--config to specify config file dir
This commit is contained in:
commit
5bf98dd997
9 changed files with 132 additions and 15 deletions
|
@ -7,13 +7,11 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"path/filepath"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
"github.com/docker/docker/cliconfig"
|
"github.com/docker/docker/cliconfig"
|
||||||
"github.com/docker/docker/pkg/homedir"
|
|
||||||
flag "github.com/docker/docker/pkg/mflag"
|
flag "github.com/docker/docker/pkg/mflag"
|
||||||
"github.com/docker/docker/pkg/sockets"
|
"github.com/docker/docker/pkg/sockets"
|
||||||
"github.com/docker/docker/pkg/term"
|
"github.com/docker/docker/pkg/term"
|
||||||
|
@ -212,7 +210,7 @@ func NewDockerCli(in io.ReadCloser, out, err io.Writer, keyFile string, proto, a
|
||||||
}
|
}
|
||||||
sockets.ConfigureTCPTransport(tr, proto, addr)
|
sockets.ConfigureTCPTransport(tr, proto, addr)
|
||||||
|
|
||||||
configFile, e := cliconfig.Load(filepath.Join(homedir.Get(), ".docker"))
|
configFile, e := cliconfig.Load(cliconfig.ConfigDir())
|
||||||
if e != nil {
|
if e != nil {
|
||||||
fmt.Fprintf(err, "WARNING: Error loading config file:%v\n", e)
|
fmt.Fprintf(err, "WARNING: Error loading config file:%v\n", e)
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,9 +25,24 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
configDir = os.Getenv("DOCKER_CONFIG")
|
||||||
ErrConfigFileMissing = errors.New("The Auth config file is missing")
|
ErrConfigFileMissing = errors.New("The Auth config file is missing")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
if configDir == "" {
|
||||||
|
configDir = filepath.Join(homedir.Get(), ".docker")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConfigDir() string {
|
||||||
|
return configDir
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetConfigDir(dir string) {
|
||||||
|
configDir = dir
|
||||||
|
}
|
||||||
|
|
||||||
// Registry Auth Info
|
// Registry Auth Info
|
||||||
type AuthConfig struct {
|
type AuthConfig struct {
|
||||||
Username string `json:"username,omitempty"`
|
Username string `json:"username,omitempty"`
|
||||||
|
@ -56,7 +71,7 @@ func NewConfigFile(fn string) *ConfigFile {
|
||||||
// FIXME: use the internal golang config parser
|
// FIXME: use the internal golang config parser
|
||||||
func Load(configDir string) (*ConfigFile, error) {
|
func Load(configDir string) (*ConfigFile, error) {
|
||||||
if configDir == "" {
|
if configDir == "" {
|
||||||
configDir = filepath.Join(homedir.Get(), ".docker")
|
configDir = ConfigDir()
|
||||||
}
|
}
|
||||||
|
|
||||||
configFile := ConfigFile{
|
configFile := ConfigFile{
|
||||||
|
|
|
@ -13,8 +13,8 @@ import (
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
apiserver "github.com/docker/docker/api/server"
|
apiserver "github.com/docker/docker/api/server"
|
||||||
"github.com/docker/docker/autogen/dockerversion"
|
"github.com/docker/docker/autogen/dockerversion"
|
||||||
|
"github.com/docker/docker/cliconfig"
|
||||||
"github.com/docker/docker/daemon"
|
"github.com/docker/docker/daemon"
|
||||||
"github.com/docker/docker/pkg/homedir"
|
|
||||||
flag "github.com/docker/docker/pkg/mflag"
|
flag "github.com/docker/docker/pkg/mflag"
|
||||||
"github.com/docker/docker/pkg/pidfile"
|
"github.com/docker/docker/pkg/pidfile"
|
||||||
"github.com/docker/docker/pkg/signal"
|
"github.com/docker/docker/pkg/signal"
|
||||||
|
@ -39,7 +39,7 @@ func init() {
|
||||||
|
|
||||||
func migrateKey() (err error) {
|
func migrateKey() (err error) {
|
||||||
// Migrate trust key if exists at ~/.docker/key.json and owned by current user
|
// Migrate trust key if exists at ~/.docker/key.json and owned by current user
|
||||||
oldPath := filepath.Join(homedir.Get(), ".docker", defaultTrustKeyFile)
|
oldPath := filepath.Join(cliconfig.ConfigDir(), defaultTrustKeyFile)
|
||||||
newPath := filepath.Join(getDaemonConfDir(), defaultTrustKeyFile)
|
newPath := filepath.Join(getDaemonConfDir(), defaultTrustKeyFile)
|
||||||
if _, statErr := os.Stat(newPath); os.IsNotExist(statErr) && currentUserIsOwner(oldPath) {
|
if _, statErr := os.Stat(newPath); os.IsNotExist(statErr) && currentUserIsOwner(oldPath) {
|
||||||
defer func() {
|
defer func() {
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/docker/docker/api/client"
|
"github.com/docker/docker/api/client"
|
||||||
"github.com/docker/docker/autogen/dockerversion"
|
"github.com/docker/docker/autogen/dockerversion"
|
||||||
|
"github.com/docker/docker/cliconfig"
|
||||||
"github.com/docker/docker/opts"
|
"github.com/docker/docker/opts"
|
||||||
flag "github.com/docker/docker/pkg/mflag"
|
flag "github.com/docker/docker/pkg/mflag"
|
||||||
"github.com/docker/docker/pkg/reexec"
|
"github.com/docker/docker/pkg/reexec"
|
||||||
|
@ -43,6 +44,10 @@ func main() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if *flConfigDir != "" {
|
||||||
|
cliconfig.SetConfigDir(*flConfigDir)
|
||||||
|
}
|
||||||
|
|
||||||
if *flLogLevel != "" {
|
if *flLogLevel != "" {
|
||||||
lvl, err := logrus.ParseLevel(*flLogLevel)
|
lvl, err := logrus.ParseLevel(*flLogLevel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -7,8 +7,8 @@ import (
|
||||||
"runtime"
|
"runtime"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
|
"github.com/docker/docker/cliconfig"
|
||||||
"github.com/docker/docker/opts"
|
"github.com/docker/docker/opts"
|
||||||
"github.com/docker/docker/pkg/homedir"
|
|
||||||
flag "github.com/docker/docker/pkg/mflag"
|
flag "github.com/docker/docker/pkg/mflag"
|
||||||
"github.com/docker/docker/pkg/tlsconfig"
|
"github.com/docker/docker/pkg/tlsconfig"
|
||||||
)
|
)
|
||||||
|
@ -73,19 +73,20 @@ var (
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
if dockerCertPath == "" {
|
if dockerCertPath == "" {
|
||||||
dockerCertPath = filepath.Join(homedir.Get(), ".docker")
|
dockerCertPath = cliconfig.ConfigDir()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getDaemonConfDir() string {
|
func getDaemonConfDir() string {
|
||||||
// TODO: update for Windows daemon
|
// TODO: update for Windows daemon
|
||||||
if runtime.GOOS == "windows" {
|
if runtime.GOOS == "windows" {
|
||||||
return filepath.Join(homedir.Get(), ".docker")
|
return cliconfig.ConfigDir()
|
||||||
}
|
}
|
||||||
return "/etc/docker"
|
return "/etc/docker"
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
flConfigDir = flag.String([]string{"-config"}, cliconfig.ConfigDir(), "Location of client config files")
|
||||||
flVersion = flag.Bool([]string{"v", "-version"}, false, "Print version information and quit")
|
flVersion = flag.Bool([]string{"v", "-version"}, false, "Print version information and quit")
|
||||||
flDaemon = flag.Bool([]string{"d", "-daemon"}, false, "Enable daemon mode")
|
flDaemon = flag.Bool([]string{"d", "-daemon"}, false, "Enable daemon mode")
|
||||||
flDebug = flag.Bool([]string{"D", "-debug"}, false, "Enable debug mode")
|
flDebug = flag.Bool([]string{"D", "-debug"}, false, "Enable debug mode")
|
||||||
|
@ -105,7 +106,7 @@ func setDefaultConfFlag(flag *string, def string) {
|
||||||
if *flDaemon {
|
if *flDaemon {
|
||||||
*flag = filepath.Join(getDaemonConfDir(), def)
|
*flag = filepath.Join(getDaemonConfDir(), def)
|
||||||
} else {
|
} else {
|
||||||
*flag = filepath.Join(homedir.Get(), ".docker", def)
|
*flag = filepath.Join(cliconfig.ConfigDir(), def)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ parent = "smn_cli"
|
||||||
|
|
||||||
# Using the command line
|
# Using the command line
|
||||||
|
|
||||||
> **Note:** if you are using a remote Docker daemon, such as Boot2Docker,
|
> **Note:** If you are using a remote Docker daemon, such as Boot2Docker,
|
||||||
> then _do not_ type the `sudo` before the `docker` commands shown in the
|
> then _do not_ type the `sudo` before the `docker` commands shown in the
|
||||||
> documentation's examples.
|
> documentation's examples.
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@ the [installation](/installation) instructions for your operating system.
|
||||||
For easy reference, the following list of environment variables are supported
|
For easy reference, the following list of environment variables are supported
|
||||||
by the `docker` command line:
|
by the `docker` command line:
|
||||||
|
|
||||||
|
* `DOCKER_CONFIG` The location of your client configuration files.
|
||||||
* `DOCKER_CERT_PATH` The location of your authentication keys.
|
* `DOCKER_CERT_PATH` The location of your authentication keys.
|
||||||
* `DOCKER_DRIVER` The graph driver to use.
|
* `DOCKER_DRIVER` The graph driver to use.
|
||||||
* `DOCKER_HOST` Daemon socket to connect to.
|
* `DOCKER_HOST` Daemon socket to connect to.
|
||||||
|
@ -60,10 +61,21 @@ variables.
|
||||||
|
|
||||||
## Configuration files
|
## Configuration files
|
||||||
|
|
||||||
The Docker command line stores its configuration files in a directory called
|
By default, the Docker command line stores its configuration files in a
|
||||||
`.docker` within your `HOME` directory. Docker manages most of the files in
|
directory called `.docker` within your `HOME` directory. However, you can
|
||||||
`.docker` and you should not modify them. However, you *can modify* the
|
specify a different location via the `DOCKER_CONFIG` environment variable
|
||||||
`.docker/config.json` file to control certain aspects of how the `docker`
|
or the `--config` command line option. If both are specified, then the
|
||||||
|
`--config` option overrides the `DOCKER_CONFIG` environment variable.
|
||||||
|
For example:
|
||||||
|
|
||||||
|
docker --config ~/testconfigs/ ps
|
||||||
|
|
||||||
|
Instructs Docker to use the configuration files in your `~/testconfigs/`
|
||||||
|
directory when running the `ps` command.
|
||||||
|
|
||||||
|
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`
|
||||||
command behaves.
|
command behaves.
|
||||||
|
|
||||||
Currently, you can modify the `docker` command behavior using environment
|
Currently, you can modify the `docker` command behavior using environment
|
||||||
|
|
|
@ -18,6 +18,7 @@ parent = "smn_cli"
|
||||||
--api-cors-header="" Set CORS headers in the remote API
|
--api-cors-header="" Set CORS headers in the remote API
|
||||||
-b, --bridge="" Attach containers to a network bridge
|
-b, --bridge="" Attach containers to a network bridge
|
||||||
--bip="" Specify network bridge IP
|
--bip="" Specify network bridge IP
|
||||||
|
--config=~/.docker Location of client config files
|
||||||
-D, --debug=false Enable debug mode
|
-D, --debug=false Enable debug mode
|
||||||
-d, --daemon=false Enable daemon mode
|
-d, --daemon=false Enable daemon mode
|
||||||
--default-gateway="" Container default gateway IPv4 address
|
--default-gateway="" Container default gateway IPv4 address
|
||||||
|
|
|
@ -64,3 +64,85 @@ func (s *DockerSuite) TestConfigHttpHeader(c *check.C) {
|
||||||
c.Fatalf("Missing/bad header: %q\nout:%v", headers, out)
|
c.Fatalf("Missing/bad header: %q\nout:%v", headers, out)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *DockerSuite) TestConfigDir(c *check.C) {
|
||||||
|
cDir, _ := ioutil.TempDir("", "fake-home")
|
||||||
|
|
||||||
|
// First make sure pointing to empty dir doesn't generate an error
|
||||||
|
cmd := exec.Command(dockerBinary, "--config", cDir, "ps")
|
||||||
|
out, rc, err := runCommandWithOutput(cmd)
|
||||||
|
|
||||||
|
if rc != 0 || err != nil {
|
||||||
|
c.Fatalf("ps1 didn't work:\nrc:%d\nout%s\nerr:%v", rc, out, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test with env var too
|
||||||
|
cmd = exec.Command(dockerBinary, "ps")
|
||||||
|
cmd.Env = append(os.Environ(), "DOCKER_CONFIG="+cDir)
|
||||||
|
out, rc, err = runCommandWithOutput(cmd)
|
||||||
|
|
||||||
|
if rc != 0 || err != nil {
|
||||||
|
c.Fatalf("ps2 didn't work:\nrc:%d\nout%s\nerr:%v", rc, out, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start a server so we can check to see if the config file was
|
||||||
|
// loaded properly
|
||||||
|
var headers map[string][]string
|
||||||
|
|
||||||
|
server := httptest.NewServer(http.HandlerFunc(
|
||||||
|
func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
headers = r.Header
|
||||||
|
}))
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
// Create a dummy config file in our new config dir
|
||||||
|
data := `{
|
||||||
|
"HttpHeaders": { "MyHeader": "MyValue" }
|
||||||
|
}`
|
||||||
|
|
||||||
|
tmpCfg := filepath.Join(cDir, "config.json")
|
||||||
|
err = ioutil.WriteFile(tmpCfg, []byte(data), 0600)
|
||||||
|
if err != nil {
|
||||||
|
c.Fatalf("Err creating file(%s): %v", tmpCfg, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd = exec.Command(dockerBinary, "--config", cDir, "-H="+server.URL[7:], "ps")
|
||||||
|
out, _, _ = runCommandWithOutput(cmd)
|
||||||
|
|
||||||
|
if headers["Myheader"] == nil || headers["Myheader"][0] != "MyValue" {
|
||||||
|
c.Fatalf("ps3 - Missing header: %q\nout:%v", headers, out)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset headers and try again using env var this time
|
||||||
|
headers = map[string][]string{}
|
||||||
|
cmd = exec.Command(dockerBinary, "-H="+server.URL[7:], "ps")
|
||||||
|
cmd.Env = append(os.Environ(), "DOCKER_CONFIG="+cDir)
|
||||||
|
out, _, _ = runCommandWithOutput(cmd)
|
||||||
|
|
||||||
|
if headers["Myheader"] == nil || headers["Myheader"][0] != "MyValue" {
|
||||||
|
c.Fatalf("ps4 - Missing header: %q\nout:%v", headers, out)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset headers and make sure flag overrides the env var
|
||||||
|
headers = map[string][]string{}
|
||||||
|
cmd = exec.Command(dockerBinary, "--config", cDir, "-H="+server.URL[7:], "ps")
|
||||||
|
cmd.Env = append(os.Environ(), "DOCKER_CONFIG=MissingDir")
|
||||||
|
out, _, _ = runCommandWithOutput(cmd)
|
||||||
|
|
||||||
|
if headers["Myheader"] == nil || headers["Myheader"][0] != "MyValue" {
|
||||||
|
c.Fatalf("ps5 - Missing header: %q\nout:%v", headers, out)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset headers and make sure flag overrides the env var.
|
||||||
|
// Almost same as previous but make sure the "MissingDir" isn't
|
||||||
|
// ignore - we don't want to default back to the env var.
|
||||||
|
headers = map[string][]string{}
|
||||||
|
cmd = exec.Command(dockerBinary, "--config", "MissingDir", "-H="+server.URL[7:], "ps")
|
||||||
|
cmd.Env = append(os.Environ(), "DOCKER_CONFIG="+cDir)
|
||||||
|
out, _, _ = runCommandWithOutput(cmd)
|
||||||
|
|
||||||
|
if headers["Myheader"] != nil {
|
||||||
|
c.Fatalf("ps6 - Headers are there but shouldn't be: %q\nout:%v", headers, out)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -35,6 +35,9 @@ To see the man page for a command run **man docker <command>**.
|
||||||
**--bip**=""
|
**--bip**=""
|
||||||
Use the provided CIDR notation address for the dynamically created bridge (docker0); Mutually exclusive of \-b
|
Use the provided CIDR notation address for the dynamically created bridge (docker0); Mutually exclusive of \-b
|
||||||
|
|
||||||
|
**--config**=""
|
||||||
|
Specifies the location of the Docker client configuration files. The default is '~/.docker'.
|
||||||
|
|
||||||
**-D**, **--debug**=*true*|*false*
|
**-D**, **--debug**=*true*|*false*
|
||||||
Enable debug mode. Default is false.
|
Enable debug mode. Default is false.
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue