| ... | ... |
@@ -13,6 +13,7 @@ type HostConfig struct {
|
| 13 | 13 |
PortBindings nat.PortMap |
| 14 | 14 |
Links []string |
| 15 | 15 |
PublishAllPorts bool |
| 16 |
+ PluginOptions map[string][]string |
|
| 16 | 17 |
} |
| 17 | 18 |
|
| 18 | 19 |
type KeyValuePair struct {
|
| ... | ... |
@@ -28,6 +29,7 @@ func ContainerHostConfigFromJob(job *engine.Job) *HostConfig {
|
| 28 | 28 |
} |
| 29 | 29 |
job.GetenvJson("LxcConf", &hostConfig.LxcConf)
|
| 30 | 30 |
job.GetenvJson("PortBindings", &hostConfig.PortBindings)
|
| 31 |
+ job.GetenvJson("PluginOptions", &hostConfig.PluginOptions)
|
|
| 31 | 32 |
if Binds := job.GetenvList("Binds"); Binds != nil {
|
| 32 | 33 |
hostConfig.Binds = Binds |
| 33 | 34 |
} |
| ... | ... |
@@ -45,6 +45,7 @@ func parseRun(cmd *flag.FlagSet, args []string, sysInfo *sysinfo.SysInfo) (*Conf |
| 45 | 45 |
flDnsSearch = opts.NewListOpts(opts.ValidateDomain) |
| 46 | 46 |
flVolumesFrom opts.ListOpts |
| 47 | 47 |
flLxcOpts opts.ListOpts |
| 48 |
+ flPluginOpts opts.ListOpts |
|
| 48 | 49 |
|
| 49 | 50 |
flAutoRemove = cmd.Bool([]string{"#rm", "-rm"}, false, "Automatically remove the container when it exits (incompatible with -d)")
|
| 50 | 51 |
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 |
| 77 | 77 |
cmd.Var(&flDnsSearch, []string{"-dns-search"}, "Set custom dns search domains")
|
| 78 | 78 |
cmd.Var(&flVolumesFrom, []string{"#volumes-from", "-volumes-from"}, "Mount volumes from the specified container(s)")
|
| 79 | 79 |
cmd.Var(&flLxcOpts, []string{"#lxc-conf", "-lxc-conf"}, "Add custom lxc options --lxc-conf=\"lxc.cgroup.cpuset.cpus = 0,1\"")
|
| 80 |
+ cmd.Var(&flPluginOpts, []string{"-plugin"}, "Add custom plugin options")
|
|
| 80 | 81 |
|
| 81 | 82 |
if err := cmd.Parse(args); err != nil {
|
| 82 | 83 |
return nil, nil, cmd, err |
| ... | ... |
@@ -206,6 +208,8 @@ func parseRun(cmd *flag.FlagSet, args []string, sysInfo *sysinfo.SysInfo) (*Conf |
| 206 | 206 |
WorkingDir: *flWorkingDir, |
| 207 | 207 |
} |
| 208 | 208 |
|
| 209 |
+ pluginOptions := parsePluginOpts(flPluginOpts) |
|
| 210 |
+ |
|
| 209 | 211 |
hostConfig := &HostConfig{
|
| 210 | 212 |
Binds: binds, |
| 211 | 213 |
ContainerIDFile: *flContainerIDFile, |
| ... | ... |
@@ -214,6 +218,7 @@ func parseRun(cmd *flag.FlagSet, args []string, sysInfo *sysinfo.SysInfo) (*Conf |
| 214 | 214 |
PortBindings: portBindings, |
| 215 | 215 |
Links: flLinks.GetAll(), |
| 216 | 216 |
PublishAllPorts: *flPublishAll, |
| 217 |
+ PluginOptions: pluginOptions, |
|
| 217 | 218 |
} |
| 218 | 219 |
|
| 219 | 220 |
if sysInfo != nil && flMemory > 0 && !sysInfo.SwapLimit {
|
| ... | ... |
@@ -247,3 +252,16 @@ func parseLxcOpt(opt string) (string, string, error) {
|
| 247 | 247 |
} |
| 248 | 248 |
return strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1]), nil |
| 249 | 249 |
} |
| 250 |
+ |
|
| 251 |
+func parsePluginOpts(opts opts.ListOpts) map[string][]string {
|
|
| 252 |
+ out := make(map[string][]string, len(opts.GetAll())) |
|
| 253 |
+ for _, o := range opts.GetAll() {
|
|
| 254 |
+ parts := strings.SplitN(o, " ", 2) |
|
| 255 |
+ values, exists := out[parts[0]] |
|
| 256 |
+ if !exists {
|
|
| 257 |
+ values = []string{}
|
|
| 258 |
+ } |
|
| 259 |
+ out[parts[0]] = append(values, parts[1]) |
|
| 260 |
+ } |
|
| 261 |
+ return out |
|
| 262 |
+} |
| ... | ... |
@@ -361,7 +361,7 @@ func (container *Container) Attach(stdin io.ReadCloser, stdinCloser io.Closer, s |
| 361 | 361 |
func populateCommand(c *Container) {
|
| 362 | 362 |
var ( |
| 363 | 363 |
en *execdriver.Network |
| 364 |
- driverConfig []string |
|
| 364 |
+ driverConfig = c.hostConfig.PluginOptions |
|
| 365 | 365 |
) |
| 366 | 366 |
|
| 367 | 367 |
en = &execdriver.Network{
|
| ... | ... |
@@ -379,11 +379,15 @@ func populateCommand(c *Container) {
|
| 379 | 379 |
} |
| 380 | 380 |
} |
| 381 | 381 |
|
| 382 |
+ // merge in the lxc conf options into the generic config map |
|
| 382 | 383 |
if lxcConf := c.hostConfig.LxcConf; lxcConf != nil {
|
| 384 |
+ lxc := driverConfig["lxc"] |
|
| 383 | 385 |
for _, pair := range lxcConf {
|
| 384 |
- driverConfig = append(driverConfig, fmt.Sprintf("%s = %s", pair.Key, pair.Value))
|
|
| 386 |
+ lxc = append(lxc, fmt.Sprintf("%s = %s", pair.Key, pair.Value))
|
|
| 385 | 387 |
} |
| 388 |
+ driverConfig["lxc"] = lxc |
|
| 386 | 389 |
} |
| 390 |
+ |
|
| 387 | 391 |
resources := &execdriver.Resources{
|
| 388 | 392 |
Memory: c.Config.Memory, |
| 389 | 393 |
MemorySwap: c.Config.MemorySwap, |
| ... | ... |
@@ -112,20 +112,20 @@ type Mount struct {
|
| 112 | 112 |
type Command struct {
|
| 113 | 113 |
exec.Cmd `json:"-"` |
| 114 | 114 |
|
| 115 |
- ID string `json:"id"` |
|
| 116 |
- Privileged bool `json:"privileged"` |
|
| 117 |
- User string `json:"user"` |
|
| 118 |
- Rootfs string `json:"rootfs"` // root fs of the container |
|
| 119 |
- InitPath string `json:"initpath"` // dockerinit |
|
| 120 |
- Entrypoint string `json:"entrypoint"` |
|
| 121 |
- Arguments []string `json:"arguments"` |
|
| 122 |
- WorkingDir string `json:"working_dir"` |
|
| 123 |
- ConfigPath string `json:"config_path"` // this should be able to be removed when the lxc template is moved into the driver |
|
| 124 |
- Tty bool `json:"tty"` |
|
| 125 |
- Network *Network `json:"network"` |
|
| 126 |
- Config []string `json:"config"` // generic values that specific drivers can consume |
|
| 127 |
- Resources *Resources `json:"resources"` |
|
| 128 |
- Mounts []Mount `json:"mounts"` |
|
| 115 |
+ ID string `json:"id"` |
|
| 116 |
+ Privileged bool `json:"privileged"` |
|
| 117 |
+ User string `json:"user"` |
|
| 118 |
+ Rootfs string `json:"rootfs"` // root fs of the container |
|
| 119 |
+ InitPath string `json:"initpath"` // dockerinit |
|
| 120 |
+ Entrypoint string `json:"entrypoint"` |
|
| 121 |
+ Arguments []string `json:"arguments"` |
|
| 122 |
+ WorkingDir string `json:"working_dir"` |
|
| 123 |
+ ConfigPath string `json:"config_path"` // this should be able to be removed when the lxc template is moved into the driver |
|
| 124 |
+ Tty bool `json:"tty"` |
|
| 125 |
+ Network *Network `json:"network"` |
|
| 126 |
+ Config map[string][]string `json:"config"` // generic values that specific drivers can consume |
|
| 127 |
+ Resources *Resources `json:"resources"` |
|
| 128 |
+ Mounts []Mount `json:"mounts"` |
|
| 129 | 129 |
|
| 130 | 130 |
Terminal Terminal `json:"-"` // standard or tty terminal |
| 131 | 131 |
Console string `json:"-"` // dev/console path |
| ... | ... |
@@ -75,10 +75,11 @@ func TestCustomLxcConfig(t *testing.T) {
|
| 75 | 75 |
command := &execdriver.Command{
|
| 76 | 76 |
ID: "1", |
| 77 | 77 |
Privileged: false, |
| 78 |
- Config: []string{
|
|
| 78 |
+ Config: map[string][]string{"lxc": {
|
|
| 79 | 79 |
"lxc.utsname = docker", |
| 80 | 80 |
"lxc.cgroup.cpuset.cpus = 0,1", |
| 81 | 81 |
}, |
| 82 |
+ }, |
|
| 82 | 83 |
Network: &execdriver.Network{
|
| 83 | 84 |
Mtu: 1500, |
| 84 | 85 |
Interface: nil, |
| ... | ... |
@@ -184,10 +184,8 @@ func (d *driver) removeContainerRoot(id string) error {
|
| 184 | 184 |
func (d *driver) validateCommand(c *execdriver.Command) error {
|
| 185 | 185 |
// we need to check the Config of the command to make sure that we |
| 186 | 186 |
// do not have any of the lxc-conf variables |
| 187 |
- for _, conf := range c.Config {
|
|
| 188 |
- if strings.Contains(conf, "lxc") {
|
|
| 189 |
- return fmt.Errorf("%s is not supported by the native driver", conf)
|
|
| 190 |
- } |
|
| 187 |
+ for _, conf := range c.Config["native"] {
|
|
| 188 |
+ log.Println(conf) |
|
| 191 | 189 |
} |
| 192 | 190 |
return nil |
| 193 | 191 |
} |