func (d *DockerDriver) containerBinds(driverConfig *DockerDriverConfig, alloc *allocdir.AllocDir, task *structs.Task) ([]string, error) { shared := alloc.SharedDir taskDir, ok := alloc.TaskDirs[task.Name] if !ok { return nil, fmt.Errorf("Failed to find task local directory: %v", task.Name) } local := filepath.Join(taskDir, allocdir.TaskLocal) secret, err := alloc.GetSecretDir(task.Name) if err != nil { return nil, err } allocDirBind := fmt.Sprintf("%s:%s", shared, allocdir.SharedAllocContainerPath) taskLocalBind := fmt.Sprintf("%s:%s", local, allocdir.TaskLocalContainerPath) secretDirBind := fmt.Sprintf("%s:%s", secret, allocdir.TaskSecretsContainerPath) binds := []string{allocDirBind, taskLocalBind, secretDirBind} volumesEnabled := d.config.ReadBoolDefault(dockerVolumesConfigOption, dockerVolumesConfigDefault) for _, userbind := range driverConfig.Volumes { parts := strings.Split(userbind, ":") if len(parts) < 2 { return nil, fmt.Errorf("invalid docker volume: %q", userbind) } // Resolve dotted path segments parts[0] = filepath.Clean(parts[0]) // Absolute paths aren't always supported if filepath.IsAbs(parts[0]) { if !volumesEnabled { // Disallow mounting arbitrary absolute paths return nil, fmt.Errorf("%s is false; cannot mount host paths: %+q", dockerVolumesConfigOption, userbind) } binds = append(binds, userbind) continue } // Relative paths are always allowed as they mount within a container // Expand path relative to alloc dir parts[0] = filepath.Join(taskDir, parts[0]) binds = append(binds, strings.Join(parts, ":")) } if selinuxLabel := d.config.Read(dockerSELinuxLabelConfigOption); selinuxLabel != "" { // Apply SELinux Label to each volume for i := range binds { binds[i] = fmt.Sprintf("%s:%s", binds[i], selinuxLabel) } } return binds, nil }
// ConfigureTaskDir creates the necessary directory structure for a proper // chroot. cleanTaskDir should be called after. func (e *LinuxExecutor) ConfigureTaskDir(taskName string, alloc *allocdir.AllocDir) error { e.taskName = taskName e.allocDir = alloc.AllocDir taskDir, ok := alloc.TaskDirs[taskName] if !ok { fmt.Errorf("Couldn't find task directory for task %v", taskName) } e.taskDir = taskDir if err := alloc.MountSharedDir(taskName); err != nil { return err } if err := alloc.Embed(taskName, chrootEnv); err != nil { return err } // Mount dev dev := filepath.Join(taskDir, "dev") if !e.pathExists(dev) { if err := os.Mkdir(dev, 0777); err != nil { return fmt.Errorf("Mkdir(%v) failed: %v", dev, err) } if err := syscall.Mount("", dev, "devtmpfs", syscall.MS_RDONLY, ""); err != nil { return fmt.Errorf("Couldn't mount /dev to %v: %v", dev, err) } } // Mount proc proc := filepath.Join(taskDir, "proc") if !e.pathExists(proc) { if err := os.Mkdir(proc, 0777); err != nil { return fmt.Errorf("Mkdir(%v) failed: %v", proc, err) } if err := syscall.Mount("", proc, "proc", syscall.MS_RDONLY, ""); err != nil { return fmt.Errorf("Couldn't mount /proc to %v: %v", proc, err) } } // Set the tasks AllocDir environment variable. env, err := environment.ParseFromList(e.cmd.Env) if err != nil { return err } env.SetAllocDir(filepath.Join("/", allocdir.SharedAllocName)) env.SetTaskLocalDir(filepath.Join("/", allocdir.TaskLocal)) e.cmd.Env = env.List() return nil }
func (d *DockerDriver) containerBinds(driverConfig *DockerDriverConfig, alloc *allocdir.AllocDir, task *structs.Task) ([]string, error) { shared := alloc.SharedDir taskDir, ok := alloc.TaskDirs[task.Name] if !ok { return nil, fmt.Errorf("Failed to find task local directory: %v", task.Name) } local := filepath.Join(taskDir, allocdir.TaskLocal) secret, err := alloc.GetSecretDir(task.Name) if err != nil { return nil, err } allocDirBind := fmt.Sprintf("%s:%s", shared, allocdir.SharedAllocContainerPath) taskLocalBind := fmt.Sprintf("%s:%s", local, allocdir.TaskLocalContainerPath) secretDirBind := fmt.Sprintf("%s:%s", secret, allocdir.TaskSecretsContainerPath) binds := []string{allocDirBind, taskLocalBind, secretDirBind} volumesEnabled := d.config.ReadBoolDefault(dockerVolumesConfigOption, false) if len(driverConfig.Volumes) > 0 && !volumesEnabled { return nil, fmt.Errorf("%s is false; cannot use Docker Volumes: %+q", dockerVolumesConfigOption, driverConfig.Volumes) } if len(driverConfig.Volumes) > 0 { binds = append(binds, driverConfig.Volumes...) } if selinuxLabel := d.config.Read(dockerSELinuxLabelConfigOption); selinuxLabel != "" { // Apply SELinux Label to each volume for i := range binds { binds[i] = fmt.Sprintf("%s:%s", binds[i], selinuxLabel) } } return binds, nil }