Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NOMAD-236 userns podman configuration option #212

Merged
merged 6 commits into from
Mar 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ IMPROVEMENTS:

* config: Add `extra_labels` option [[GH-215](https://github.com/hashicorp/nomad-driver-podman/pull/215)]
* config: Allow setting `pids_limit` option. [[GH-203](https://github.com/hashicorp/nomad-driver-podman/pull/203)]
* config: Allow setting `userns` option. [[GH-212](https://github.com/hashicorp/nomad-driver-podman/pull/212)]
* runtime: Set mount propagation from TaskConfig [[GH-204](https://github.com/hashicorp/nomad-driver-podman/pull/204)]

BUG FIXES:
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,13 @@ config {
}
```

* **userns** - (Optional) Set the [user namespace mode](https://docs.podman.io/en/latest/markdown/podman-run.1.html#userns-mode) for the container.
```hcl
config {
userns = "keep-id:uid=200,gid=210"
}
```

* **pids_limit** - (Optional) An integer value that specifies the pid limit for the container.
```hcl
config {
Expand Down
12 changes: 6 additions & 6 deletions api/structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,12 @@ type ContainerSecurityConfig struct {
// If unset, the container will be run as root.
// Optional.
User string `json:"user,omitempty"`
// UserNS is the container's user namespace.
// It defaults to host, indicating that no user namespace will be
// created.
// If set to private, IDMappings must be set.
// Mandatory.
UserNS Namespace `json:"userns,omitempty"`
// Groups are a list of supplemental groups the container's user will
// be granted access to.
// Optional.
Expand Down Expand Up @@ -292,12 +298,6 @@ type ContainerSecurityConfig struct {
// privileges flag on create, which disables gaining additional
// privileges (e.g. via setuid) in the container.
NoNewPrivileges bool `json:"no_new_privileges,omitempty"`
// UserNS is the container's user namespace.
// It defaults to host, indicating that no user namespace will be
// created.
// If set to private, IDMappings must be set.
// Mandatory.
// UserNS Namespace `json:"userns,omitempty"`

// IDMappings are UID and GID mappings that will be used by user
// namespaces.
Expand Down
2 changes: 2 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ var (
"volumes": hclspec.NewAttr("volumes", "list(string)", false),
"force_pull": hclspec.NewAttr("force_pull", "bool", false),
"readonly_rootfs": hclspec.NewAttr("readonly_rootfs", "bool", false),
"userns": hclspec.NewAttr("userns", "string", false),
})
)

Expand Down Expand Up @@ -164,4 +165,5 @@ type TaskConfig struct {
ForcePull bool `codec:"force_pull"`
Privileged bool `codec:"privileged"`
ReadOnlyRootfs bool `codec:"readonly_rootfs"`
UserNS string `codec:"userns"`
}
12 changes: 12 additions & 0 deletions driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,18 @@ func (d *Driver) StartTask(cfg *drivers.TaskConfig) (*drivers.TaskHandle, *drive
createOpts.ContainerSecurityConfig.ReadOnlyFilesystem = driverConfig.ReadOnlyRootfs
createOpts.ContainerSecurityConfig.ApparmorProfile = driverConfig.ApparmorProfile

// Populate --userns mode only if configured
if driverConfig.UserNS != "" {
userns := strings.SplitN(driverConfig.UserNS, ":", 2)
mode := api.NamespaceMode(userns[0])
// Populate value only if specified
if len(userns) > 1 {
createOpts.ContainerSecurityConfig.UserNS = api.Namespace{NSMode: mode, Value: userns[1]}
} else {
createOpts.ContainerSecurityConfig.UserNS = api.Namespace{NSMode: mode}
}
}

// Network config options
if cfg.DNS != nil {
for _, strdns := range cfg.DNS.Servers {
Expand Down
24 changes: 24 additions & 0 deletions driver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1566,6 +1566,30 @@ func TestPodmanDriver_ReadOnlyFilesystem(t *testing.T) {
require.True(t, inspectData.HostConfig.ReadonlyRootfs)
}

// check userns mode configuration (single value)
func TestPodmanDriver_UsernsMode(t *testing.T) {
// TODO: run test once CI can use rootless Podman.
t.Skip("Test suite requires rootful Podman")

taskCfg := newTaskConfig("", busyboxLongRunningCmd)
taskCfg.UserNS = "host"
inspectData := startDestroyInspect(t, taskCfg, "userns")

require.Equal(t, "host", inspectData.HostConfig.UsernsMode)
}

// check userns mode configuration (parsed value)
func TestPodmanDriver_UsernsModeParsed(t *testing.T) {
// TODO: run test once CI can use rootless Podman.
t.Skip("Test suite requires rootful Podman")

taskCfg := newTaskConfig("", busyboxLongRunningCmd)
taskCfg.UserNS = "keep-id:uid=200,gid=210"
inspectData := startDestroyInspect(t, taskCfg, "userns")

require.Equal(t, "keep-id:uid=200,gid=210", inspectData.HostConfig.UsernsMode)
}

// check dns server configuration
func TestPodmanDriver_Dns(t *testing.T) {
if !tu.IsCI() {
Expand Down