diff --git a/client/driver/lxc.go b/client/driver/lxc.go index 87011e55a..fefb6f2fb 100644 --- a/client/driver/lxc.go +++ b/client/driver/lxc.go @@ -31,6 +31,11 @@ const ( // Config.Options map. lxcConfigOption = "driver.lxc.enable" + // lxcVolumesConfigOption is the key for enabling the use of + // custom bind volumes to arbitrary host paths + lxcVolumesConfigOption = "lxc.volumes.enabled" + lxcVolumesConfigDefault = true + // containerMonitorIntv is the interval at which the driver checks if the // container is still alive containerMonitorIntv = 2 * time.Second @@ -190,6 +195,12 @@ func (d *LxcDriver) Fingerprint(cfg *config.Config, node *structs.Node) (bool, e } node.Attributes["driver.lxc.version"] = version node.Attributes["driver.lxc"] = "1" + + // Advertise if this node supports lxc volumes + if d.config.ReadBoolDefault(lxcVolumesConfigOption, lxcVolumesConfigDefault) { + node.Attributes["driver."+lxcVolumesConfigOption] = "1" + } + return true, nil } @@ -271,9 +282,21 @@ func (d *LxcDriver) Start(ctx *ExecContext, task *structs.Task) (*StartResponse, fmt.Sprintf("%s secrets none rw,bind,create=dir", ctx.TaskDir.SecretsDir), } + volumesEnabled := d.config.ReadBoolDefault(lxcVolumesConfigOption, lxcVolumesConfigDefault) + for _, volDesc := range driverConfig.Volumes { // the format was checked in Validate() paths := strings.Split(volDesc, ":") + + if filepath.IsAbs(paths[0]) { + if !volumesEnabled { + return nil, fmt.Errorf("absolute bind-mount volume in config but '%v' is false", lxcVolumesConfigOption) + } + } else { + // Relative source paths are treated as relative to alloc dir + paths[0] = filepath.Join(ctx.TaskDir.Dir, paths[0]) + } + mounts = append(mounts, fmt.Sprintf("%s %s none rw,bind,create=dir", paths[0], paths[1])) }