diff --git a/drivers/rkt/driver.go b/drivers/rkt/driver.go index a93b0aaae..e31b8e747 100644 --- a/drivers/rkt/driver.go +++ b/drivers/rkt/driver.go @@ -488,6 +488,21 @@ func (d *Driver) StartTask(cfg *drivers.TaskConfig) (*drivers.TaskHandle, *cstru } } + // Mount task volumes, always do + for i, vol := range cfg.Mounts { + volName := fmt.Sprintf("%s-%s-taskmounts-%d", cfg.AllocID, sanitizedName, i) + prepareArgs = append(prepareArgs, fmt.Sprintf("--volume=%s,kind=host,source=%s,readOnly=%v", volName, vol.HostPath, vol.Readonly)) + prepareArgs = append(prepareArgs, fmt.Sprintf("--mount=volume=%s,target=%s", volName, vol.TaskPath)) + } + + // Mount task devices, always do + for i, vol := range cfg.Devices { + volName := fmt.Sprintf("%s-%s-taskdevices-%d", cfg.AllocID, sanitizedName, i) + readOnly := !strings.Contains(vol.Permissions, "w") + prepareArgs = append(prepareArgs, fmt.Sprintf("--volume=%s,kind=host,source=%s,readOnly=%v", volName, vol.HostPath, readOnly)) + prepareArgs = append(prepareArgs, fmt.Sprintf("--mount=volume=%s,target=%s", volName, vol.TaskPath)) + } + // Inject environment variables for k, v := range cfg.Env { prepareArgs = append(prepareArgs, fmt.Sprintf("--set-env=%s=%s", k, v)) diff --git a/drivers/rkt/driver_test.go b/drivers/rkt/driver_test.go index 0c065ea9e..b7e0c904b 100644 --- a/drivers/rkt/driver_test.go +++ b/drivers/rkt/driver_test.go @@ -502,6 +502,89 @@ func TestRktDriver_Start_Wait_Volume(t *testing.T) { require.NoError(harness.DestroyTask(task.ID, true)) } +// Verifies mounting a task mount from the host machine and writing +// some data to it from inside the container +func TestRktDriver_Start_Wait_TaskMounts(t *testing.T) { + ctestutil.RktCompatible(t) + if !testutil.IsTravis() { + t.Parallel() + } + + require := require.New(t) + d := NewRktDriver(testlog.HCLogger(t)) + harness := dtestutil.NewDriverHarness(t, d) + + // mounts through task config should be enabled regardless + config := &Config{VolumesEnabled: false} + + var data []byte + require.NoError(basePlug.MsgPackEncode(&data, config)) + require.NoError(harness.SetConfig(data, nil)) + + tmpvol, err := ioutil.TempDir("", "nomadtest_rktdriver_volumes") + require.NoError(err) + defer os.RemoveAll(tmpvol) + + task := &drivers.TaskConfig{ + ID: uuid.Generate(), + AllocID: uuid.Generate(), + Name: "rkttest_alpine", + Resources: &drivers.Resources{ + NomadResources: &structs.Resources{ + MemoryMB: 128, + CPU: 100, + }, + LinuxResources: &drivers.LinuxResources{ + MemoryLimitBytes: 134217728, + CPUShares: 100, + }, + }, + Mounts: []*drivers.MountConfig{ + {HostPath: tmpvol, TaskPath: "/foo", Readonly: false}, + }, + } + exp := []byte{'w', 'i', 'n'} + file := "output.txt" + hostpath := filepath.Join(tmpvol, file) + + taskConfig := map[string]interface{}{ + "image": "docker://redis:3.2-alpine", + "command": "/bin/sh", + "args": []string{ + "-c", + fmt.Sprintf("echo -n %s > /foo/%s", string(exp), file), + }, + "net": []string{"none"}, + } + + encodeDriverHelper(require, task, taskConfig) + testtask.SetTaskConfigEnv(task) + + cleanup := harness.MkAllocDir(task, true) + defer cleanup() + + _, _, err = harness.StartTask(task) + require.NoError(err) + + // Task should terminate quickly + waitCh, err := harness.WaitTask(context.Background(), task.ID) + require.NoError(err) + + select { + case res := <-waitCh: + require.NoError(res.Err) + require.True(res.Successful(), fmt.Sprintf("exit code %v", res.ExitCode)) + case <-time.After(time.Duration(testutil.TestMultiplier()*5) * time.Second): + require.Fail("WaitTask timeout") + } + + // Check that data was written to the shared alloc directory. + act, err := ioutil.ReadFile(hostpath) + require.NoError(err) + require.Exactly(exp, act) + require.NoError(harness.DestroyTask(task.ID, true)) +} + // Verifies port mapping func TestRktDriver_PortMapping(t *testing.T) { ctestutil.RktCompatible(t)