Skip to content

Commit

Permalink
#13 Support for --tmpfs option
Browse files Browse the repository at this point in the history
  • Loading branch information
towe75 committed Dec 31, 2019
1 parent d66b48c commit 4c03f74
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 9 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,16 @@ config {
}
```

* **tmpfs** - (Optional) A list of /container_path strings for tmpfs mount points. See podman run --tmpfs options for details.

```
config {
tmpfs = [
"/var"
]
}
```

* **hostname** - (Optional) The hostname to assign to the container. When launching more than one of a task (using count) with this option set, every container the task starts will have the same hostname.

* **Forwarding and Exposing Ports** - (Optional) See [Docker Driver Configuration](https://www.nomadproject.io/docs/drivers/docker.html#forwarding-and-exposing-ports) for details.
Expand Down
4 changes: 3 additions & 1 deletion config.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ var (
"memory_reservation": hclspec.NewAttr("memory_reservation", "string", false),
"memory_swap": hclspec.NewAttr("memory_swap", "string", false),
"memory_swappiness": hclspec.NewAttr("memory_swappiness", "number", false),
"tmpfs": hclspec.NewAttr("tmpfs", "list(string)", false),
})
)

Expand All @@ -72,7 +73,7 @@ type GCConfig struct {
Container bool `codec:"container"`
}

// VolumeConfig
// VolumeConfig is the drivers volume specific configuration
type VolumeConfig struct {
Enabled bool `codec:"enabled"`
SelinuxLabel string `codec:"selinuxlabel"`
Expand All @@ -98,4 +99,5 @@ type TaskConfig struct {
MemoryReservation string `codec:"memory_reservation"`
MemorySwap string `codec:"memory_swap"`
MemorySwappiness int64 `codec:"memory_swappiness"`
Tmpfs []string `codec:"tmpfs"`
}
1 change: 1 addition & 0 deletions driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,7 @@ func (d *Driver) StartTask(cfg *drivers.TaskConfig) (*drivers.TaskHandle, *drive
MemoryReservation: &driverConfig.MemoryReservation,
MemorySwap: &swap,
MemorySwappiness: &driverConfig.MemorySwappiness,
Tmpfs: &driverConfig.Tmpfs,
}

// Setup port mapping and exposed ports
Expand Down
75 changes: 67 additions & 8 deletions driver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -537,9 +537,7 @@ func TestPodmanDriver_PortMap(t *testing.T) {

defer d.DestroyTask(task.ID, true)

inspectJSON := inspectContainer(t, containerName)
var inspectData iopodman.InspectContainerData
require.NoError(t, json.Unmarshal([]byte(inspectJSON), &inspectData))
inspectData := inspectContainer(t, containerName)

// Verify that the port environment variables are set
require.Contains(t, inspectData.Config.Env, "NOMAD_PORT_main=8888")
Expand Down Expand Up @@ -774,10 +772,8 @@ func TestPodmanDriver_Swap(t *testing.T) {
case <-time.After(time.Duration(tu.TestMultiplier()*2) * time.Second):
}
// inspect container to learn about the actual podman limits
inspectJSON := inspectContainer(t, containerName)
var inspectData iopodman.InspectContainerData
inspectData := inspectContainer(t, containerName)

require.NoError(t, json.Unmarshal([]byte(inspectJSON), &inspectData))
// see if the configured values are set correctly
require.Equal(t, int64(52428800), inspectData.HostConfig.Memory)
require.Equal(t, int64(41943040), inspectData.HostConfig.MemoryReservation)
Expand All @@ -786,6 +782,66 @@ func TestPodmanDriver_Swap(t *testing.T) {

}

// check tmpfs mounts
func TestPodmanDriver_Tmpfs(t *testing.T) {
if !tu.IsCI() {
t.Parallel()
}

taskCfg := newTaskConfig("", []string{
// print our username to stdout
"sh",
"-c",
"mount|grep tmpfs",
})
taskCfg.Tmpfs = []string{
"/tmpdata1",
"/tmpdata2",
}

task := &drivers.TaskConfig{
ID: uuid.Generate(),
Name: "tmpfs",
AllocID: uuid.Generate(),
Resources: createBasicResources(),
}
// use "www-data" as a user for our test, it's part of the busybox image
require.NoError(t, task.EncodeConcreteDriverConfig(&taskCfg))

d := podmanDriverHarness(t, nil)
cleanup := d.MkAllocDir(task, true)
defer cleanup()

containerName := BuildContainerName(task)
_, _, err := d.StartTask(task)
require.NoError(t, err)

defer d.DestroyTask(task.ID, true)

// Attempt to wait
waitCh, err := d.WaitTask(context.Background(), task.ID)
require.NoError(t, err)

select {
case <-waitCh:
case <-time.After(time.Duration(tu.TestMultiplier()*2) * time.Second):
t.Fatalf("Container did not exit in time")
}

// see if tmpfs was propagated to podman
inspectData := inspectContainer(t, containerName)
expectedFilesystem := map[string]string {
"/tmpdata1" : "rw,rprivate,noexec,nosuid,nodev,tmpcopyup",
"/tmpdata2" : "rw,rprivate,noexec,nosuid,nodev,tmpcopyup",
}
require.Exactly(t, expectedFilesystem, inspectData.HostConfig.Tmpfs)

// see if stdout was populated with expected "mount" output
tasklog := readLogfile(t, task)
require.Contains(t, tasklog, " tmpfs on /tmpdata1 type tmpfs ")
require.Contains(t, tasklog, " tmpfs on /tmpdata2 type tmpfs ")
}

// read a tasks logfile into a string, fail on error
func readLogfile(t *testing.T, task *drivers.TaskConfig) string {
logfile := filepath.Join(filepath.Dir(task.StdoutPath), fmt.Sprintf("%s.stdout.0", task.Name))
Expand All @@ -810,7 +866,7 @@ func newTaskConfig(variant string, command []string) TaskConfig {
}
}

func inspectContainer(t *testing.T, containerName string) string {
func inspectContainer(t *testing.T, containerName string) iopodman.InspectContainerData {
ctx := context.Background()
varlinkConnection, err := getPodmanConnection(ctx)
require.NoError(t, err)
Expand All @@ -820,7 +876,10 @@ func inspectContainer(t *testing.T, containerName string) string {
inspectJSON, err := iopodman.InspectContainer().Call(ctx, varlinkConnection, containerName)
require.NoError(t, err)

return inspectJSON
var inspectData iopodman.InspectContainerData
require.NoError(t, json.Unmarshal([]byte(inspectJSON), &inspectData))

return inspectData
}

func getContainer(t *testing.T, containerName string) iopodman.Container {
Expand Down
4 changes: 4 additions & 0 deletions iopodman/inspect.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,10 @@ type InspectContainerHostConfig struct {
// and represents the container port. A single container port may be
// bound to multiple host ports (on different IPs).
PortBindings map[string][]InspectHostPort `json:"PortBindings"`
// Tmpfs is a list of tmpfs filesystems that will be mounted into the
// container.
// It is a map of destination path to options for the mount.
Tmpfs map[string]string `json:"Tmpfs"`
// Memory indicates the memory resources allocated to the container.
// This is the limit (in bytes) of RAM the container may use.
Memory int64 `json:"Memory"`
Expand Down

0 comments on commit 4c03f74

Please sign in to comment.