From f7b3e879fc3047ed93ac6b43cd9bf47a25f3d0fc Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Thu, 20 Mar 2014 22:58:02 +0000 Subject: [PATCH] Add initial plugin flag to pass lxc and native driver options Docker-DCO-1.1-Signed-off-by: Michael Crosby (github: crosbymichael) --- runconfig/hostconfig.go | 2 ++ runconfig/parse.go | 18 ++++++++++++ runtime/container.go | 8 ++++-- runtime/execdriver/driver.go | 28 +++++++++---------- runtime/execdriver/lxc/lxc_template.go | 4 +-- .../execdriver/lxc/lxc_template_unit_test.go | 3 +- runtime/execdriver/native/driver.go | 6 ++-- 7 files changed, 46 insertions(+), 23 deletions(-) diff --git a/runconfig/hostconfig.go b/runconfig/hostconfig.go index 6c8618ee81..8ee2288b4b 100644 --- a/runconfig/hostconfig.go +++ b/runconfig/hostconfig.go @@ -13,6 +13,7 @@ type HostConfig struct { PortBindings nat.PortMap Links []string PublishAllPorts bool + PluginOptions map[string][]string } type KeyValuePair struct { @@ -28,6 +29,7 @@ func ContainerHostConfigFromJob(job *engine.Job) *HostConfig { } job.GetenvJson("LxcConf", &hostConfig.LxcConf) job.GetenvJson("PortBindings", &hostConfig.PortBindings) + job.GetenvJson("PluginOptions", &hostConfig.PluginOptions) if Binds := job.GetenvList("Binds"); Binds != nil { hostConfig.Binds = Binds } diff --git a/runconfig/parse.go b/runconfig/parse.go index cc33188ad5..afcaec304f 100644 --- a/runconfig/parse.go +++ b/runconfig/parse.go @@ -45,6 +45,7 @@ func parseRun(cmd *flag.FlagSet, args []string, sysInfo *sysinfo.SysInfo) (*Conf flDnsSearch = opts.NewListOpts(opts.ValidateDomain) flVolumesFrom opts.ListOpts flLxcOpts opts.ListOpts + flPluginOpts opts.ListOpts 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, print new container id") @@ -77,6 +78,7 @@ func parseRun(cmd *flag.FlagSet, args []string, sysInfo *sysinfo.SysInfo) (*Conf cmd.Var(&flDnsSearch, []string{"-dns-search"}, "Set custom dns search domains") cmd.Var(&flVolumesFrom, []string{"#volumes-from", "-volumes-from"}, "Mount volumes from the specified container(s)") cmd.Var(&flLxcOpts, []string{"#lxc-conf", "-lxc-conf"}, "Add custom lxc options --lxc-conf=\"lxc.cgroup.cpuset.cpus = 0,1\"") + cmd.Var(&flPluginOpts, []string{"-plugin"}, "Add custom plugin options") if err := cmd.Parse(args); err != nil { return nil, nil, cmd, err @@ -206,6 +208,8 @@ func parseRun(cmd *flag.FlagSet, args []string, sysInfo *sysinfo.SysInfo) (*Conf WorkingDir: *flWorkingDir, } + pluginOptions := parsePluginOpts(flPluginOpts) + hostConfig := &HostConfig{ Binds: binds, ContainerIDFile: *flContainerIDFile, @@ -214,6 +218,7 @@ func parseRun(cmd *flag.FlagSet, args []string, sysInfo *sysinfo.SysInfo) (*Conf PortBindings: portBindings, Links: flLinks.GetAll(), PublishAllPorts: *flPublishAll, + PluginOptions: pluginOptions, } if sysInfo != nil && flMemory > 0 && !sysInfo.SwapLimit { @@ -247,3 +252,16 @@ func parseLxcOpt(opt string) (string, string, error) { } return strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1]), nil } + +func parsePluginOpts(opts opts.ListOpts) map[string][]string { + out := make(map[string][]string, len(opts.GetAll())) + for _, o := range opts.GetAll() { + parts := strings.SplitN(o, " ", 2) + values, exists := out[parts[0]] + if !exists { + values = []string{} + } + out[parts[0]] = append(values, parts[1]) + } + return out +} diff --git a/runtime/container.go b/runtime/container.go index 6194a19c8c..488d905f4b 100644 --- a/runtime/container.go +++ b/runtime/container.go @@ -361,7 +361,7 @@ func (container *Container) Attach(stdin io.ReadCloser, stdinCloser io.Closer, s func populateCommand(c *Container) { var ( en *execdriver.Network - driverConfig []string + driverConfig = c.hostConfig.PluginOptions ) en = &execdriver.Network{ @@ -379,11 +379,15 @@ func populateCommand(c *Container) { } } + // merge in the lxc conf options into the generic config map if lxcConf := c.hostConfig.LxcConf; lxcConf != nil { + lxc := driverConfig["lxc"] for _, pair := range lxcConf { - driverConfig = append(driverConfig, fmt.Sprintf("%s = %s", pair.Key, pair.Value)) + lxc = append(lxc, fmt.Sprintf("%s = %s", pair.Key, pair.Value)) } + driverConfig["lxc"] = lxc } + resources := &execdriver.Resources{ Memory: c.Config.Memory, MemorySwap: c.Config.MemorySwap, diff --git a/runtime/execdriver/driver.go b/runtime/execdriver/driver.go index 23e31ee8d9..2b7c367453 100644 --- a/runtime/execdriver/driver.go +++ b/runtime/execdriver/driver.go @@ -112,20 +112,20 @@ type Mount struct { type Command struct { exec.Cmd `json:"-"` - ID string `json:"id"` - Privileged bool `json:"privileged"` - User string `json:"user"` - Rootfs string `json:"rootfs"` // root fs of the container - InitPath string `json:"initpath"` // dockerinit - Entrypoint string `json:"entrypoint"` - Arguments []string `json:"arguments"` - WorkingDir string `json:"working_dir"` - ConfigPath string `json:"config_path"` // this should be able to be removed when the lxc template is moved into the driver - Tty bool `json:"tty"` - Network *Network `json:"network"` - Config []string `json:"config"` // generic values that specific drivers can consume - Resources *Resources `json:"resources"` - Mounts []Mount `json:"mounts"` + ID string `json:"id"` + Privileged bool `json:"privileged"` + User string `json:"user"` + Rootfs string `json:"rootfs"` // root fs of the container + InitPath string `json:"initpath"` // dockerinit + Entrypoint string `json:"entrypoint"` + Arguments []string `json:"arguments"` + WorkingDir string `json:"working_dir"` + ConfigPath string `json:"config_path"` // this should be able to be removed when the lxc template is moved into the driver + Tty bool `json:"tty"` + Network *Network `json:"network"` + Config map[string][]string `json:"config"` // generic values that specific drivers can consume + Resources *Resources `json:"resources"` + Mounts []Mount `json:"mounts"` Terminal Terminal `json:"-"` // standard or tty terminal Console string `json:"-"` // dev/console path diff --git a/runtime/execdriver/lxc/lxc_template.go b/runtime/execdriver/lxc/lxc_template.go index ce9d90469f..7979e4f284 100644 --- a/runtime/execdriver/lxc/lxc_template.go +++ b/runtime/execdriver/lxc/lxc_template.go @@ -118,8 +118,8 @@ lxc.cgroup.cpu.shares = {{.Resources.CpuShares}} {{end}} {{end}} -{{if .Config}} -{{range $value := .Config}} +{{if .Config.lxc}} +{{range $value := .Config.lxc}} {{$value}} {{end}} {{end}} diff --git a/runtime/execdriver/lxc/lxc_template_unit_test.go b/runtime/execdriver/lxc/lxc_template_unit_test.go index e613adf7a9..74cfd6229c 100644 --- a/runtime/execdriver/lxc/lxc_template_unit_test.go +++ b/runtime/execdriver/lxc/lxc_template_unit_test.go @@ -75,10 +75,11 @@ func TestCustomLxcConfig(t *testing.T) { command := &execdriver.Command{ ID: "1", Privileged: false, - Config: []string{ + Config: map[string][]string{"lxc": { "lxc.utsname = docker", "lxc.cgroup.cpuset.cpus = 0,1", }, + }, Network: &execdriver.Network{ Mtu: 1500, Interface: nil, diff --git a/runtime/execdriver/native/driver.go b/runtime/execdriver/native/driver.go index bf7e8ccdec..0a09d324db 100644 --- a/runtime/execdriver/native/driver.go +++ b/runtime/execdriver/native/driver.go @@ -184,10 +184,8 @@ func (d *driver) removeContainerRoot(id string) error { func (d *driver) validateCommand(c *execdriver.Command) error { // we need to check the Config of the command to make sure that we // do not have any of the lxc-conf variables - for _, conf := range c.Config { - if strings.Contains(conf, "lxc") { - return fmt.Errorf("%s is not supported by the native driver", conf) - } + for _, conf := range c.Config["native"] { + log.Println(conf) } return nil }