Add support for DOCKER_CONFIG/--config to specific config file dir
Carry #11675 Aside from what #11675 says, to me a key usecase for this is to support more than one Docker cli running at the same time but each may have its own set of config files. Signed-off-by: Doug Davis <dug@us.ibm.com>
This commit is contained in:
parent
0afd7bde02
commit
daced1d303
9 changed files with 132 additions and 15 deletions
|
@ -7,13 +7,11 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/docker/docker/cliconfig"
|
||||
"github.com/docker/docker/pkg/homedir"
|
||||
flag "github.com/docker/docker/pkg/mflag"
|
||||
"github.com/docker/docker/pkg/sockets"
|
||||
"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)
|
||||
|
||||
configFile, e := cliconfig.Load(filepath.Join(homedir.Get(), ".docker"))
|
||||
configFile, e := cliconfig.Load(cliconfig.ConfigDir())
|
||||
if e != nil {
|
||||
fmt.Fprintf(err, "WARNING: Error loading config file:%v\n", e)
|
||||
}
|
||||
|
|
|
@ -25,9 +25,24 @@ const (
|
|||
)
|
||||
|
||||
var (
|
||||
configDir = os.Getenv("DOCKER_CONFIG")
|
||||
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
|
||||
type AuthConfig struct {
|
||||
Username string `json:"username,omitempty"`
|
||||
|
@ -56,7 +71,7 @@ func NewConfigFile(fn string) *ConfigFile {
|
|||
// FIXME: use the internal golang config parser
|
||||
func Load(configDir string) (*ConfigFile, error) {
|
||||
if configDir == "" {
|
||||
configDir = filepath.Join(homedir.Get(), ".docker")
|
||||
configDir = ConfigDir()
|
||||
}
|
||||
|
||||
configFile := ConfigFile{
|
||||
|
|
|
@ -13,8 +13,8 @@ import (
|
|||
"github.com/Sirupsen/logrus"
|
||||
apiserver "github.com/docker/docker/api/server"
|
||||
"github.com/docker/docker/autogen/dockerversion"
|
||||
"github.com/docker/docker/cliconfig"
|
||||
"github.com/docker/docker/daemon"
|
||||
"github.com/docker/docker/pkg/homedir"
|
||||
flag "github.com/docker/docker/pkg/mflag"
|
||||
"github.com/docker/docker/pkg/pidfile"
|
||||
"github.com/docker/docker/pkg/signal"
|
||||
|
@ -39,7 +39,7 @@ func init() {
|
|||
|
||||
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)
|
||||
oldPath := filepath.Join(cliconfig.ConfigDir(), defaultTrustKeyFile)
|
||||
newPath := filepath.Join(getDaemonConfDir(), defaultTrustKeyFile)
|
||||
if _, statErr := os.Stat(newPath); os.IsNotExist(statErr) && currentUserIsOwner(oldPath) {
|
||||
defer func() {
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/docker/api/client"
|
||||
"github.com/docker/docker/autogen/dockerversion"
|
||||
"github.com/docker/docker/cliconfig"
|
||||
"github.com/docker/docker/opts"
|
||||
flag "github.com/docker/docker/pkg/mflag"
|
||||
"github.com/docker/docker/pkg/reexec"
|
||||
|
@ -43,6 +44,10 @@ func main() {
|
|||
return
|
||||
}
|
||||
|
||||
if *flConfigDir != "" {
|
||||
cliconfig.SetConfigDir(*flConfigDir)
|
||||
}
|
||||
|
||||
if *flLogLevel != "" {
|
||||
lvl, err := logrus.ParseLevel(*flLogLevel)
|
||||
if err != nil {
|
||||
|
|
|
@ -7,8 +7,8 @@ import (
|
|||
"runtime"
|
||||
"sort"
|
||||
|
||||
"github.com/docker/docker/cliconfig"
|
||||
"github.com/docker/docker/opts"
|
||||
"github.com/docker/docker/pkg/homedir"
|
||||
flag "github.com/docker/docker/pkg/mflag"
|
||||
"github.com/docker/docker/pkg/tlsconfig"
|
||||
)
|
||||
|
@ -73,19 +73,20 @@ var (
|
|||
|
||||
func init() {
|
||||
if dockerCertPath == "" {
|
||||
dockerCertPath = filepath.Join(homedir.Get(), ".docker")
|
||||
dockerCertPath = cliconfig.ConfigDir()
|
||||
}
|
||||
}
|
||||
|
||||
func getDaemonConfDir() string {
|
||||
// TODO: update for Windows daemon
|
||||
if runtime.GOOS == "windows" {
|
||||
return filepath.Join(homedir.Get(), ".docker")
|
||||
return cliconfig.ConfigDir()
|
||||
}
|
||||
return "/etc/docker"
|
||||
}
|
||||
|
||||
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")
|
||||
flDaemon = flag.Bool([]string{"d", "-daemon"}, false, "Enable daemon mode")
|
||||
flDebug = flag.Bool([]string{"D", "-debug"}, false, "Enable debug mode")
|
||||
|
@ -105,7 +106,7 @@ func setDefaultConfFlag(flag *string, def string) {
|
|||
if *flDaemon {
|
||||
*flag = filepath.Join(getDaemonConfDir(), def)
|
||||
} 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
|
||||
|
||||
> **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
|
||||
> 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
|
||||
by the `docker` command line:
|
||||
|
||||
* `DOCKER_CONFIG` The location of your client configuration files.
|
||||
* `DOCKER_CERT_PATH` The location of your authentication keys.
|
||||
* `DOCKER_DRIVER` The graph driver to use.
|
||||
* `DOCKER_HOST` Daemon socket to connect to.
|
||||
|
@ -60,10 +61,21 @@ variables.
|
|||
|
||||
## Configuration files
|
||||
|
||||
The Docker command line stores its configuration files in a directory called
|
||||
`.docker` within your `HOME` directory. Docker manages most of the files in
|
||||
`.docker` and you should not modify them. However, you *can modify* the
|
||||
`.docker/config.json` file to control certain aspects of how the `docker`
|
||||
By default, the Docker command line stores its configuration files in a
|
||||
directory called `.docker` within your `HOME` directory. However, you can
|
||||
specify a different location via the `DOCKER_CONFIG` environment variable
|
||||
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.
|
||||
|
||||
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
|
||||
-b, --bridge="" Attach containers to a network bridge
|
||||
--bip="" Specify network bridge IP
|
||||
--config=~/.docker Location of client config files
|
||||
-D, --debug=false Enable debug mode
|
||||
-d, --daemon=false Enable daemon mode
|
||||
--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)
|
||||
}
|
||||
}
|
||||
|
||||
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**=""
|
||||
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*
|
||||
Enable debug mode. Default is false.
|
||||
|
||||
|
|
Loading…
Reference in a new issue