- Moving the `common*.go` files in `cmd/dockerd` directly (it's the
only place it's getting used)
- Rename `cli/flags` to `cli/config` because it's the only thing left
in that package 👼
Now, `integration-cli` does *truly* not depend on `cobra` stuff.
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
| 1 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,25 @@ |
| 0 |
+package config |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "os" |
|
| 4 |
+ "path/filepath" |
|
| 5 |
+ |
|
| 6 |
+ "github.com/docker/docker/pkg/homedir" |
|
| 7 |
+) |
|
| 8 |
+ |
|
| 9 |
+var ( |
|
| 10 |
+ configDir = os.Getenv("DOCKER_CONFIG")
|
|
| 11 |
+ configFileDir = ".docker" |
|
| 12 |
+) |
|
| 13 |
+ |
|
| 14 |
+// Dir returns the path to the configuration directory as specified by the DOCKER_CONFIG environment variable. |
|
| 15 |
+// TODO: this was copied from cli/config/configfile and should be removed once cmd/dockerd moves |
|
| 16 |
+func Dir() string {
|
|
| 17 |
+ return configDir |
|
| 18 |
+} |
|
| 19 |
+ |
|
| 20 |
+func init() {
|
|
| 21 |
+ if configDir == "" {
|
|
| 22 |
+ configDir = filepath.Join(homedir.Get(), configFileDir) |
|
| 23 |
+ } |
|
| 24 |
+} |
| 0 | 25 |
deleted file mode 100644 |
| ... | ... |
@@ -1,13 +0,0 @@ |
| 1 |
-package flags |
|
| 2 |
- |
|
| 3 |
-// ClientOptions are the options used to configure the client cli |
|
| 4 |
-type ClientOptions struct {
|
|
| 5 |
- Common *CommonOptions |
|
| 6 |
- ConfigDir string |
|
| 7 |
- Version bool |
|
| 8 |
-} |
|
| 9 |
- |
|
| 10 |
-// NewClientOptions returns a new ClientOptions |
|
| 11 |
-func NewClientOptions() *ClientOptions {
|
|
| 12 |
- return &ClientOptions{Common: NewCommonOptions()}
|
|
| 13 |
-} |
| 14 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,116 +0,0 @@ |
| 1 |
-package flags |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- "fmt" |
|
| 5 |
- "os" |
|
| 6 |
- "path/filepath" |
|
| 7 |
- |
|
| 8 |
- "github.com/Sirupsen/logrus" |
|
| 9 |
- "github.com/docker/docker/opts" |
|
| 10 |
- "github.com/docker/go-connections/tlsconfig" |
|
| 11 |
- "github.com/spf13/pflag" |
|
| 12 |
-) |
|
| 13 |
- |
|
| 14 |
-const ( |
|
| 15 |
- // DefaultCaFile is the default filename for the CA pem file |
|
| 16 |
- DefaultCaFile = "ca.pem" |
|
| 17 |
- // DefaultKeyFile is the default filename for the key pem file |
|
| 18 |
- DefaultKeyFile = "key.pem" |
|
| 19 |
- // DefaultCertFile is the default filename for the cert pem file |
|
| 20 |
- DefaultCertFile = "cert.pem" |
|
| 21 |
- // FlagTLSVerify is the flag name for the TLS verification option |
|
| 22 |
- FlagTLSVerify = "tlsverify" |
|
| 23 |
-) |
|
| 24 |
- |
|
| 25 |
-var ( |
|
| 26 |
- dockerCertPath = os.Getenv("DOCKER_CERT_PATH")
|
|
| 27 |
- dockerTLSVerify = os.Getenv("DOCKER_TLS_VERIFY") != ""
|
|
| 28 |
-) |
|
| 29 |
- |
|
| 30 |
-// CommonOptions are options common to both the client and the daemon. |
|
| 31 |
-type CommonOptions struct {
|
|
| 32 |
- Debug bool |
|
| 33 |
- Hosts []string |
|
| 34 |
- LogLevel string |
|
| 35 |
- TLS bool |
|
| 36 |
- TLSVerify bool |
|
| 37 |
- TLSOptions *tlsconfig.Options |
|
| 38 |
-} |
|
| 39 |
- |
|
| 40 |
-// NewCommonOptions returns a new CommonOptions |
|
| 41 |
-func NewCommonOptions() *CommonOptions {
|
|
| 42 |
- return &CommonOptions{}
|
|
| 43 |
-} |
|
| 44 |
- |
|
| 45 |
-// InstallFlags adds flags for the common options on the FlagSet |
|
| 46 |
-func (commonOpts *CommonOptions) InstallFlags(flags *pflag.FlagSet) {
|
|
| 47 |
- if dockerCertPath == "" {
|
|
| 48 |
- dockerCertPath = ConfigurationDir() |
|
| 49 |
- } |
|
| 50 |
- |
|
| 51 |
- flags.BoolVarP(&commonOpts.Debug, "debug", "D", false, "Enable debug mode") |
|
| 52 |
- flags.StringVarP(&commonOpts.LogLevel, "log-level", "l", "info", `Set the logging level ("debug"|"info"|"warn"|"error"|"fatal")`)
|
|
| 53 |
- flags.BoolVar(&commonOpts.TLS, "tls", false, "Use TLS; implied by --tlsverify") |
|
| 54 |
- flags.BoolVar(&commonOpts.TLSVerify, FlagTLSVerify, dockerTLSVerify, "Use TLS and verify the remote") |
|
| 55 |
- |
|
| 56 |
- // TODO use flag flags.String("identity"}, "i", "", "Path to libtrust key file")
|
|
| 57 |
- |
|
| 58 |
- commonOpts.TLSOptions = &tlsconfig.Options{
|
|
| 59 |
- CAFile: filepath.Join(dockerCertPath, DefaultCaFile), |
|
| 60 |
- CertFile: filepath.Join(dockerCertPath, DefaultCertFile), |
|
| 61 |
- KeyFile: filepath.Join(dockerCertPath, DefaultKeyFile), |
|
| 62 |
- } |
|
| 63 |
- tlsOptions := commonOpts.TLSOptions |
|
| 64 |
- flags.Var(opts.NewQuotedString(&tlsOptions.CAFile), "tlscacert", "Trust certs signed only by this CA") |
|
| 65 |
- flags.Var(opts.NewQuotedString(&tlsOptions.CertFile), "tlscert", "Path to TLS certificate file") |
|
| 66 |
- flags.Var(opts.NewQuotedString(&tlsOptions.KeyFile), "tlskey", "Path to TLS key file") |
|
| 67 |
- |
|
| 68 |
- hostOpt := opts.NewNamedListOptsRef("hosts", &commonOpts.Hosts, opts.ValidateHost)
|
|
| 69 |
- flags.VarP(hostOpt, "host", "H", "Daemon socket(s) to connect to") |
|
| 70 |
-} |
|
| 71 |
- |
|
| 72 |
-// SetDefaultOptions sets default values for options after flag parsing is |
|
| 73 |
-// complete |
|
| 74 |
-func (commonOpts *CommonOptions) SetDefaultOptions(flags *pflag.FlagSet) {
|
|
| 75 |
- // Regardless of whether the user sets it to true or false, if they |
|
| 76 |
- // specify --tlsverify at all then we need to turn on TLS |
|
| 77 |
- // TLSVerify can be true even if not set due to DOCKER_TLS_VERIFY env var, so we need |
|
| 78 |
- // to check that here as well |
|
| 79 |
- if flags.Changed(FlagTLSVerify) || commonOpts.TLSVerify {
|
|
| 80 |
- commonOpts.TLS = true |
|
| 81 |
- } |
|
| 82 |
- |
|
| 83 |
- if !commonOpts.TLS {
|
|
| 84 |
- commonOpts.TLSOptions = nil |
|
| 85 |
- } else {
|
|
| 86 |
- tlsOptions := commonOpts.TLSOptions |
|
| 87 |
- tlsOptions.InsecureSkipVerify = !commonOpts.TLSVerify |
|
| 88 |
- |
|
| 89 |
- // Reset CertFile and KeyFile to empty string if the user did not specify |
|
| 90 |
- // the respective flags and the respective default files were not found. |
|
| 91 |
- if !flags.Changed("tlscert") {
|
|
| 92 |
- if _, err := os.Stat(tlsOptions.CertFile); os.IsNotExist(err) {
|
|
| 93 |
- tlsOptions.CertFile = "" |
|
| 94 |
- } |
|
| 95 |
- } |
|
| 96 |
- if !flags.Changed("tlskey") {
|
|
| 97 |
- if _, err := os.Stat(tlsOptions.KeyFile); os.IsNotExist(err) {
|
|
| 98 |
- tlsOptions.KeyFile = "" |
|
| 99 |
- } |
|
| 100 |
- } |
|
| 101 |
- } |
|
| 102 |
-} |
|
| 103 |
- |
|
| 104 |
-// SetLogLevel sets the logrus logging level |
|
| 105 |
-func SetLogLevel(logLevel string) {
|
|
| 106 |
- if logLevel != "" {
|
|
| 107 |
- lvl, err := logrus.ParseLevel(logLevel) |
|
| 108 |
- if err != nil {
|
|
| 109 |
- fmt.Fprintf(os.Stderr, "Unable to parse logging level: %s\n", logLevel) |
|
| 110 |
- os.Exit(1) |
|
| 111 |
- } |
|
| 112 |
- logrus.SetLevel(lvl) |
|
| 113 |
- } else {
|
|
| 114 |
- logrus.SetLevel(logrus.InfoLevel) |
|
| 115 |
- } |
|
| 116 |
-} |
| 117 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,41 +0,0 @@ |
| 1 |
-package flags |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- "path/filepath" |
|
| 5 |
- "testing" |
|
| 6 |
- |
|
| 7 |
- "github.com/spf13/pflag" |
|
| 8 |
- "github.com/stretchr/testify/assert" |
|
| 9 |
-) |
|
| 10 |
- |
|
| 11 |
-func TestCommonOptionsInstallFlags(t *testing.T) {
|
|
| 12 |
- flags := pflag.NewFlagSet("testing", pflag.ContinueOnError)
|
|
| 13 |
- opts := NewCommonOptions() |
|
| 14 |
- opts.InstallFlags(flags) |
|
| 15 |
- |
|
| 16 |
- err := flags.Parse([]string{
|
|
| 17 |
- "--tlscacert=\"/foo/cafile\"", |
|
| 18 |
- "--tlscert=\"/foo/cert\"", |
|
| 19 |
- "--tlskey=\"/foo/key\"", |
|
| 20 |
- }) |
|
| 21 |
- assert.NoError(t, err) |
|
| 22 |
- assert.Equal(t, "/foo/cafile", opts.TLSOptions.CAFile) |
|
| 23 |
- assert.Equal(t, "/foo/cert", opts.TLSOptions.CertFile) |
|
| 24 |
- assert.Equal(t, opts.TLSOptions.KeyFile, "/foo/key") |
|
| 25 |
-} |
|
| 26 |
- |
|
| 27 |
-func defaultPath(filename string) string {
|
|
| 28 |
- return filepath.Join(ConfigurationDir(), filename) |
|
| 29 |
-} |
|
| 30 |
- |
|
| 31 |
-func TestCommonOptionsInstallFlagsWithDefaults(t *testing.T) {
|
|
| 32 |
- flags := pflag.NewFlagSet("testing", pflag.ContinueOnError)
|
|
| 33 |
- opts := NewCommonOptions() |
|
| 34 |
- opts.InstallFlags(flags) |
|
| 35 |
- |
|
| 36 |
- err := flags.Parse([]string{})
|
|
| 37 |
- assert.NoError(t, err) |
|
| 38 |
- assert.Equal(t, defaultPath("ca.pem"), opts.TLSOptions.CAFile)
|
|
| 39 |
- assert.Equal(t, defaultPath("cert.pem"), opts.TLSOptions.CertFile)
|
|
| 40 |
- assert.Equal(t, defaultPath("key.pem"), opts.TLSOptions.KeyFile)
|
|
| 41 |
-} |
| 42 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,25 +0,0 @@ |
| 1 |
-package flags |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- "os" |
|
| 5 |
- "path/filepath" |
|
| 6 |
- |
|
| 7 |
- "github.com/docker/docker/pkg/homedir" |
|
| 8 |
-) |
|
| 9 |
- |
|
| 10 |
-var ( |
|
| 11 |
- configDir = os.Getenv("DOCKER_CONFIG")
|
|
| 12 |
- configFileDir = ".docker" |
|
| 13 |
-) |
|
| 14 |
- |
|
| 15 |
-// ConfigurationDir returns the path to the configuration directory as specified by the DOCKER_CONFIG environment variable. |
|
| 16 |
-// TODO: this was copied from cli/config/configfile and should be removed once cmd/dockerd moves |
|
| 17 |
-func ConfigurationDir() string {
|
|
| 18 |
- return configDir |
|
| 19 |
-} |
|
| 20 |
- |
|
| 21 |
-func init() {
|
|
| 22 |
- if configDir == "" {
|
|
| 23 |
- configDir = filepath.Join(homedir.Get(), configFileDir) |
|
| 24 |
- } |
|
| 25 |
-} |
| ... | ... |
@@ -27,7 +27,6 @@ import ( |
| 27 | 27 |
systemrouter "github.com/docker/docker/api/server/router/system" |
| 28 | 28 |
"github.com/docker/docker/api/server/router/volume" |
| 29 | 29 |
"github.com/docker/docker/cli/debug" |
| 30 |
- cliflags "github.com/docker/docker/cli/flags" |
|
| 31 | 30 |
"github.com/docker/docker/daemon" |
| 32 | 31 |
"github.com/docker/docker/daemon/cluster" |
| 33 | 32 |
"github.com/docker/docker/daemon/config" |
| ... | ... |
@@ -65,14 +64,14 @@ func NewDaemonCli() *DaemonCli {
|
| 65 | 65 |
return &DaemonCli{}
|
| 66 | 66 |
} |
| 67 | 67 |
|
| 68 |
-func (cli *DaemonCli) start(opts daemonOptions) (err error) {
|
|
| 68 |
+func (cli *DaemonCli) start(opts *daemonOptions) (err error) {
|
|
| 69 | 69 |
stopc := make(chan bool) |
| 70 | 70 |
defer close(stopc) |
| 71 | 71 |
|
| 72 | 72 |
// warn from uuid package when running the daemon |
| 73 | 73 |
uuid.Loggerf = logrus.Warnf |
| 74 | 74 |
|
| 75 |
- opts.common.SetDefaultOptions(opts.flags) |
|
| 75 |
+ opts.SetDefaultOptions(opts.flags) |
|
| 76 | 76 |
|
| 77 | 77 |
if cli.Config, err = loadDaemonCliConfig(opts); err != nil {
|
| 78 | 78 |
return err |
| ... | ... |
@@ -358,20 +357,20 @@ func shutdownDaemon(d *daemon.Daemon) {
|
| 358 | 358 |
} |
| 359 | 359 |
} |
| 360 | 360 |
|
| 361 |
-func loadDaemonCliConfig(opts daemonOptions) (*config.Config, error) {
|
|
| 361 |
+func loadDaemonCliConfig(opts *daemonOptions) (*config.Config, error) {
|
|
| 362 | 362 |
conf := opts.daemonConfig |
| 363 | 363 |
flags := opts.flags |
| 364 |
- conf.Debug = opts.common.Debug |
|
| 365 |
- conf.Hosts = opts.common.Hosts |
|
| 366 |
- conf.LogLevel = opts.common.LogLevel |
|
| 367 |
- conf.TLS = opts.common.TLS |
|
| 368 |
- conf.TLSVerify = opts.common.TLSVerify |
|
| 364 |
+ conf.Debug = opts.Debug |
|
| 365 |
+ conf.Hosts = opts.Hosts |
|
| 366 |
+ conf.LogLevel = opts.LogLevel |
|
| 367 |
+ conf.TLS = opts.TLS |
|
| 368 |
+ conf.TLSVerify = opts.TLSVerify |
|
| 369 | 369 |
conf.CommonTLSOptions = config.CommonTLSOptions{}
|
| 370 | 370 |
|
| 371 |
- if opts.common.TLSOptions != nil {
|
|
| 372 |
- conf.CommonTLSOptions.CAFile = opts.common.TLSOptions.CAFile |
|
| 373 |
- conf.CommonTLSOptions.CertFile = opts.common.TLSOptions.CertFile |
|
| 374 |
- conf.CommonTLSOptions.KeyFile = opts.common.TLSOptions.KeyFile |
|
| 371 |
+ if opts.TLSOptions != nil {
|
|
| 372 |
+ conf.CommonTLSOptions.CAFile = opts.TLSOptions.CAFile |
|
| 373 |
+ conf.CommonTLSOptions.CertFile = opts.TLSOptions.CertFile |
|
| 374 |
+ conf.CommonTLSOptions.KeyFile = opts.TLSOptions.KeyFile |
|
| 375 | 375 |
} |
| 376 | 376 |
|
| 377 | 377 |
if conf.TrustKeyPath == "" {
|
| ... | ... |
@@ -425,12 +424,12 @@ func loadDaemonCliConfig(opts daemonOptions) (*config.Config, error) {
|
| 425 | 425 |
|
| 426 | 426 |
// Regardless of whether the user sets it to true or false, if they |
| 427 | 427 |
// specify TLSVerify at all then we need to turn on TLS |
| 428 |
- if conf.IsValueSet(cliflags.FlagTLSVerify) {
|
|
| 428 |
+ if conf.IsValueSet(FlagTLSVerify) {
|
|
| 429 | 429 |
conf.TLS = true |
| 430 | 430 |
} |
| 431 | 431 |
|
| 432 | 432 |
// ensure that the log level is the one set after merging configurations |
| 433 |
- cliflags.SetLogLevel(conf.LogLevel) |
|
| 433 |
+ setLogLevel(conf.LogLevel) |
|
| 434 | 434 |
|
| 435 | 435 |
return conf, nil |
| 436 | 436 |
} |
| ... | ... |
@@ -4,7 +4,6 @@ import ( |
| 4 | 4 |
"testing" |
| 5 | 5 |
|
| 6 | 6 |
"github.com/Sirupsen/logrus" |
| 7 |
- cliflags "github.com/docker/docker/cli/flags" |
|
| 8 | 7 |
"github.com/docker/docker/daemon/config" |
| 9 | 8 |
"github.com/docker/docker/pkg/testutil" |
| 10 | 9 |
"github.com/docker/docker/pkg/testutil/tempfile" |
| ... | ... |
@@ -13,13 +12,10 @@ import ( |
| 13 | 13 |
"github.com/stretchr/testify/require" |
| 14 | 14 |
) |
| 15 | 15 |
|
| 16 |
-func defaultOptions(configFile string) daemonOptions {
|
|
| 17 |
- opts := daemonOptions{
|
|
| 18 |
- daemonConfig: &config.Config{},
|
|
| 19 |
- flags: &pflag.FlagSet{},
|
|
| 20 |
- common: cliflags.NewCommonOptions(), |
|
| 21 |
- } |
|
| 22 |
- opts.common.InstallFlags(opts.flags) |
|
| 16 |
+func defaultOptions(configFile string) *daemonOptions {
|
|
| 17 |
+ opts := newDaemonOptions(&config.Config{})
|
|
| 18 |
+ opts.flags = &pflag.FlagSet{}
|
|
| 19 |
+ opts.InstallFlags(opts.flags) |
|
| 23 | 20 |
installConfigFlags(opts.daemonConfig, opts.flags) |
| 24 | 21 |
opts.flags.StringVar(&opts.configFile, "config-file", defaultDaemonConfigFile, "") |
| 25 | 22 |
opts.configFile = configFile |
| ... | ... |
@@ -28,7 +24,7 @@ func defaultOptions(configFile string) daemonOptions {
|
| 28 | 28 |
|
| 29 | 29 |
func TestLoadDaemonCliConfigWithoutOverriding(t *testing.T) {
|
| 30 | 30 |
opts := defaultOptions("")
|
| 31 |
- opts.common.Debug = true |
|
| 31 |
+ opts.Debug = true |
|
| 32 | 32 |
|
| 33 | 33 |
loadedConfig, err := loadDaemonCliConfig(opts) |
| 34 | 34 |
require.NoError(t, err) |
| ... | ... |
@@ -40,8 +36,8 @@ func TestLoadDaemonCliConfigWithoutOverriding(t *testing.T) {
|
| 40 | 40 |
|
| 41 | 41 |
func TestLoadDaemonCliConfigWithTLS(t *testing.T) {
|
| 42 | 42 |
opts := defaultOptions("")
|
| 43 |
- opts.common.TLSOptions.CAFile = "/tmp/ca.pem" |
|
| 44 |
- opts.common.TLS = true |
|
| 43 |
+ opts.TLSOptions.CAFile = "/tmp/ca.pem" |
|
| 44 |
+ opts.TLS = true |
|
| 45 | 45 |
|
| 46 | 46 |
loadedConfig, err := loadDaemonCliConfig(opts) |
| 47 | 47 |
require.NoError(t, err) |
| ... | ... |
@@ -70,7 +66,7 @@ func TestLoadDaemonCliConfigWithTLSVerify(t *testing.T) {
|
| 70 | 70 |
defer tempFile.Remove() |
| 71 | 71 |
|
| 72 | 72 |
opts := defaultOptions(tempFile.Name()) |
| 73 |
- opts.common.TLSOptions.CAFile = "/tmp/ca.pem" |
|
| 73 |
+ opts.TLSOptions.CAFile = "/tmp/ca.pem" |
|
| 74 | 74 |
|
| 75 | 75 |
loadedConfig, err := loadDaemonCliConfig(opts) |
| 76 | 76 |
require.NoError(t, err) |
| ... | ... |
@@ -83,7 +79,7 @@ func TestLoadDaemonCliConfigWithExplicitTLSVerifyFalse(t *testing.T) {
|
| 83 | 83 |
defer tempFile.Remove() |
| 84 | 84 |
|
| 85 | 85 |
opts := defaultOptions(tempFile.Name()) |
| 86 |
- opts.common.TLSOptions.CAFile = "/tmp/ca.pem" |
|
| 86 |
+ opts.TLSOptions.CAFile = "/tmp/ca.pem" |
|
| 87 | 87 |
|
| 88 | 88 |
loadedConfig, err := loadDaemonCliConfig(opts) |
| 89 | 89 |
require.NoError(t, err) |
| ... | ... |
@@ -96,7 +92,7 @@ func TestLoadDaemonCliConfigWithoutTLSVerify(t *testing.T) {
|
| 96 | 96 |
defer tempFile.Remove() |
| 97 | 97 |
|
| 98 | 98 |
opts := defaultOptions(tempFile.Name()) |
| 99 |
- opts.common.TLSOptions.CAFile = "/tmp/ca.pem" |
|
| 99 |
+ opts.TLSOptions.CAFile = "/tmp/ca.pem" |
|
| 100 | 100 |
|
| 101 | 101 |
loadedConfig, err := loadDaemonCliConfig(opts) |
| 102 | 102 |
require.NoError(t, err) |
| ... | ... |
@@ -20,8 +20,8 @@ func TestLoadDaemonCliConfigWithDaemonFlags(t *testing.T) {
|
| 20 | 20 |
defer tempFile.Remove() |
| 21 | 21 |
|
| 22 | 22 |
opts := defaultOptions(tempFile.Name()) |
| 23 |
- opts.common.Debug = true |
|
| 24 |
- opts.common.LogLevel = "info" |
|
| 23 |
+ opts.Debug = true |
|
| 24 |
+ opts.LogLevel = "info" |
|
| 25 | 25 |
assert.NoError(t, opts.flags.Set("selinux-enabled", "true"))
|
| 26 | 26 |
|
| 27 | 27 |
loadedConfig, err := loadDaemonCliConfig(opts) |
| ... | ... |
@@ -8,28 +8,15 @@ import ( |
| 8 | 8 |
|
| 9 | 9 |
"github.com/Sirupsen/logrus" |
| 10 | 10 |
"github.com/docker/docker/cli" |
| 11 |
- cliflags "github.com/docker/docker/cli/flags" |
|
| 12 | 11 |
"github.com/docker/docker/daemon/config" |
| 13 | 12 |
"github.com/docker/docker/dockerversion" |
| 14 | 13 |
"github.com/docker/docker/pkg/reexec" |
| 15 | 14 |
"github.com/docker/docker/pkg/term" |
| 16 | 15 |
"github.com/spf13/cobra" |
| 17 |
- "github.com/spf13/pflag" |
|
| 18 | 16 |
) |
| 19 | 17 |
|
| 20 |
-type daemonOptions struct {
|
|
| 21 |
- version bool |
|
| 22 |
- configFile string |
|
| 23 |
- daemonConfig *config.Config |
|
| 24 |
- common *cliflags.CommonOptions |
|
| 25 |
- flags *pflag.FlagSet |
|
| 26 |
-} |
|
| 27 |
- |
|
| 28 | 18 |
func newDaemonCommand() *cobra.Command {
|
| 29 |
- opts := daemonOptions{
|
|
| 30 |
- daemonConfig: config.New(), |
|
| 31 |
- common: cliflags.NewCommonOptions(), |
|
| 32 |
- } |
|
| 19 |
+ opts := newDaemonOptions(config.New()) |
|
| 33 | 20 |
|
| 34 | 21 |
cmd := &cobra.Command{
|
| 35 | 22 |
Use: "dockerd [OPTIONS]", |
| ... | ... |
@@ -47,14 +34,14 @@ func newDaemonCommand() *cobra.Command {
|
| 47 | 47 |
flags := cmd.Flags() |
| 48 | 48 |
flags.BoolVarP(&opts.version, "version", "v", false, "Print version information and quit") |
| 49 | 49 |
flags.StringVar(&opts.configFile, "config-file", defaultDaemonConfigFile, "Daemon configuration file") |
| 50 |
- opts.common.InstallFlags(flags) |
|
| 50 |
+ opts.InstallFlags(flags) |
|
| 51 | 51 |
installConfigFlags(opts.daemonConfig, flags) |
| 52 | 52 |
installServiceFlags(flags) |
| 53 | 53 |
|
| 54 | 54 |
return cmd |
| 55 | 55 |
} |
| 56 | 56 |
|
| 57 |
-func runDaemon(opts daemonOptions) error {
|
|
| 57 |
+func runDaemon(opts *daemonOptions) error {
|
|
| 58 | 58 |
if opts.version {
|
| 59 | 59 |
showVersion() |
| 60 | 60 |
return nil |
| 61 | 61 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,123 @@ |
| 0 |
+package main |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "fmt" |
|
| 4 |
+ "os" |
|
| 5 |
+ "path/filepath" |
|
| 6 |
+ |
|
| 7 |
+ "github.com/Sirupsen/logrus" |
|
| 8 |
+ cliconfig "github.com/docker/docker/cli/config" |
|
| 9 |
+ "github.com/docker/docker/daemon/config" |
|
| 10 |
+ "github.com/docker/docker/opts" |
|
| 11 |
+ "github.com/docker/go-connections/tlsconfig" |
|
| 12 |
+ "github.com/spf13/pflag" |
|
| 13 |
+) |
|
| 14 |
+ |
|
| 15 |
+const ( |
|
| 16 |
+ // DefaultCaFile is the default filename for the CA pem file |
|
| 17 |
+ DefaultCaFile = "ca.pem" |
|
| 18 |
+ // DefaultKeyFile is the default filename for the key pem file |
|
| 19 |
+ DefaultKeyFile = "key.pem" |
|
| 20 |
+ // DefaultCertFile is the default filename for the cert pem file |
|
| 21 |
+ DefaultCertFile = "cert.pem" |
|
| 22 |
+ // FlagTLSVerify is the flag name for the TLS verification option |
|
| 23 |
+ FlagTLSVerify = "tlsverify" |
|
| 24 |
+) |
|
| 25 |
+ |
|
| 26 |
+var ( |
|
| 27 |
+ dockerCertPath = os.Getenv("DOCKER_CERT_PATH")
|
|
| 28 |
+ dockerTLSVerify = os.Getenv("DOCKER_TLS_VERIFY") != ""
|
|
| 29 |
+) |
|
| 30 |
+ |
|
| 31 |
+type daemonOptions struct {
|
|
| 32 |
+ version bool |
|
| 33 |
+ configFile string |
|
| 34 |
+ daemonConfig *config.Config |
|
| 35 |
+ flags *pflag.FlagSet |
|
| 36 |
+ Debug bool |
|
| 37 |
+ Hosts []string |
|
| 38 |
+ LogLevel string |
|
| 39 |
+ TLS bool |
|
| 40 |
+ TLSVerify bool |
|
| 41 |
+ TLSOptions *tlsconfig.Options |
|
| 42 |
+} |
|
| 43 |
+ |
|
| 44 |
+// newDaemonOptions returns a new daemonFlags |
|
| 45 |
+func newDaemonOptions(config *config.Config) *daemonOptions {
|
|
| 46 |
+ return &daemonOptions{
|
|
| 47 |
+ daemonConfig: config, |
|
| 48 |
+ } |
|
| 49 |
+} |
|
| 50 |
+ |
|
| 51 |
+// InstallFlags adds flags for the common options on the FlagSet |
|
| 52 |
+func (o *daemonOptions) InstallFlags(flags *pflag.FlagSet) {
|
|
| 53 |
+ if dockerCertPath == "" {
|
|
| 54 |
+ dockerCertPath = cliconfig.Dir() |
|
| 55 |
+ } |
|
| 56 |
+ |
|
| 57 |
+ flags.BoolVarP(&o.Debug, "debug", "D", false, "Enable debug mode") |
|
| 58 |
+ flags.StringVarP(&o.LogLevel, "log-level", "l", "info", `Set the logging level ("debug"|"info"|"warn"|"error"|"fatal")`)
|
|
| 59 |
+ flags.BoolVar(&o.TLS, "tls", false, "Use TLS; implied by --tlsverify") |
|
| 60 |
+ flags.BoolVar(&o.TLSVerify, FlagTLSVerify, dockerTLSVerify, "Use TLS and verify the remote") |
|
| 61 |
+ |
|
| 62 |
+ // TODO use flag flags.String("identity"}, "i", "", "Path to libtrust key file")
|
|
| 63 |
+ |
|
| 64 |
+ o.TLSOptions = &tlsconfig.Options{
|
|
| 65 |
+ CAFile: filepath.Join(dockerCertPath, DefaultCaFile), |
|
| 66 |
+ CertFile: filepath.Join(dockerCertPath, DefaultCertFile), |
|
| 67 |
+ KeyFile: filepath.Join(dockerCertPath, DefaultKeyFile), |
|
| 68 |
+ } |
|
| 69 |
+ tlsOptions := o.TLSOptions |
|
| 70 |
+ flags.Var(opts.NewQuotedString(&tlsOptions.CAFile), "tlscacert", "Trust certs signed only by this CA") |
|
| 71 |
+ flags.Var(opts.NewQuotedString(&tlsOptions.CertFile), "tlscert", "Path to TLS certificate file") |
|
| 72 |
+ flags.Var(opts.NewQuotedString(&tlsOptions.KeyFile), "tlskey", "Path to TLS key file") |
|
| 73 |
+ |
|
| 74 |
+ hostOpt := opts.NewNamedListOptsRef("hosts", &o.Hosts, opts.ValidateHost)
|
|
| 75 |
+ flags.VarP(hostOpt, "host", "H", "Daemon socket(s) to connect to") |
|
| 76 |
+} |
|
| 77 |
+ |
|
| 78 |
+// SetDefaultOptions sets default values for options after flag parsing is |
|
| 79 |
+// complete |
|
| 80 |
+func (o *daemonOptions) SetDefaultOptions(flags *pflag.FlagSet) {
|
|
| 81 |
+ // Regardless of whether the user sets it to true or false, if they |
|
| 82 |
+ // specify --tlsverify at all then we need to turn on TLS |
|
| 83 |
+ // TLSVerify can be true even if not set due to DOCKER_TLS_VERIFY env var, so we need |
|
| 84 |
+ // to check that here as well |
|
| 85 |
+ if flags.Changed(FlagTLSVerify) || o.TLSVerify {
|
|
| 86 |
+ o.TLS = true |
|
| 87 |
+ } |
|
| 88 |
+ |
|
| 89 |
+ if !o.TLS {
|
|
| 90 |
+ o.TLSOptions = nil |
|
| 91 |
+ } else {
|
|
| 92 |
+ tlsOptions := o.TLSOptions |
|
| 93 |
+ tlsOptions.InsecureSkipVerify = !o.TLSVerify |
|
| 94 |
+ |
|
| 95 |
+ // Reset CertFile and KeyFile to empty string if the user did not specify |
|
| 96 |
+ // the respective flags and the respective default files were not found. |
|
| 97 |
+ if !flags.Changed("tlscert") {
|
|
| 98 |
+ if _, err := os.Stat(tlsOptions.CertFile); os.IsNotExist(err) {
|
|
| 99 |
+ tlsOptions.CertFile = "" |
|
| 100 |
+ } |
|
| 101 |
+ } |
|
| 102 |
+ if !flags.Changed("tlskey") {
|
|
| 103 |
+ if _, err := os.Stat(tlsOptions.KeyFile); os.IsNotExist(err) {
|
|
| 104 |
+ tlsOptions.KeyFile = "" |
|
| 105 |
+ } |
|
| 106 |
+ } |
|
| 107 |
+ } |
|
| 108 |
+} |
|
| 109 |
+ |
|
| 110 |
+// setLogLevel sets the logrus logging level |
|
| 111 |
+func setLogLevel(logLevel string) {
|
|
| 112 |
+ if logLevel != "" {
|
|
| 113 |
+ lvl, err := logrus.ParseLevel(logLevel) |
|
| 114 |
+ if err != nil {
|
|
| 115 |
+ fmt.Fprintf(os.Stderr, "Unable to parse logging level: %s\n", logLevel) |
|
| 116 |
+ os.Exit(1) |
|
| 117 |
+ } |
|
| 118 |
+ logrus.SetLevel(lvl) |
|
| 119 |
+ } else {
|
|
| 120 |
+ logrus.SetLevel(logrus.InfoLevel) |
|
| 121 |
+ } |
|
| 122 |
+} |
| 0 | 123 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,43 @@ |
| 0 |
+package main |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "path/filepath" |
|
| 4 |
+ "testing" |
|
| 5 |
+ |
|
| 6 |
+ cliconfig "github.com/docker/docker/cli/config" |
|
| 7 |
+ "github.com/docker/docker/daemon/config" |
|
| 8 |
+ "github.com/spf13/pflag" |
|
| 9 |
+ "github.com/stretchr/testify/assert" |
|
| 10 |
+) |
|
| 11 |
+ |
|
| 12 |
+func TestCommonOptionsInstallFlags(t *testing.T) {
|
|
| 13 |
+ flags := pflag.NewFlagSet("testing", pflag.ContinueOnError)
|
|
| 14 |
+ opts := newDaemonOptions(&config.Config{})
|
|
| 15 |
+ opts.InstallFlags(flags) |
|
| 16 |
+ |
|
| 17 |
+ err := flags.Parse([]string{
|
|
| 18 |
+ "--tlscacert=\"/foo/cafile\"", |
|
| 19 |
+ "--tlscert=\"/foo/cert\"", |
|
| 20 |
+ "--tlskey=\"/foo/key\"", |
|
| 21 |
+ }) |
|
| 22 |
+ assert.NoError(t, err) |
|
| 23 |
+ assert.Equal(t, "/foo/cafile", opts.TLSOptions.CAFile) |
|
| 24 |
+ assert.Equal(t, "/foo/cert", opts.TLSOptions.CertFile) |
|
| 25 |
+ assert.Equal(t, opts.TLSOptions.KeyFile, "/foo/key") |
|
| 26 |
+} |
|
| 27 |
+ |
|
| 28 |
+func defaultPath(filename string) string {
|
|
| 29 |
+ return filepath.Join(cliconfig.Dir(), filename) |
|
| 30 |
+} |
|
| 31 |
+ |
|
| 32 |
+func TestCommonOptionsInstallFlagsWithDefaults(t *testing.T) {
|
|
| 33 |
+ flags := pflag.NewFlagSet("testing", pflag.ContinueOnError)
|
|
| 34 |
+ opts := newDaemonOptions(&config.Config{})
|
|
| 35 |
+ opts.InstallFlags(flags) |
|
| 36 |
+ |
|
| 37 |
+ err := flags.Parse([]string{})
|
|
| 38 |
+ assert.NoError(t, err) |
|
| 39 |
+ assert.Equal(t, defaultPath("ca.pem"), opts.TLSOptions.CAFile)
|
|
| 40 |
+ assert.Equal(t, defaultPath("cert.pem"), opts.TLSOptions.CertFile)
|
|
| 41 |
+ assert.Equal(t, defaultPath("key.pem"), opts.TLSOptions.KeyFile)
|
|
| 42 |
+} |
| ... | ... |
@@ -12,7 +12,7 @@ import ( |
| 12 | 12 |
"testing" |
| 13 | 13 |
|
| 14 | 14 |
"github.com/docker/docker/api/types/swarm" |
| 15 |
- "github.com/docker/docker/cli/flags" |
|
| 15 |
+ "github.com/docker/docker/cli/config" |
|
| 16 | 16 |
"github.com/docker/docker/integration-cli/cli" |
| 17 | 17 |
"github.com/docker/docker/integration-cli/cli/build/fakestorage" |
| 18 | 18 |
"github.com/docker/docker/integration-cli/daemon" |
| ... | ... |
@@ -406,7 +406,7 @@ func (s *DockerTrustSuite) TearDownTest(c *check.C) {
|
| 406 | 406 |
} |
| 407 | 407 |
|
| 408 | 408 |
// Remove trusted keys and metadata after test |
| 409 |
- os.RemoveAll(filepath.Join(flags.ConfigurationDir(), "trust")) |
|
| 409 |
+ os.RemoveAll(filepath.Join(config.Dir(), "trust")) |
|
| 410 | 410 |
s.ds.TearDownTest(c) |
| 411 | 411 |
} |
| 412 | 412 |
|
| ... | ... |
@@ -12,7 +12,7 @@ import ( |
| 12 | 12 |
"sync" |
| 13 | 13 |
|
| 14 | 14 |
"github.com/docker/distribution/reference" |
| 15 |
- "github.com/docker/docker/cli/flags" |
|
| 15 |
+ "github.com/docker/docker/cli/config" |
|
| 16 | 16 |
"github.com/docker/docker/integration-cli/checker" |
| 17 | 17 |
"github.com/docker/docker/integration-cli/cli" |
| 18 | 18 |
"github.com/docker/docker/integration-cli/cli/build" |
| ... | ... |
@@ -294,7 +294,7 @@ func (s *DockerTrustSuite) TestTrustedPush(c *check.C) {
|
| 294 | 294 |
}) |
| 295 | 295 |
|
| 296 | 296 |
// Assert that we rotated the snapshot key to the server by checking our local keystore |
| 297 |
- contents, err := ioutil.ReadDir(filepath.Join(flags.ConfigurationDir(), "trust/private/tuf_keys", privateRegistryURL, "dockerclitrusted/pushtest")) |
|
| 297 |
+ contents, err := ioutil.ReadDir(filepath.Join(config.Dir(), "trust/private/tuf_keys", privateRegistryURL, "dockerclitrusted/pushtest")) |
|
| 298 | 298 |
c.Assert(err, check.IsNil, check.Commentf("Unable to read local tuf key files"))
|
| 299 | 299 |
// Check that we only have 1 key (targets key) |
| 300 | 300 |
c.Assert(contents, checker.HasLen, 1) |
| ... | ... |
@@ -399,7 +399,7 @@ func (s *DockerTrustSuite) TestTrustedPushWithReleasesDelegationOnly(c *check.C) |
| 399 | 399 |
s.assertTargetNotInRoles(c, repoName, "latest", "targets") |
| 400 | 400 |
|
| 401 | 401 |
// Try pull after push |
| 402 |
- os.RemoveAll(filepath.Join(flags.ConfigurationDir(), "trust")) |
|
| 402 |
+ os.RemoveAll(filepath.Join(config.Dir(), "trust")) |
|
| 403 | 403 |
|
| 404 | 404 |
cli.Docker(cli.Args("pull", targetName), trustedCmd).Assert(c, icmd.Expected{
|
| 405 | 405 |
Out: "Status: Image is up to date", |
| ... | ... |
@@ -436,7 +436,7 @@ func (s *DockerTrustSuite) TestTrustedPushSignsAllFirstLevelRolesWeHaveKeysFor(c |
| 436 | 436 |
s.assertTargetNotInRoles(c, repoName, "latest", "targets") |
| 437 | 437 |
|
| 438 | 438 |
// Try pull after push |
| 439 |
- os.RemoveAll(filepath.Join(flags.ConfigurationDir(), "trust")) |
|
| 439 |
+ os.RemoveAll(filepath.Join(config.Dir(), "trust")) |
|
| 440 | 440 |
|
| 441 | 441 |
// pull should fail because none of these are the releases role |
| 442 | 442 |
cli.Docker(cli.Args("pull", targetName), trustedCmd).Assert(c, icmd.Expected{
|
| ... | ... |
@@ -472,7 +472,7 @@ func (s *DockerTrustSuite) TestTrustedPushSignsForRolesWithKeysAndValidPaths(c * |
| 472 | 472 |
s.assertTargetNotInRoles(c, repoName, "latest", "targets") |
| 473 | 473 |
|
| 474 | 474 |
// Try pull after push |
| 475 |
- os.RemoveAll(filepath.Join(flags.ConfigurationDir(), "trust")) |
|
| 475 |
+ os.RemoveAll(filepath.Join(config.Dir(), "trust")) |
|
| 476 | 476 |
|
| 477 | 477 |
// pull should fail because none of these are the releases role |
| 478 | 478 |
cli.Docker(cli.Args("pull", targetName), trustedCmd).Assert(c, icmd.Expected{
|
| ... | ... |
@@ -11,7 +11,7 @@ import ( |
| 11 | 11 |
"strings" |
| 12 | 12 |
"time" |
| 13 | 13 |
|
| 14 |
- "github.com/docker/docker/cli/flags" |
|
| 14 |
+ cliconfig "github.com/docker/docker/cli/config" |
|
| 15 | 15 |
"github.com/docker/docker/integration-cli/checker" |
| 16 | 16 |
"github.com/docker/docker/integration-cli/cli" |
| 17 | 17 |
icmd "github.com/docker/docker/pkg/testutil/cmd" |
| ... | ... |
@@ -108,7 +108,7 @@ func newTestNotary(c *check.C) (*testNotary, error) {
|
| 108 | 108 |
"skipTLSVerify": true |
| 109 | 109 |
} |
| 110 | 110 |
}` |
| 111 |
- if _, err = fmt.Fprintf(clientConfig, template, filepath.Join(flags.ConfigurationDir(), "trust"), notaryURL); err != nil {
|
|
| 111 |
+ if _, err = fmt.Fprintf(clientConfig, template, filepath.Join(cliconfig.Dir(), "trust"), notaryURL); err != nil {
|
|
| 112 | 112 |
os.RemoveAll(tmp) |
| 113 | 113 |
return nil, err |
| 114 | 114 |
} |