From a4befff533cf786df7a4da29798984ebb2268d8c Mon Sep 17 00:00:00 2001 From: Solomon Hykes Date: Sat, 9 Aug 2014 22:30:27 +0000 Subject: [PATCH 1/8] Move daemonconfig into daemon Signed-off-by: Solomon Hykes --- {daemonconfig => daemon}/config.go | 5 ++++- daemon/daemon.go | 9 ++++----- daemonconfig/README.md | 3 --- docker/daemon.go | 11 +++++------ integration/utils_test.go | 12 +++++++----- 5 files changed, 20 insertions(+), 20 deletions(-) rename {daemonconfig => daemon}/config.go (84%) delete mode 100644 daemonconfig/README.md diff --git a/daemonconfig/config.go b/daemon/config.go similarity index 84% rename from daemonconfig/config.go rename to daemon/config.go index 13c2a5db5c..0f269da869 100644 --- a/daemonconfig/config.go +++ b/daemon/config.go @@ -1,4 +1,4 @@ -package daemonconfig +package daemon import ( "github.com/docker/docker/daemon/networkdriver" @@ -10,6 +10,9 @@ const ( DisableNetworkBridge = "none" ) +// Config define the configuration of a docker daemon +// These are the configuration settings that you pass +// to the docker daemon when you launch it with say: `docker -d -e lxc` // FIXME: separate runtime configuration from http api configuration type Config struct { Pidfile string diff --git a/daemon/daemon.go b/daemon/daemon.go index d65bad8b82..0a2ad4c315 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -21,7 +21,6 @@ import ( _ "github.com/docker/docker/daemon/graphdriver/vfs" _ "github.com/docker/docker/daemon/networkdriver/bridge" "github.com/docker/docker/daemon/networkdriver/portallocator" - "github.com/docker/docker/daemonconfig" "github.com/docker/docker/dockerversion" "github.com/docker/docker/engine" "github.com/docker/docker/graph" @@ -95,7 +94,7 @@ type Daemon struct { sysInfo *sysinfo.SysInfo volumes *graph.Graph eng *engine.Engine - config *daemonconfig.Config + config *Config containerGraph *graphdb.Database driver graphdriver.Driver execDriver execdriver.Driver @@ -664,7 +663,7 @@ func (daemon *Daemon) RegisterLinks(container *Container, hostConfig *runconfig. } // FIXME: harmonize with NewGraph() -func NewDaemon(config *daemonconfig.Config, eng *engine.Engine) (*Daemon, error) { +func NewDaemon(config *Config, eng *engine.Engine) (*Daemon, error) { daemon, err := NewDaemonFromDirectory(config, eng) if err != nil { return nil, err @@ -672,7 +671,7 @@ func NewDaemon(config *daemonconfig.Config, eng *engine.Engine) (*Daemon, error) return daemon, nil } -func NewDaemonFromDirectory(config *daemonconfig.Config, eng *engine.Engine) (*Daemon, error) { +func NewDaemonFromDirectory(config *Config, eng *engine.Engine) (*Daemon, error) { // Claim the pidfile first, to avoid any and all unexpected race conditions. // Some of the init doesn't need a pidfile lock - but let's not try to be smart. if config.Pidfile != "" { @@ -1010,7 +1009,7 @@ func (daemon *Daemon) Repositories() *graph.TagStore { return daemon.repositories } -func (daemon *Daemon) Config() *daemonconfig.Config { +func (daemon *Daemon) Config() *Config { return daemon.config } diff --git a/daemonconfig/README.md b/daemonconfig/README.md deleted file mode 100644 index b61df1449e..0000000000 --- a/daemonconfig/README.md +++ /dev/null @@ -1,3 +0,0 @@ -This directory contains code pertaining to the configuration of the docker daemon - -These are the configuration settings that you pass to the docker daemon when you launch it with say: `docker -d -e lxc` diff --git a/docker/daemon.go b/docker/daemon.go index 6a4d767733..2866f6990c 100644 --- a/docker/daemon.go +++ b/docker/daemon.go @@ -10,7 +10,6 @@ import ( "github.com/docker/docker/daemon" _ "github.com/docker/docker/daemon/execdriver/lxc" _ "github.com/docker/docker/daemon/execdriver/native" - "github.com/docker/docker/daemonconfig" "github.com/docker/docker/dockerversion" "github.com/docker/docker/engine" flag "github.com/docker/docker/pkg/mflag" @@ -48,8 +47,8 @@ func mainDaemon() { // the http api so that connections don't fail while the daemon // is booting go func() { - // FIXME: daemonconfig and CLI flag parsing should be directly integrated - cfg := &daemonconfig.Config{ + // FIXME: daemon config and CLI flag parsing should be directly integrated + cfg := &daemon.Config{ Pidfile: *pidfile, Root: *flRoot, AutoRestart: *flAutoRestart, @@ -68,12 +67,12 @@ func mainDaemon() { Mtu: *flMtu, Sockets: flHosts.GetAll(), } - // FIXME this should be initialized in NewDaemon or somewhere in daemonconfig. + // FIXME this should be initialized in NewDaemon or somewhere in daemon. // Currently it is copy-pasted in `integration` to create test daemons that work. if cfg.Mtu == 0 { - cfg.Mtu = daemonconfig.GetDefaultNetworkMtu() + cfg.Mtu = daemon.GetDefaultNetworkMtu() } - cfg.DisableNetwork = cfg.BridgeIface == daemonconfig.DisableNetworkBridge + cfg.DisableNetwork = cfg.BridgeIface == daemon.DisableNetworkBridge d, err := daemon.NewDaemon(cfg, eng) if err != nil { diff --git a/integration/utils_test.go b/integration/utils_test.go index 29741465a8..a7f3f999e2 100644 --- a/integration/utils_test.go +++ b/integration/utils_test.go @@ -17,7 +17,6 @@ import ( "github.com/docker/docker/builtins" "github.com/docker/docker/daemon" - "github.com/docker/docker/daemonconfig" "github.com/docker/docker/engine" "github.com/docker/docker/runconfig" "github.com/docker/docker/utils" @@ -179,17 +178,20 @@ func newTestEngine(t utils.Fataler, autorestart bool, root string) *engine.Engin // Load default plugins builtins.Register(eng) // (This is manually copied and modified from main() until we have a more generic plugin system) - cfg := &daemonconfig.Config{ + cfg := &daemon.Config{ Root: root, AutoRestart: autorestart, ExecDriver: "native", + // Either InterContainerCommunication or EnableIptables must be set, + // otherwise NewDaemon will fail because of conflicting settings. + InterContainerCommunication: true, } - // FIXME: this should be initialized in NewDaemon or somewhere in daemonconfig. + // FIXME: this should be initialized in NewDaemon // Currently it is copy-pasted from daemonMain() if cfg.Mtu == 0 { - cfg.Mtu = daemonconfig.GetDefaultNetworkMtu() + cfg.Mtu = daemon.GetDefaultNetworkMtu() } - cfg.DisableNetwork = cfg.BridgeIface == daemonconfig.DisableNetworkBridge + cfg.DisableNetwork = cfg.BridgeIface == daemon.DisableNetworkBridge d, err := daemon.NewDaemon(cfg, eng) if err != nil { t.Fatal(err) From 6d59a566759da5729d7eb89a8e1888fc612f03cf Mon Sep 17 00:00:00 2001 From: Solomon Hykes Date: Sun, 10 Aug 2014 01:12:52 +0000 Subject: [PATCH 2/8] opts.IpOpt: a helper to parse IP addressed from the command line Signed-off-by: Solomon Hykes --- opts/ip.go | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 opts/ip.go diff --git a/opts/ip.go b/opts/ip.go new file mode 100644 index 0000000000..3610b14538 --- /dev/null +++ b/opts/ip.go @@ -0,0 +1,28 @@ +package opts + +import ( + "net" +) + +type IpOpt struct { + *net.IP +} + +func NewIpOpt(ref *net.IP, defaultVal string) *IpOpt { + o := &IpOpt{ + IP: ref, + } + o.Set(defaultVal) + return o +} + +func (o *IpOpt) Set(val string) error { + // FIXME: return a parse error if the value is not a valid IP? + // We are not changing this now to preserve behavior while refactoring. + (*o.IP) = net.ParseIP(val) + return nil +} + +func (o *IpOpt) String() string { + return (*o.IP).String() +} From 6200002669874f3314856527fecd0c004060913c Mon Sep 17 00:00:00 2001 From: Solomon Hykes Date: Sun, 10 Aug 2014 01:13:44 +0000 Subject: [PATCH 3/8] Helpers to parse lists, IPs, hosts, dns searches from the command line Signed-off-by: Solomon Hykes --- api/client/commands.go | 4 ++-- docker/flags.go | 2 +- opts/opts.go | 48 +++++++++++++++++++++++++++++++++--------- opts/opts_test.go | 6 ++++++ runconfig/parse.go | 14 ++++++------ 5 files changed, 54 insertions(+), 20 deletions(-) diff --git a/api/client/commands.go b/api/client/commands.go index 1d6ff1668e..e4c1808f1c 100644 --- a/api/client/commands.go +++ b/api/client/commands.go @@ -1254,7 +1254,7 @@ func (cli *DockerCli) CmdImages(args ...string) error { flViz := cmd.Bool([]string{"#v", "#viz", "#-viz"}, false, "Output graph in graphviz format") flTree := cmd.Bool([]string{"#t", "#tree", "#-tree"}, false, "Output graph in tree format") - var flFilter opts.ListOpts + flFilter := opts.NewListOpts(nil) cmd.Var(&flFilter, []string{"f", "-filter"}, "Provide filter values (i.e. 'dangling=true')") if err := cmd.Parse(args); err != nil { @@ -1487,7 +1487,7 @@ func (cli *DockerCli) CmdPs(args ...string) error { before := cmd.String([]string{"#beforeId", "#-before-id", "-before"}, "", "Show only container created before Id or Name, include non-running ones.") last := cmd.Int([]string{"n"}, -1, "Show n last created containers, include non-running ones.") - var flFilter opts.ListOpts + flFilter := opts.NewListOpts(nil) cmd.Var(&flFilter, []string{"f", "-filter"}, "Provide filter values. Valid filters:\nexited= - containers with exit code of ") if err := cmd.Parse(args); err != nil { diff --git a/docker/flags.go b/docker/flags.go index 6740db5ceb..533f48aa9e 100644 --- a/docker/flags.go +++ b/docker/flags.go @@ -22,7 +22,7 @@ func init() { var ( flVersion = flag.Bool([]string{"v", "-version"}, false, "Print version information and quit") flDaemon = flag.Bool([]string{"d", "-daemon"}, false, "Enable daemon mode") - flGraphOpts opts.ListOpts + flGraphOpts = opts.NewListOpts(nil) flDebug = flag.Bool([]string{"D", "-debug"}, false, "Enable debug mode") flAutoRestart = flag.Bool([]string{"r", "-restart"}, true, "Restart previously running containers") bridgeName = flag.String([]string{"b", "-bridge"}, "", "Attach containers to a pre-existing network bridge\nuse 'none' to disable container networking") diff --git a/opts/opts.go b/opts/opts.go index bfee2ad217..65806f3698 100644 --- a/opts/opts.go +++ b/opts/opts.go @@ -8,23 +8,51 @@ import ( "regexp" "strings" + "github.com/docker/docker/api" + flag "github.com/docker/docker/pkg/mflag" "github.com/docker/docker/pkg/parsers" ) +func ListVar(values *[]string, names []string, usage string) { + flag.Var(newListOptsRef(values, nil), names, usage) +} + +func HostListVar(values *[]string, names []string, usage string) { + flag.Var(newListOptsRef(values, api.ValidateHost), names, usage) +} + +func IPListVar(values *[]string, names []string, usage string) { + flag.Var(newListOptsRef(values, ValidateIPAddress), names, usage) +} + +func DnsSearchListVar(values *[]string, names []string, usage string) { + flag.Var(newListOptsRef(values, ValidateDnsSearch), names, usage) +} + +func IPVar(value *net.IP, names []string, defaultValue, usage string) { + flag.Var(NewIpOpt(value, defaultValue), names, usage) +} + // ListOpts type type ListOpts struct { - values []string + values *[]string validator ValidatorFctType } func NewListOpts(validator ValidatorFctType) ListOpts { - return ListOpts{ + var values []string + return *newListOptsRef(&values, validator) +} + +func newListOptsRef(values *[]string, validator ValidatorFctType) *ListOpts { + return &ListOpts{ + values: values, validator: validator, } } func (opts *ListOpts) String() string { - return fmt.Sprintf("%v", []string(opts.values)) + return fmt.Sprintf("%v", []string((*opts.values))) } // Set validates if needed the input value and add it to the @@ -37,15 +65,15 @@ func (opts *ListOpts) Set(value string) error { } value = v } - opts.values = append(opts.values, value) + (*opts.values) = append((*opts.values), value) return nil } // Delete remove the given element from the slice. func (opts *ListOpts) Delete(key string) { - for i, k := range opts.values { + for i, k := range *opts.values { if k == key { - opts.values = append(opts.values[:i], opts.values[i+1:]...) + (*opts.values) = append((*opts.values)[:i], (*opts.values)[i+1:]...) return } } @@ -56,7 +84,7 @@ func (opts *ListOpts) Delete(key string) { // FIXME: can we remove this? func (opts *ListOpts) GetMap() map[string]struct{} { ret := make(map[string]struct{}) - for _, k := range opts.values { + for _, k := range *opts.values { ret[k] = struct{}{} } return ret @@ -65,12 +93,12 @@ func (opts *ListOpts) GetMap() map[string]struct{} { // GetAll returns the values' slice. // FIXME: Can we remove this? func (opts *ListOpts) GetAll() []string { - return opts.values + return (*opts.values) } // Get checks the existence of the given key. func (opts *ListOpts) Get(key string) bool { - for _, k := range opts.values { + for _, k := range *opts.values { if k == key { return true } @@ -80,7 +108,7 @@ func (opts *ListOpts) Get(key string) bool { // Len returns the amount of element in the slice. func (opts *ListOpts) Len() int { - return len(opts.values) + return len((*opts.values)) } // Validators diff --git a/opts/opts_test.go b/opts/opts_test.go index 9494e27a75..09b5aa780b 100644 --- a/opts/opts_test.go +++ b/opts/opts_test.go @@ -27,6 +27,12 @@ func TestValidateIPAddress(t *testing.T) { } +func TestListOpts(t *testing.T) { + o := NewListOpts(nil) + o.Set("foo") + o.String() +} + func TestValidateDnsSearch(t *testing.T) { valid := []string{ `.`, diff --git a/runconfig/parse.go b/runconfig/parse.go index 741c7469ca..96c36dd394 100644 --- a/runconfig/parse.go +++ b/runconfig/parse.go @@ -45,15 +45,15 @@ func parseRun(cmd *flag.FlagSet, args []string, sysInfo *sysinfo.SysInfo) (*Conf flEnv = opts.NewListOpts(opts.ValidateEnv) flDevices = opts.NewListOpts(opts.ValidatePath) - flPublish opts.ListOpts - flExpose opts.ListOpts + flPublish = opts.NewListOpts(nil) + flExpose = opts.NewListOpts(nil) flDns = opts.NewListOpts(opts.ValidateIPAddress) flDnsSearch = opts.NewListOpts(opts.ValidateDnsSearch) - flVolumesFrom opts.ListOpts - flLxcOpts opts.ListOpts - flEnvFile opts.ListOpts - flCapAdd opts.ListOpts - flCapDrop opts.ListOpts + flVolumesFrom = opts.NewListOpts(nil) + flLxcOpts = opts.NewListOpts(nil) + flEnvFile = opts.NewListOpts(nil) + flCapAdd = opts.NewListOpts(nil) + flCapDrop = opts.NewListOpts(nil) flAutoRemove = cmd.Bool([]string{"#rm", "-rm"}, false, "Automatically remove the container when it exits (incompatible with -d)") flDetach = cmd.Bool([]string{"d", "-detach"}, false, "Detached mode: run container in the background and print new container ID") From 353b7c8ec77b30fa83dac5ec0778193f6de8b437 Mon Sep 17 00:00:00 2001 From: Solomon Hykes Date: Sun, 10 Aug 2014 01:18:32 +0000 Subject: [PATCH 4/8] Parse daemon configuration in daemon.Config.InstallFlags instead of main Signed-off-by: Solomon Hykes --- daemon/config.go | 32 ++++++++++++++++++++-- daemon/daemon.go | 8 ++++++ docker/daemon.go | 56 ++++++++++++++------------------------- docker/docker.go | 10 +++---- docker/flags.go | 38 +++++--------------------- integration/utils_test.go | 6 ----- 6 files changed, 70 insertions(+), 80 deletions(-) diff --git a/daemon/config.go b/daemon/config.go index 0f269da869..9de5f3e185 100644 --- a/daemon/config.go +++ b/daemon/config.go @@ -1,8 +1,11 @@ package daemon import ( - "github.com/docker/docker/daemon/networkdriver" "net" + + "github.com/docker/docker/daemon/networkdriver" + "github.com/docker/docker/opts" + flag "github.com/docker/docker/pkg/mflag" ) const ( @@ -11,7 +14,7 @@ const ( ) // Config define the configuration of a docker daemon -// These are the configuration settings that you pass +// These are the configuration settings that you pass // to the docker daemon when you launch it with say: `docker -d -e lxc` // FIXME: separate runtime configuration from http api configuration type Config struct { @@ -36,6 +39,31 @@ type Config struct { Sockets []string } +// InstallFlags adds command-line options to the top-level flag parser for +// the current process. +// Subsequent calls to `flag.Parse` will populate config with values parsed +// from the command-line. +func (config *Config) InstallFlags() { + flag.StringVar(&config.Pidfile, []string{"p", "-pidfile"}, "/var/run/docker.pid", "Path to use for daemon PID file") + flag.StringVar(&config.Root, []string{"g", "-graph"}, "/var/lib/docker", "Path to use as the root of the Docker runtime") + flag.BoolVar(&config.AutoRestart, []string{"r", "-restart"}, true, "Restart previously running containers") + flag.BoolVar(&config.EnableIptables, []string{"#iptables", "-iptables"}, true, "Enable Docker's addition of iptables rules") + flag.BoolVar(&config.EnableIpForward, []string{"#ip-forward", "-ip-forward"}, true, "Enable net.ipv4.ip_forward") + flag.StringVar(&config.BridgeIP, []string{"#bip", "-bip"}, "", "Use this CIDR notation address for the network bridge's IP, not compatible with -b") + flag.StringVar(&config.BridgeIface, []string{"b", "-bridge"}, "", "Attach containers to a pre-existing network bridge\nuse 'none' to disable container networking") + flag.BoolVar(&config.InterContainerCommunication, []string{"#icc", "-icc"}, true, "Enable inter-container communication") + flag.StringVar(&config.GraphDriver, []string{"s", "-storage-driver"}, "", "Force the Docker runtime to use a specific storage driver") + flag.StringVar(&config.ExecDriver, []string{"e", "-exec-driver"}, "native", "Force the Docker runtime to use a specific exec driver") + flag.BoolVar(&config.EnableSelinuxSupport, []string{"-selinux-enabled"}, false, "Enable selinux support. SELinux does not presently support the BTRFS storage driver") + flag.IntVar(&config.Mtu, []string{"#mtu", "-mtu"}, 0, "Set the containers network MTU\nif no value is provided: default to the default route MTU or 1500 if no default route is available") + opts.IPVar(&config.DefaultIp, []string{"#ip", "-ip"}, "0.0.0.0", "Default IP address to use when binding container ports") + opts.ListVar(&config.GraphOptions, []string{"-storage-opt"}, "Set storage driver options") + // FIXME: why the inconsistency between "hosts" and "sockets"? + opts.HostListVar(&config.Sockets, []string{"H", "-host"}, "The socket(s) to bind to in daemon mode\nspecified using one or more tcp://host:port, unix:///path/to/socket, fd://* or fd://socketfd.") + opts.IPListVar(&config.Dns, []string{"#dns", "-dns"}, "Force Docker to use specific DNS servers") + opts.DnsSearchListVar(&config.DnsSearch, []string{"-dns-search"}, "Force Docker to use specific DNS search domains") +} + func GetDefaultNetworkMtu() int { if iface, err := networkdriver.GetDefaultRouteIface(); err == nil { return iface.MTU diff --git a/daemon/daemon.go b/daemon/daemon.go index 0a2ad4c315..7328e8fb26 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -672,6 +672,14 @@ func NewDaemon(config *Config, eng *engine.Engine) (*Daemon, error) { } func NewDaemonFromDirectory(config *Config, eng *engine.Engine) (*Daemon, error) { + // Apply configuration defaults + if config.Mtu == 0 { + // FIXME: GetDefaultNetwork Mtu doesn't need to be public anymore + config.Mtu = GetDefaultNetworkMtu() + } + // FIXME: DisableNetworkBidge doesn't need to be public anymore + config.DisableNetwork = config.BridgeIface == DisableNetworkBridge + // Claim the pidfile first, to avoid any and all unexpected race conditions. // Some of the init doesn't need a pidfile lock - but let's not try to be smart. if config.Pidfile != "" { diff --git a/docker/daemon.go b/docker/daemon.go index 2866f6990c..6bff0109d2 100644 --- a/docker/daemon.go +++ b/docker/daemon.go @@ -4,7 +4,6 @@ package main import ( "log" - "net" "github.com/docker/docker/builtins" "github.com/docker/docker/daemon" @@ -18,22 +17,32 @@ import ( const CanDaemon = true +var ( + daemonCfg = &daemon.Config{} +) + +func init() { + daemonCfg.InstallFlags() +} + func mainDaemon() { if flag.NArg() != 0 { flag.Usage() return } - if *bridgeName != "" && *bridgeIp != "" { + // FIXME: validate daemon.Config values in a method of daemon.Config + if daemonCfg.BridgeIface != "" && daemonCfg.BridgeIP != "" { log.Fatal("You specified -b & --bip, mutually exclusive options. Please specify only one.") } - if !*flEnableIptables && !*flInterContainerComm { + if !daemonCfg.EnableIptables && !daemonCfg.InterContainerCommunication { log.Fatal("You specified --iptables=false with --icc=false. ICC uses iptables to function. Please set --icc or --iptables to true.") } - if net.ParseIP(*flDefaultIp) == nil { - log.Fatalf("Specified --ip=%s is not in correct format \"0.0.0.0\".", *flDefaultIp) + // FIXME: move this validation to opts.IpOpt + if daemonCfg.DefaultIp == nil { + log.Fatalf("Specified --ip is not in correct format \"0.0.0.0\".") } eng := engine.New() @@ -47,34 +56,7 @@ func mainDaemon() { // the http api so that connections don't fail while the daemon // is booting go func() { - // FIXME: daemon config and CLI flag parsing should be directly integrated - cfg := &daemon.Config{ - Pidfile: *pidfile, - Root: *flRoot, - AutoRestart: *flAutoRestart, - EnableIptables: *flEnableIptables, - EnableIpForward: *flEnableIpForward, - BridgeIP: *bridgeIp, - BridgeIface: *bridgeName, - DefaultIp: net.ParseIP(*flDefaultIp), - InterContainerCommunication: *flInterContainerComm, - GraphDriver: *flGraphDriver, - ExecDriver: *flExecDriver, - EnableSelinuxSupport: *flSelinuxEnabled, - GraphOptions: flGraphOpts.GetAll(), - Dns: flDns.GetAll(), - DnsSearch: flDnsSearch.GetAll(), - Mtu: *flMtu, - Sockets: flHosts.GetAll(), - } - // FIXME this should be initialized in NewDaemon or somewhere in daemon. - // Currently it is copy-pasted in `integration` to create test daemons that work. - if cfg.Mtu == 0 { - cfg.Mtu = daemon.GetDefaultNetworkMtu() - } - cfg.DisableNetwork = cfg.BridgeIface == daemon.DisableNetworkBridge - - d, err := daemon.NewDaemon(cfg, eng) + d, err := daemon.NewDaemon(daemonCfg, eng) if err != nil { log.Fatal(err) } @@ -91,11 +73,13 @@ func mainDaemon() { log.Printf("docker daemon: %s %s; execdriver: %s; graphdriver: %s", dockerversion.VERSION, dockerversion.GITCOMMIT, - *flExecDriver, - *flGraphDriver) + daemonCfg.ExecDriver, + daemonCfg.GraphDriver, + ) // Serve api - job := eng.Job("serveapi", flHosts.GetAll()...) + // FIXME: 'Sockets' should not be part of daemon.Config + job := eng.Job("serveapi", daemonCfg.Sockets...) job.SetenvBool("Logging", true) job.SetenvBool("EnableCors", *flEnableCors) job.Setenv("Version", dockerversion.VERSION) diff --git a/docker/docker.go b/docker/docker.go index 49053bf87b..2cd8165733 100644 --- a/docker/docker.go +++ b/docker/docker.go @@ -27,8 +27,8 @@ func main() { if reexec.Init() { return } - flag.Parse() + // FIXME: validate daemon flags here if *flVersion { showVersion() @@ -38,7 +38,7 @@ func main() { os.Setenv("DEBUG", "1") } - if flHosts.Len() == 0 { + if len(daemonCfg.Sockets) == 0 { defaultHost := os.Getenv("DOCKER_HOST") if defaultHost == "" || *flDaemon { // If we do not have a host, default to unix socket @@ -47,7 +47,7 @@ func main() { if _, err := api.ValidateHost(defaultHost); err != nil { log.Fatal(err) } - flHosts.Set(defaultHost) + daemonCfg.Sockets = append(daemonCfg.Sockets, defaultHost) } if *flDaemon { @@ -55,10 +55,10 @@ func main() { return } - if flHosts.Len() > 1 { + if len(daemonCfg.Sockets) > 1 { log.Fatal("Please specify only one -H") } - protoAddrParts := strings.SplitN(flHosts.GetAll()[0], "://", 2) + protoAddrParts := strings.SplitN(daemonCfg.Sockets[0], "://", 2) var ( cli *client.DockerCli diff --git a/docker/flags.go b/docker/flags.go index 533f48aa9e..cb22751042 100644 --- a/docker/flags.go +++ b/docker/flags.go @@ -4,8 +4,6 @@ import ( "os" "path/filepath" - "github.com/docker/docker/api" - "github.com/docker/docker/opts" flag "github.com/docker/docker/pkg/mflag" ) @@ -20,30 +18,13 @@ func init() { } var ( - flVersion = flag.Bool([]string{"v", "-version"}, false, "Print version information and quit") - flDaemon = flag.Bool([]string{"d", "-daemon"}, false, "Enable daemon mode") - flGraphOpts = opts.NewListOpts(nil) - flDebug = flag.Bool([]string{"D", "-debug"}, false, "Enable debug mode") - flAutoRestart = flag.Bool([]string{"r", "-restart"}, true, "Restart previously running containers") - bridgeName = flag.String([]string{"b", "-bridge"}, "", "Attach containers to a pre-existing network bridge\nuse 'none' to disable container networking") - bridgeIp = flag.String([]string{"#bip", "-bip"}, "", "Use this CIDR notation address for the network bridge's IP, not compatible with -b") - pidfile = flag.String([]string{"p", "-pidfile"}, "/var/run/docker.pid", "Path to use for daemon PID file") - flRoot = flag.String([]string{"g", "-graph"}, "/var/lib/docker", "Path to use as the root of the Docker runtime") - flSocketGroup = flag.String([]string{"G", "-group"}, "docker", "Group to assign the unix socket specified by -H when running in daemon mode\nuse '' (the empty string) to disable setting of a group") - flEnableCors = flag.Bool([]string{"#api-enable-cors", "-api-enable-cors"}, false, "Enable CORS headers in the remote API") - flDns = opts.NewListOpts(opts.ValidateIPAddress) - flDnsSearch = opts.NewListOpts(opts.ValidateDnsSearch) - flEnableIptables = flag.Bool([]string{"#iptables", "-iptables"}, true, "Enable Docker's addition of iptables rules") - flEnableIpForward = flag.Bool([]string{"#ip-forward", "-ip-forward"}, true, "Enable net.ipv4.ip_forward") - flDefaultIp = flag.String([]string{"#ip", "-ip"}, "0.0.0.0", "Default IP address to use when binding container ports") - flInterContainerComm = flag.Bool([]string{"#icc", "-icc"}, true, "Enable inter-container communication") - flGraphDriver = flag.String([]string{"s", "-storage-driver"}, "", "Force the Docker runtime to use a specific storage driver") - flExecDriver = flag.String([]string{"e", "-exec-driver"}, "native", "Force the Docker runtime to use a specific exec driver") - flHosts = opts.NewListOpts(api.ValidateHost) - flMtu = flag.Int([]string{"#mtu", "-mtu"}, 0, "Set the containers network MTU\nif no value is provided: default to the default route MTU or 1500 if no default route is available") - flTls = flag.Bool([]string{"-tls"}, false, "Use TLS; implied by tls-verify flags") - flTlsVerify = flag.Bool([]string{"-tlsverify"}, false, "Use TLS and verify the remote (daemon: verify client, client: verify daemon)") - flSelinuxEnabled = flag.Bool([]string{"-selinux-enabled"}, false, "Enable selinux support. SELinux does not presently support the BTRFS storage driver") + 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") + flSocketGroup = flag.String([]string{"G", "-group"}, "docker", "Group to assign the unix socket specified by -H when running in daemon mode\nuse '' (the empty string) to disable setting of a group") + flEnableCors = flag.Bool([]string{"#api-enable-cors", "-api-enable-cors"}, false, "Enable CORS headers in the remote API") + flTls = flag.Bool([]string{"-tls"}, false, "Use TLS; implied by tls-verify flags") + flTlsVerify = flag.Bool([]string{"-tlsverify"}, false, "Use TLS and verify the remote (daemon: verify client, client: verify daemon)") // these are initialized in init() below since their default values depend on dockerCertPath which isn't fully initialized until init() runs flCa *string @@ -55,9 +36,4 @@ func init() { flCa = flag.String([]string{"-tlscacert"}, filepath.Join(dockerCertPath, defaultCaFile), "Trust only remotes providing a certificate signed by the CA given here") flCert = flag.String([]string{"-tlscert"}, filepath.Join(dockerCertPath, defaultCertFile), "Path to TLS certificate file") flKey = flag.String([]string{"-tlskey"}, filepath.Join(dockerCertPath, defaultKeyFile), "Path to TLS key file") - - flag.Var(&flDns, []string{"#dns", "-dns"}, "Force Docker to use specific DNS servers") - flag.Var(&flDnsSearch, []string{"-dns-search"}, "Force Docker to use specific DNS search domains") - flag.Var(&flHosts, []string{"H", "-host"}, "The socket(s) to bind to in daemon mode\nspecified using one or more tcp://host:port, unix:///path/to/socket, fd://* or fd://socketfd.") - flag.Var(&flGraphOpts, []string{"-storage-opt"}, "Set storage driver options") } diff --git a/integration/utils_test.go b/integration/utils_test.go index a7f3f999e2..b070288533 100644 --- a/integration/utils_test.go +++ b/integration/utils_test.go @@ -186,12 +186,6 @@ func newTestEngine(t utils.Fataler, autorestart bool, root string) *engine.Engin // otherwise NewDaemon will fail because of conflicting settings. InterContainerCommunication: true, } - // FIXME: this should be initialized in NewDaemon - // Currently it is copy-pasted from daemonMain() - if cfg.Mtu == 0 { - cfg.Mtu = daemon.GetDefaultNetworkMtu() - } - cfg.DisableNetwork = cfg.BridgeIface == daemon.DisableNetworkBridge d, err := daemon.NewDaemon(cfg, eng) if err != nil { t.Fatal(err) From ca11b77471bd3a99b4dbc44b716675ba8174306c Mon Sep 17 00:00:00 2001 From: Solomon Hykes Date: Sun, 10 Aug 2014 03:50:46 +0000 Subject: [PATCH 5/8] opts.IPVal returns an error on incorrect input Signed-off-by: Solomon Hykes --- docker/daemon.go | 6 ------ opts/ip.go | 7 +++++-- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/docker/daemon.go b/docker/daemon.go index 6bff0109d2..089eae5464 100644 --- a/docker/daemon.go +++ b/docker/daemon.go @@ -39,12 +39,6 @@ func mainDaemon() { if !daemonCfg.EnableIptables && !daemonCfg.InterContainerCommunication { log.Fatal("You specified --iptables=false with --icc=false. ICC uses iptables to function. Please set --icc or --iptables to true.") } - - // FIXME: move this validation to opts.IpOpt - if daemonCfg.DefaultIp == nil { - log.Fatalf("Specified --ip is not in correct format \"0.0.0.0\".") - } - eng := engine.New() signal.Trap(eng.Shutdown) // Load builtins diff --git a/opts/ip.go b/opts/ip.go index 3610b14538..f0c29750bc 100644 --- a/opts/ip.go +++ b/opts/ip.go @@ -1,6 +1,7 @@ package opts import ( + "fmt" "net" ) @@ -17,8 +18,10 @@ func NewIpOpt(ref *net.IP, defaultVal string) *IpOpt { } func (o *IpOpt) Set(val string) error { - // FIXME: return a parse error if the value is not a valid IP? - // We are not changing this now to preserve behavior while refactoring. + ip := net.ParseIP(val) + if ip == nil { + return fmt.Errorf("incorrect IP format") + } (*o.IP) = net.ParseIP(val) return nil } From 1eba59eb249b14a0499a52495be2c27b5afc4749 Mon Sep 17 00:00:00 2001 From: Solomon Hykes Date: Sun, 10 Aug 2014 03:58:19 +0000 Subject: [PATCH 6/8] Check for conflicting daemon config options in NewDaemon Signed-off-by: Solomon Hykes --- daemon/daemon.go | 7 +++++++ docker/daemon.go | 9 --------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/daemon/daemon.go b/daemon/daemon.go index 7328e8fb26..f68197b2f6 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -677,6 +677,13 @@ func NewDaemonFromDirectory(config *Config, eng *engine.Engine) (*Daemon, error) // FIXME: GetDefaultNetwork Mtu doesn't need to be public anymore config.Mtu = GetDefaultNetworkMtu() } + // Check for mutually incompatible config options + if config.BridgeIface != "" && config.BridgeIP != "" { + return nil, fmt.Errorf("You specified -b & --bip, mutually exclusive options. Please specify only one.") + } + if !config.EnableIptables && !config.InterContainerCommunication { + return nil, fmt.Errorf("You specified --iptables=false with --icc=false. ICC uses iptables to function. Please set --icc or --iptables to true.") + } // FIXME: DisableNetworkBidge doesn't need to be public anymore config.DisableNetwork = config.BridgeIface == DisableNetworkBridge diff --git a/docker/daemon.go b/docker/daemon.go index 089eae5464..948412ea86 100644 --- a/docker/daemon.go +++ b/docker/daemon.go @@ -30,15 +30,6 @@ func mainDaemon() { flag.Usage() return } - - // FIXME: validate daemon.Config values in a method of daemon.Config - if daemonCfg.BridgeIface != "" && daemonCfg.BridgeIP != "" { - log.Fatal("You specified -b & --bip, mutually exclusive options. Please specify only one.") - } - - if !daemonCfg.EnableIptables && !daemonCfg.InterContainerCommunication { - log.Fatal("You specified --iptables=false with --icc=false. ICC uses iptables to function. Please set --icc or --iptables to true.") - } eng := engine.New() signal.Trap(eng.Shutdown) // Load builtins From 1d10c55aec891df609d36c90ee6c30adb24c16c4 Mon Sep 17 00:00:00 2001 From: Solomon Hykes Date: Mon, 11 Aug 2014 22:30:01 +0000 Subject: [PATCH 7/8] Move remote API config out of daemon/ Signed-off-by: Solomon Hykes --- api/client/commands.go | 3 --- daemon/config.go | 2 -- daemon/daemon.go | 2 -- daemon/info.go | 1 - docker/daemon.go | 3 +-- docker/docker.go | 8 ++++---- docker/flags.go | 9 ++++++--- docs/sources/reference/api/docker_remote_api_v1.13.md | 1 - docs/sources/reference/api/docker_remote_api_v1.14.md | 1 - docs/sources/reference/commandline/cli.md | 1 - 10 files changed, 11 insertions(+), 20 deletions(-) diff --git a/api/client/commands.go b/api/client/commands.go index e4c1808f1c..99856ee5eb 100644 --- a/api/client/commands.go +++ b/api/client/commands.go @@ -505,9 +505,6 @@ func (cli *DockerCli) CmdInfo(args ...string) error { if initPath := remoteInfo.Get("InitPath"); initPath != "" { fmt.Fprintf(cli.out, "Init Path: %s\n", initPath) } - if len(remoteInfo.GetList("Sockets")) != 0 { - fmt.Fprintf(cli.out, "Sockets: %v\n", remoteInfo.GetList("Sockets")) - } } if len(remoteInfo.GetList("IndexServerAddress")) != 0 { diff --git a/daemon/config.go b/daemon/config.go index 9de5f3e185..5d0ea6ac12 100644 --- a/daemon/config.go +++ b/daemon/config.go @@ -36,7 +36,6 @@ type Config struct { DisableNetwork bool EnableSelinuxSupport bool Context map[string][]string - Sockets []string } // InstallFlags adds command-line options to the top-level flag parser for @@ -59,7 +58,6 @@ func (config *Config) InstallFlags() { opts.IPVar(&config.DefaultIp, []string{"#ip", "-ip"}, "0.0.0.0", "Default IP address to use when binding container ports") opts.ListVar(&config.GraphOptions, []string{"-storage-opt"}, "Set storage driver options") // FIXME: why the inconsistency between "hosts" and "sockets"? - opts.HostListVar(&config.Sockets, []string{"H", "-host"}, "The socket(s) to bind to in daemon mode\nspecified using one or more tcp://host:port, unix:///path/to/socket, fd://* or fd://socketfd.") opts.IPListVar(&config.Dns, []string{"#dns", "-dns"}, "Force Docker to use specific DNS servers") opts.DnsSearchListVar(&config.DnsSearch, []string{"-dns-search"}, "Force Docker to use specific DNS search domains") } diff --git a/daemon/daemon.go b/daemon/daemon.go index f68197b2f6..540ee7d985 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -98,7 +98,6 @@ type Daemon struct { containerGraph *graphdb.Database driver graphdriver.Driver execDriver execdriver.Driver - Sockets []string } // Install installs daemon capabilities to eng. @@ -851,7 +850,6 @@ func NewDaemonFromDirectory(config *Config, eng *engine.Engine) (*Daemon, error) sysInitPath: sysInitPath, execDriver: ed, eng: eng, - Sockets: config.Sockets, } if err := daemon.checkLocaldns(); err != nil { return nil, err diff --git a/daemon/info.go b/daemon/info.go index 215d82acdc..d028a8341f 100644 --- a/daemon/info.go +++ b/daemon/info.go @@ -66,7 +66,6 @@ func (daemon *Daemon) CmdInfo(job *engine.Job) engine.Status { v.Set("IndexServerAddress", registry.IndexServerAddress()) v.Set("InitSha1", dockerversion.INITSHA1) v.Set("InitPath", initPath) - v.SetList("Sockets", daemon.Sockets) if _, err := v.WriteTo(job.Stdout); err != nil { return job.Error(err) } diff --git a/docker/daemon.go b/docker/daemon.go index 948412ea86..dc9d56d1d9 100644 --- a/docker/daemon.go +++ b/docker/daemon.go @@ -63,8 +63,7 @@ func mainDaemon() { ) // Serve api - // FIXME: 'Sockets' should not be part of daemon.Config - job := eng.Job("serveapi", daemonCfg.Sockets...) + job := eng.Job("serveapi", flHosts...) job.SetenvBool("Logging", true) job.SetenvBool("EnableCors", *flEnableCors) job.Setenv("Version", dockerversion.VERSION) diff --git a/docker/docker.go b/docker/docker.go index 2cd8165733..f2b4ca90b1 100644 --- a/docker/docker.go +++ b/docker/docker.go @@ -38,7 +38,7 @@ func main() { os.Setenv("DEBUG", "1") } - if len(daemonCfg.Sockets) == 0 { + if len(flHosts) == 0 { defaultHost := os.Getenv("DOCKER_HOST") if defaultHost == "" || *flDaemon { // If we do not have a host, default to unix socket @@ -47,7 +47,7 @@ func main() { if _, err := api.ValidateHost(defaultHost); err != nil { log.Fatal(err) } - daemonCfg.Sockets = append(daemonCfg.Sockets, defaultHost) + flHosts = append(flHosts, defaultHost) } if *flDaemon { @@ -55,10 +55,10 @@ func main() { return } - if len(daemonCfg.Sockets) > 1 { + if len(flHosts) > 1 { log.Fatal("Please specify only one -H") } - protoAddrParts := strings.SplitN(daemonCfg.Sockets[0], "://", 2) + protoAddrParts := strings.SplitN(flHosts[0], "://", 2) var ( cli *client.DockerCli diff --git a/docker/flags.go b/docker/flags.go index cb22751042..baae40eafc 100644 --- a/docker/flags.go +++ b/docker/flags.go @@ -4,6 +4,7 @@ import ( "os" "path/filepath" + "github.com/docker/docker/opts" flag "github.com/docker/docker/pkg/mflag" ) @@ -27,13 +28,15 @@ var ( flTlsVerify = flag.Bool([]string{"-tlsverify"}, false, "Use TLS and verify the remote (daemon: verify client, client: verify daemon)") // these are initialized in init() below since their default values depend on dockerCertPath which isn't fully initialized until init() runs - flCa *string - flCert *string - flKey *string + flCa *string + flCert *string + flKey *string + flHosts []string ) func init() { flCa = flag.String([]string{"-tlscacert"}, filepath.Join(dockerCertPath, defaultCaFile), "Trust only remotes providing a certificate signed by the CA given here") flCert = flag.String([]string{"-tlscert"}, filepath.Join(dockerCertPath, defaultCertFile), "Path to TLS certificate file") flKey = flag.String([]string{"-tlskey"}, filepath.Join(dockerCertPath, defaultKeyFile), "Path to TLS key file") + opts.HostListVar(&flHosts, []string{"H", "-host"}, "The socket(s) to bind to in daemon mode\nspecified using one or more tcp://host:port, unix:///path/to/socket, fd://* or fd://socketfd.") } diff --git a/docs/sources/reference/api/docker_remote_api_v1.13.md b/docs/sources/reference/api/docker_remote_api_v1.13.md index cf21aefb00..d782391476 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.13.md +++ b/docs/sources/reference/api/docker_remote_api_v1.13.md @@ -1170,7 +1170,6 @@ Display system-wide information "NGoroutines":21, "NEventsListener":0, "InitPath":"/usr/bin/docker", - "Sockets":["unix:///var/run/docker.sock"], "IndexServerAddress":["https://index.docker.io/v1/"], "MemoryLimit":true, "SwapLimit":false, diff --git a/docs/sources/reference/api/docker_remote_api_v1.14.md b/docs/sources/reference/api/docker_remote_api_v1.14.md index e411c8c6ef..9a9c36e54b 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.14.md +++ b/docs/sources/reference/api/docker_remote_api_v1.14.md @@ -1174,7 +1174,6 @@ Display system-wide information "NGoroutines":21, "NEventsListener":0, "InitPath":"/usr/bin/docker", - "Sockets":["unix:///var/run/docker.sock"], "IndexServerAddress":["https://index.docker.io/v1/"], "MemoryLimit":true, "SwapLimit":false, diff --git a/docs/sources/reference/commandline/cli.md b/docs/sources/reference/commandline/cli.md index 311fc849e9..5e6107cfaa 100644 --- a/docs/sources/reference/commandline/cli.md +++ b/docs/sources/reference/commandline/cli.md @@ -616,7 +616,6 @@ For example: Goroutines: 9 EventsListeners: 0 Init Path: /usr/bin/docker - Sockets: [unix:///var/run/docker.sock] Username: svendowideit Registry: [https://index.docker.io/v1/] From a30fd7a962f8486df0d0dbd3334c7621d22c1aec Mon Sep 17 00:00:00 2001 From: Solomon Hykes Date: Wed, 13 Aug 2014 06:45:40 +0000 Subject: [PATCH 8/8] Fix inconsistency in IP address parsing errors Signed-off-by: Solomon Hykes --- opts/ip.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opts/ip.go b/opts/ip.go index f0c29750bc..f8a493e68a 100644 --- a/opts/ip.go +++ b/opts/ip.go @@ -20,7 +20,7 @@ func NewIpOpt(ref *net.IP, defaultVal string) *IpOpt { func (o *IpOpt) Set(val string) error { ip := net.ParseIP(val) if ip == nil { - return fmt.Errorf("incorrect IP format") + return fmt.Errorf("%s is not an ip address", val) } (*o.IP) = net.ParseIP(val) return nil