drivers/exec+java: Add configuration to restore previous PID/IPC namespace behavior.

This PR adds default_pid_mode and default_ipc_mode options to the exec and java
task drivers. By default these will default to "private" mode, enabling PID and
IPC isolation for tasks. Setting them to "host" mode disables isolation. Doing
so is not recommended, but may be necessary to support legacy job configurations.

Closes #9969
This commit is contained in:
Seth Hoenig 2021-02-04 13:01:51 -06:00
parent 1fda6a4126
commit 4bc6e5a215
15 changed files with 412 additions and 117 deletions

View file

@ -6,6 +6,7 @@ FEATURES:
IMPROVEMENTS: IMPROVEMENTS:
* cli: Improved `scaling policy` commands with -verbose, auto-completion, and prefix-matching [[GH-9964](https://github.com/hashicorp/nomad/issues/9964)] * cli: Improved `scaling policy` commands with -verbose, auto-completion, and prefix-matching [[GH-9964](https://github.com/hashicorp/nomad/issues/9964)]
* consul/connect: Made handling of sidecar task container image URLs consistent with the `docker` task driver. [[GH-9580](https://github.com/hashicorp/nomad/issues/9580)] * consul/connect: Made handling of sidecar task container image URLs consistent with the `docker` task driver. [[GH-9580](https://github.com/hashicorp/nomad/issues/9580)]
* drivers/exec+java: Added client plugin configuration to re-enable previous PID/IPC namespace behavior [[GH-9982](https://github.com/hashicorp/nomad/pull/9982)]
BUG FIXES: BUG FIXES:
* consul: Fixed a bug where failing tasks with group services would only cause the allocation to restart once instead of respecting the `restart` field. [[GH-9869](https://github.com/hashicorp/nomad/issues/9869)] * consul: Fixed a bug where failing tasks with group services would only cause the allocation to restart once instead of respecting the `restart` field. [[GH-9869](https://github.com/hashicorp/nomad/issues/9869)]

View file

@ -87,7 +87,7 @@ func commandAssetsConnectShortNomad() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "command/assets/connect-short.nomad", size: 997, mode: os.FileMode(436), modTime: time.Unix(1610319873, 0)} info := bindataFileInfo{name: "command/assets/connect-short.nomad", size: 997, mode: os.FileMode(436), modTime: time.Unix(1612560436, 0)}
a := &asset{bytes: bytes, info: info} a := &asset{bytes: bytes, info: info}
return a, nil return a, nil
} }
@ -107,7 +107,7 @@ func commandAssetsConnectNomad() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "command/assets/connect.nomad", size: 17842, mode: os.FileMode(436), modTime: time.Unix(1610319873, 0)} info := bindataFileInfo{name: "command/assets/connect.nomad", size: 17842, mode: os.FileMode(436), modTime: time.Unix(1612560436, 0)}
a := &asset{bytes: bytes, info: info} a := &asset{bytes: bytes, info: info}
return a, nil return a, nil
} }
@ -127,7 +127,7 @@ func commandAssetsExampleShortNomad() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "command/assets/example-short.nomad", size: 324, mode: os.FileMode(436), modTime: time.Unix(1610319873, 0)} info := bindataFileInfo{name: "command/assets/example-short.nomad", size: 324, mode: os.FileMode(436), modTime: time.Unix(1612560436, 0)}
a := &asset{bytes: bytes, info: info} a := &asset{bytes: bytes, info: info}
return a, nil return a, nil
} }
@ -147,7 +147,7 @@ func commandAssetsExampleNomad() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "command/assets/example.nomad", size: 16057, mode: os.FileMode(436), modTime: time.Unix(1610319873, 0)} info := bindataFileInfo{name: "command/assets/example.nomad", size: 16057, mode: os.FileMode(436), modTime: time.Unix(1612560436, 0)}
a := &asset{bytes: bytes, info: info} a := &asset{bytes: bytes, info: info}
return a, nil return a, nil
} }

View file

@ -65,6 +65,14 @@ var (
hclspec.NewAttr("no_pivot_root", "bool", false), hclspec.NewAttr("no_pivot_root", "bool", false),
hclspec.NewLiteral("false"), hclspec.NewLiteral("false"),
), ),
"default_pid_mode": hclspec.NewDefault(
hclspec.NewAttr("default_pid_mode", "string", false),
hclspec.NewLiteral(`"private"`),
),
"default_ipc_mode": hclspec.NewDefault(
hclspec.NewAttr("default_ipc_mode", "string", false),
hclspec.NewLiteral(`"private"`),
),
}) })
// taskConfigSpec is the hcl specification for the driver config section of // taskConfigSpec is the hcl specification for the driver config section of
@ -122,6 +130,30 @@ type Config struct {
// NoPivotRoot disables the use of pivot_root, useful when the root partition // NoPivotRoot disables the use of pivot_root, useful when the root partition
// is on ramdisk // is on ramdisk
NoPivotRoot bool `codec:"no_pivot_root"` NoPivotRoot bool `codec:"no_pivot_root"`
// DefaultModePID is the default PID isolation set for all tasks using
// exec-based task drivers.
DefaultModePID string `codec:"default_pid_mode"`
// DefaultModeIPC is the default IPC isolation set for all tasks using
// exec-based task drivers.
DefaultModeIPC string `codec:"default_ipc_mode"`
}
func (c *Config) validate() error {
switch c.DefaultModePID {
case executor.IsoModePrivate, executor.IsoModeHost:
default:
return fmt.Errorf("default_pid_mode must be %q or %q, got %q", executor.IsoModePrivate, executor.IsoModeHost, c.DefaultModePID)
}
switch c.DefaultModeIPC {
case executor.IsoModePrivate, executor.IsoModeHost:
default:
return fmt.Errorf("default_ipc_mode must be %q or %q, got %q", executor.IsoModePrivate, executor.IsoModeHost, c.DefaultModeIPC)
}
return nil
} }
// TaskConfig is the driver configuration of a task within a job // TaskConfig is the driver configuration of a task within a job
@ -182,14 +214,18 @@ func (d *Driver) ConfigSchema() (*hclspec.Spec, error) {
} }
func (d *Driver) SetConfig(cfg *base.Config) error { func (d *Driver) SetConfig(cfg *base.Config) error {
// unpack, validate, and set agent plugin config
var config Config var config Config
if len(cfg.PluginConfig) != 0 { if len(cfg.PluginConfig) != 0 {
if err := base.MsgPackDecode(cfg.PluginConfig, &config); err != nil { if err := base.MsgPackDecode(cfg.PluginConfig, &config); err != nil {
return err return err
} }
} }
if err := config.validate(); err != nil {
return err
}
d.config = config d.config = config
if cfg != nil && cfg.AgentConfig != nil { if cfg != nil && cfg.AgentConfig != nil {
d.nomadConfig = cfg.AgentConfig.Driver d.nomadConfig = cfg.AgentConfig.Driver
} }
@ -383,6 +419,8 @@ func (d *Driver) StartTask(cfg *drivers.TaskConfig) (*drivers.TaskHandle, *drive
Mounts: cfg.Mounts, Mounts: cfg.Mounts,
Devices: cfg.Devices, Devices: cfg.Devices,
NetworkIsolation: cfg.NetworkIsolation, NetworkIsolation: cfg.NetworkIsolation,
DefaultModePID: d.config.DefaultModePID,
DefaultModeIPC: d.config.DefaultModeIPC,
} }
ps, err := exec.Launch(execCmd) ps, err := exec.Launch(execCmd)

View file

@ -3,6 +3,7 @@ package exec
import ( import (
"bytes" "bytes"
"context" "context"
"errors"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"os" "os"
@ -16,6 +17,7 @@ import (
"time" "time"
ctestutils "github.com/hashicorp/nomad/client/testutil" ctestutils "github.com/hashicorp/nomad/client/testutil"
"github.com/hashicorp/nomad/drivers/shared/executor"
"github.com/hashicorp/nomad/helper/pluginutils/hclutils" "github.com/hashicorp/nomad/helper/pluginutils/hclutils"
"github.com/hashicorp/nomad/helper/testlog" "github.com/hashicorp/nomad/helper/testlog"
"github.com/hashicorp/nomad/helper/testtask" "github.com/hashicorp/nomad/helper/testtask"
@ -273,7 +275,7 @@ func TestExecDriver_StartWaitRecover(t *testing.T) {
// task dies, the orphans in the PID namespaces are killed by the kernel // task dies, the orphans in the PID namespaces are killed by the kernel
func TestExecDriver_NoOrphans(t *testing.T) { func TestExecDriver_NoOrphans(t *testing.T) {
t.Parallel() t.Parallel()
require := require.New(t) r := require.New(t)
ctestutils.ExecCompatible(t) ctestutils.ExecCompatible(t)
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
@ -283,6 +285,17 @@ func TestExecDriver_NoOrphans(t *testing.T) {
harness := dtestutil.NewDriverHarness(t, d) harness := dtestutil.NewDriverHarness(t, d)
defer harness.Kill() defer harness.Kill()
config := &Config{
NoPivotRoot: false,
DefaultModePID: executor.IsoModePrivate,
DefaultModeIPC: executor.IsoModePrivate,
}
var data []byte
r.NoError(basePlug.MsgPackEncode(&data, config))
baseConfig := &basePlug.Config{PluginConfig: data}
r.NoError(harness.SetConfig(baseConfig))
task := &drivers.TaskConfig{ task := &drivers.TaskConfig{
ID: uuid.Generate(), ID: uuid.Generate(),
Name: "test", Name: "test",
@ -295,21 +308,21 @@ func TestExecDriver_NoOrphans(t *testing.T) {
taskConfig["command"] = "/bin/sh" taskConfig["command"] = "/bin/sh"
// print the child PID in the task PID namespace, then sleep for 5 seconds to give us a chance to examine processes // print the child PID in the task PID namespace, then sleep for 5 seconds to give us a chance to examine processes
taskConfig["args"] = []string{"-c", fmt.Sprintf(`sleep 3600 & sleep 20`)} taskConfig["args"] = []string{"-c", fmt.Sprintf(`sleep 3600 & sleep 20`)}
require.NoError(task.EncodeConcreteDriverConfig(&taskConfig)) r.NoError(task.EncodeConcreteDriverConfig(&taskConfig))
handle, _, err := harness.StartTask(task) handle, _, err := harness.StartTask(task)
require.NoError(err) r.NoError(err)
defer harness.DestroyTask(task.ID, true) defer harness.DestroyTask(task.ID, true)
waitCh, err := harness.WaitTask(context.Background(), handle.Config.ID) waitCh, err := harness.WaitTask(context.Background(), handle.Config.ID)
require.NoError(err) r.NoError(err)
require.NoError(harness.WaitUntilStarted(task.ID, 1*time.Second)) r.NoError(harness.WaitUntilStarted(task.ID, 1*time.Second))
var childPids []int var childPids []int
taskState := TaskState{} taskState := TaskState{}
testutil.WaitForResult(func() (bool, error) { testutil.WaitForResult(func() (bool, error) {
require.NoError(handle.GetDriverState(&taskState)) r.NoError(handle.GetDriverState(&taskState))
if taskState.Pid == 0 { if taskState.Pid == 0 {
return false, fmt.Errorf("task PID is zero") return false, fmt.Errorf("task PID is zero")
} }
@ -331,14 +344,14 @@ func TestExecDriver_NoOrphans(t *testing.T) {
} }
return true, nil return true, nil
}, func(err error) { }, func(err error) {
require.NoError(err) r.NoError(err)
}) })
select { select {
case result := <-waitCh: case result := <-waitCh:
require.True(result.Successful(), "command failed: %#v", result) r.True(result.Successful(), "command failed: %#v", result)
case <-time.After(30 * time.Second): case <-time.After(30 * time.Second):
require.Fail("timeout waiting for task to shutdown") r.Fail("timeout waiting for task to shutdown")
} }
// isProcessRunning returns an error if process is not running // isProcessRunning returns an error if process is not running
@ -357,7 +370,7 @@ func TestExecDriver_NoOrphans(t *testing.T) {
} }
// task should be dead // task should be dead
require.Error(isProcessRunning(taskState.Pid)) r.Error(isProcessRunning(taskState.Pid))
// all children should eventually be killed by OS // all children should eventually be killed by OS
testutil.WaitForResult(func() (bool, error) { testutil.WaitForResult(func() (bool, error) {
@ -372,7 +385,7 @@ func TestExecDriver_NoOrphans(t *testing.T) {
} }
return true, nil return true, nil
}, func(err error) { }, func(err error) {
require.NoError(err) r.NoError(err)
}) })
} }
@ -711,7 +724,7 @@ config {
func TestExecDriver_NoPivotRoot(t *testing.T) { func TestExecDriver_NoPivotRoot(t *testing.T) {
t.Parallel() t.Parallel()
require := require.New(t) r := require.New(t)
ctestutils.ExecCompatible(t) ctestutils.ExecCompatible(t)
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
@ -720,11 +733,16 @@ func TestExecDriver_NoPivotRoot(t *testing.T) {
d := NewExecDriver(ctx, testlog.HCLogger(t)) d := NewExecDriver(ctx, testlog.HCLogger(t))
harness := dtestutil.NewDriverHarness(t, d) harness := dtestutil.NewDriverHarness(t, d)
config := &Config{NoPivotRoot: true} config := &Config{
NoPivotRoot: true,
DefaultModePID: executor.IsoModePrivate,
DefaultModeIPC: executor.IsoModePrivate,
}
var data []byte var data []byte
require.NoError(basePlug.MsgPackEncode(&data, config)) r.NoError(basePlug.MsgPackEncode(&data, config))
bconfig := &basePlug.Config{PluginConfig: data} bconfig := &basePlug.Config{PluginConfig: data}
require.NoError(harness.SetConfig(bconfig)) r.NoError(harness.SetConfig(bconfig))
task := &drivers.TaskConfig{ task := &drivers.TaskConfig{
ID: uuid.Generate(), ID: uuid.Generate(),
@ -738,9 +756,28 @@ func TestExecDriver_NoPivotRoot(t *testing.T) {
Command: "/bin/sleep", Command: "/bin/sleep",
Args: []string{"100"}, Args: []string{"100"},
} }
require.NoError(task.EncodeConcreteDriverConfig(&tc)) r.NoError(task.EncodeConcreteDriverConfig(&tc))
handle, _, err := harness.StartTask(task) handle, _, err := harness.StartTask(task)
require.NoError(err) r.NoError(err)
require.NotNil(handle) r.NotNil(handle)
}
func TestDriver_Config_validate(t *testing.T) {
for _, tc := range []struct {
pidMode, ipcMode string
exp error
}{
{pidMode: "host", ipcMode: "host", exp: nil},
{pidMode: "private", ipcMode: "host", exp: nil},
{pidMode: "host", ipcMode: "private", exp: nil},
{pidMode: "private", ipcMode: "private", exp: nil},
{pidMode: "other", ipcMode: "private", exp: errors.New(`default_pid_mode must be "private" or "host", got "other"`)},
{pidMode: "private", ipcMode: "other", exp: errors.New(`default_ipc_mode must be "private" or "host", got "other"`)},
} {
require.Equal(t, tc.exp, (&Config{
DefaultModePID: tc.pidMode,
DefaultModeIPC: tc.ipcMode,
}).validate())
}
} }

View file

@ -63,7 +63,16 @@ var (
} }
// configSpec is the hcl specification returned by the ConfigSchema RPC // configSpec is the hcl specification returned by the ConfigSchema RPC
configSpec = hclspec.NewObject(map[string]*hclspec.Spec{}) configSpec = hclspec.NewObject(map[string]*hclspec.Spec{
"default_pid_mode": hclspec.NewDefault(
hclspec.NewAttr("default_pid_mode", "string", false),
hclspec.NewLiteral(`"private"`),
),
"default_ipc_mode": hclspec.NewDefault(
hclspec.NewAttr("default_ipc_mode", "string", false),
hclspec.NewLiteral(`"private"`),
),
})
// taskConfigSpec is the hcl specification for the driver config section of // taskConfigSpec is the hcl specification for the driver config section of
// a taskConfig within a job. It is returned in the TaskConfigSchema RPC // a taskConfig within a job. It is returned in the TaskConfigSchema RPC
@ -101,6 +110,33 @@ func init() {
} }
} }
// Config is the driver configuration set by the SetConfig RPC call
type Config struct {
// DefaultModePID is the default PID isolation set for all tasks using
// exec-based task drivers.
DefaultModePID string `codec:"default_pid_mode"`
// DefaultModeIPC is the default IPC isolation set for all tasks using
// exec-based task drivers.
DefaultModeIPC string `codec:"default_ipc_mode"`
}
func (c *Config) validate() error {
switch c.DefaultModePID {
case executor.IsoModePrivate, executor.IsoModeHost:
default:
return fmt.Errorf("default_pid_mode must be %q or %q, got %q", executor.IsoModePrivate, executor.IsoModeHost, c.DefaultModePID)
}
switch c.DefaultModeIPC {
case executor.IsoModePrivate, executor.IsoModeHost:
default:
return fmt.Errorf("default_ipc_mode must be %q or %q, got %q", executor.IsoModePrivate, executor.IsoModeHost, c.DefaultModeIPC)
}
return nil
}
// TaskConfig is the driver configuration of a taskConfig within a job // TaskConfig is the driver configuration of a taskConfig within a job
type TaskConfig struct { type TaskConfig struct {
Class string `codec:"class"` Class string `codec:"class"`
@ -126,6 +162,9 @@ type Driver struct {
// event can be broadcast to all callers // event can be broadcast to all callers
eventer *eventer.Eventer eventer *eventer.Eventer
// config is the driver configuration set by the SetConfig RPC
config Config
// tasks is the in memory datastore mapping taskIDs to taskHandle // tasks is the in memory datastore mapping taskIDs to taskHandle
tasks *taskStore tasks *taskStore
@ -159,6 +198,18 @@ func (d *Driver) ConfigSchema() (*hclspec.Spec, error) {
} }
func (d *Driver) SetConfig(cfg *base.Config) error { func (d *Driver) SetConfig(cfg *base.Config) error {
// unpack, validate, and set agent plugin config
var config Config
if len(cfg.PluginConfig) != 0 {
if err := base.MsgPackDecode(cfg.PluginConfig, &config); err != nil {
return err
}
}
if err := config.validate(); err != nil {
return err
}
d.config = config
if cfg != nil && cfg.AgentConfig != nil { if cfg != nil && cfg.AgentConfig != nil {
d.nomadConfig = cfg.AgentConfig.Driver d.nomadConfig = cfg.AgentConfig.Driver
} }
@ -374,6 +425,8 @@ func (d *Driver) StartTask(cfg *drivers.TaskConfig) (*drivers.TaskHandle, *drive
Mounts: cfg.Mounts, Mounts: cfg.Mounts,
Devices: cfg.Devices, Devices: cfg.Devices,
NetworkIsolation: cfg.NetworkIsolation, NetworkIsolation: cfg.NetworkIsolation,
DefaultModePID: d.config.DefaultModePID,
DefaultModeIPC: d.config.DefaultModeIPC,
} }
ps, err := exec.Launch(execCmd) ps, err := exec.Launch(execCmd)

View file

@ -1,6 +1,7 @@
package java package java
import ( import (
"errors"
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
@ -413,3 +414,22 @@ func Test_dnsConfig(t *testing.T) {
} }
} }
func TestDriver_Config_validate(t *testing.T) {
for _, tc := range []struct {
pidMode, ipcMode string
exp error
}{
{pidMode: "host", ipcMode: "host", exp: nil},
{pidMode: "private", ipcMode: "host", exp: nil},
{pidMode: "host", ipcMode: "private", exp: nil},
{pidMode: "private", ipcMode: "private", exp: nil},
{pidMode: "other", ipcMode: "private", exp: errors.New(`default_pid_mode must be "private" or "host", got "other"`)},
{pidMode: "private", ipcMode: "other", exp: errors.New(`default_ipc_mode must be "private" or "host", got "other"`)},
} {
require.Equal(t, tc.exp, (&Config{
DefaultModePID: tc.pidMode,
DefaultModeIPC: tc.ipcMode,
}).validate())
}
}

View file

@ -45,6 +45,8 @@ func (c *grpcExecutorClient) Launch(cmd *ExecCommand) (*ProcessState, error) {
Mounts: drivers.MountsToProto(cmd.Mounts), Mounts: drivers.MountsToProto(cmd.Mounts),
Devices: drivers.DevicesToProto(cmd.Devices), Devices: drivers.DevicesToProto(cmd.Devices),
NetworkIsolation: drivers.NetworkIsolationSpecToProto(cmd.NetworkIsolation), NetworkIsolation: drivers.NetworkIsolationSpecToProto(cmd.NetworkIsolation),
DefaultPidMode: cmd.DefaultModePID,
DefaultIpcMode: cmd.DefaultModeIPC,
} }
resp, err := c.client.Launch(ctx, req) resp, err := c.client.Launch(ctx, req)
if err != nil { if err != nil {

View file

@ -34,6 +34,12 @@ const (
// ExecutorVersionPre0_9 is the version of executor use prior to the release // ExecutorVersionPre0_9 is the version of executor use prior to the release
// of 0.9.x // of 0.9.x
ExecutorVersionPre0_9 = "1.1.0" ExecutorVersionPre0_9 = "1.1.0"
// IsoModePrivate represents the private isolation mode for a namespace
IsoModePrivate = "private"
// IsoModeHost represents the host isolation mode for a namespace
IsoModeHost = "host"
) )
var ( var (
@ -132,7 +138,14 @@ type ExecCommand struct {
// Devices are the the device nodes to be created in isolation environment // Devices are the the device nodes to be created in isolation environment
Devices []*drivers.DeviceConfig Devices []*drivers.DeviceConfig
// NetworkIsolation is the network isolation configuration.
NetworkIsolation *drivers.NetworkIsolationSpec NetworkIsolation *drivers.NetworkIsolationSpec
// DefaultModePID is the default PID isolation mode (private or host).
DefaultModePID string
// DefaultModeIPC is the default IPC isolation mode (private or host).
DefaultModeIPC string
} }
// SetWriters sets the writer for the process stdout and stderr. This should // SetWriters sets the writer for the process stdout and stderr. This should

View file

@ -562,6 +562,17 @@ func supportedCaps() []string {
return allCaps return allCaps
} }
func configureNamespaces(pidMode, ipcMode string) lconfigs.Namespaces {
namespaces := lconfigs.Namespaces{{Type: lconfigs.NEWNS}}
if pidMode == IsoModePrivate {
namespaces = append(namespaces, lconfigs.Namespace{Type: lconfigs.NEWPID})
}
if ipcMode == IsoModePrivate {
namespaces = append(namespaces, lconfigs.Namespace{Type: lconfigs.NEWIPC})
}
return namespaces
}
// configureIsolation prepares the isolation primitives of the container. // configureIsolation prepares the isolation primitives of the container.
// The process runs in a container configured with the following: // The process runs in a container configured with the following:
// //
@ -578,12 +589,8 @@ func configureIsolation(cfg *lconfigs.Config, command *ExecCommand) error {
// disable pivot_root if set in the driver's configuration // disable pivot_root if set in the driver's configuration
cfg.NoPivotRoot = command.NoPivotRoot cfg.NoPivotRoot = command.NoPivotRoot
// launch with mount namespace // setup default namespaces as configured
cfg.Namespaces = lconfigs.Namespaces{ cfg.Namespaces = configureNamespaces(command.DefaultModePID, command.DefaultModeIPC)
{Type: lconfigs.NEWNS},
{Type: lconfigs.NEWPID},
{Type: lconfigs.NEWIPC},
}
if command.NetworkIsolation != nil { if command.NetworkIsolation != nil {
cfg.Namespaces = append(cfg.Namespaces, lconfigs.Namespace{ cfg.Namespaces = append(cfg.Namespaces, lconfigs.Namespace{

View file

@ -87,9 +87,39 @@ func testExecutorCommandWithChroot(t *testing.T) *testExecCmd {
return testCmd return testCmd
} }
func TestExecutor_IsolationAndConstraints(t *testing.T) { func TestExecutor_configureNamespaces(t *testing.T) {
t.Run("host host", func(t *testing.T) {
require.Equal(t, lconfigs.Namespaces{
{Type: lconfigs.NEWNS},
}, configureNamespaces("host", "host"))
})
t.Run("host private", func(t *testing.T) {
require.Equal(t, lconfigs.Namespaces{
{Type: lconfigs.NEWNS},
{Type: lconfigs.NEWIPC},
}, configureNamespaces("host", "private"))
})
t.Run("private host", func(t *testing.T) {
require.Equal(t, lconfigs.Namespaces{
{Type: lconfigs.NEWNS},
{Type: lconfigs.NEWPID},
}, configureNamespaces("private", "host"))
})
t.Run("private private", func(t *testing.T) {
require.Equal(t, lconfigs.Namespaces{
{Type: lconfigs.NEWNS},
{Type: lconfigs.NEWPID},
{Type: lconfigs.NEWIPC},
}, configureNamespaces("private", "private"))
})
}
func TestExecutor_Isolation_PID_and_IPC_hostMode(t *testing.T) {
t.Parallel() t.Parallel()
require := require.New(t) r := require.New(t)
testutil.ExecCompatible(t) testutil.ExecCompatible(t)
testExecCmd := testExecutorCommandWithChroot(t) testExecCmd := testExecutorCommandWithChroot(t)
@ -99,43 +129,85 @@ func TestExecutor_IsolationAndConstraints(t *testing.T) {
defer allocDir.Destroy() defer allocDir.Destroy()
execCmd.ResourceLimits = true execCmd.ResourceLimits = true
execCmd.DefaultModePID = "host" // disable PID namespace
execCmd.DefaultModeIPC = "host" // disable IPC namespace
executor := NewExecutorWithIsolation(testlog.HCLogger(t)) executor := NewExecutorWithIsolation(testlog.HCLogger(t))
defer executor.Shutdown("SIGKILL", 0) defer executor.Shutdown("SIGKILL", 0)
ps, err := executor.Launch(execCmd) ps, err := executor.Launch(execCmd)
require.NoError(err) r.NoError(err)
require.NotZero(ps.Pid) r.NotZero(ps.Pid)
estate, err := executor.Wait(context.Background()) estate, err := executor.Wait(context.Background())
require.NoError(err) r.NoError(err)
require.Zero(estate.ExitCode) r.Zero(estate.ExitCode)
lexec, ok := executor.(*LibcontainerExecutor) lexec, ok := executor.(*LibcontainerExecutor)
require.True(ok) r.True(ok)
// Check if the resource constraints were applied
state, err := lexec.container.State()
require.NoError(err)
memLimits := filepath.Join(state.CgroupPaths["memory"], "memory.limit_in_bytes")
data, err := ioutil.ReadFile(memLimits)
require.NoError(err)
expectedMemLim := strconv.Itoa(int(execCmd.Resources.NomadResources.Memory.MemoryMB * 1024 * 1024))
actualMemLim := strings.TrimSpace(string(data))
require.Equal(actualMemLim, expectedMemLim)
// Check that namespaces were applied to the container config // Check that namespaces were applied to the container config
config := lexec.container.Config() config := lexec.container.Config()
require.NoError(err)
require.Contains(config.Namespaces, lconfigs.Namespace{Type: lconfigs.NEWNS}) r.Contains(config.Namespaces, lconfigs.Namespace{Type: lconfigs.NEWNS})
require.Contains(config.Namespaces, lconfigs.Namespace{Type: lconfigs.NEWPID}) r.NotContains(config.Namespaces, lconfigs.Namespace{Type: lconfigs.NEWPID})
require.Contains(config.Namespaces, lconfigs.Namespace{Type: lconfigs.NEWIPC}) r.NotContains(config.Namespaces, lconfigs.Namespace{Type: lconfigs.NEWIPC})
// Shut down executor // Shut down executor
require.NoError(executor.Shutdown("", 0)) r.NoError(executor.Shutdown("", 0))
executor.Wait(context.Background())
}
func TestExecutor_IsolationAndConstraints(t *testing.T) {
t.Parallel()
r := require.New(t)
testutil.ExecCompatible(t)
testExecCmd := testExecutorCommandWithChroot(t)
execCmd, allocDir := testExecCmd.command, testExecCmd.allocDir
execCmd.Cmd = "/bin/ls"
execCmd.Args = []string{"-F", "/", "/etc/"}
defer allocDir.Destroy()
execCmd.ResourceLimits = true
execCmd.DefaultModePID = "private"
execCmd.DefaultModeIPC = "private"
executor := NewExecutorWithIsolation(testlog.HCLogger(t))
defer executor.Shutdown("SIGKILL", 0)
ps, err := executor.Launch(execCmd)
r.NoError(err)
r.NotZero(ps.Pid)
estate, err := executor.Wait(context.Background())
r.NoError(err)
r.Zero(estate.ExitCode)
lexec, ok := executor.(*LibcontainerExecutor)
r.True(ok)
// Check if the resource constraints were applied
state, err := lexec.container.State()
r.NoError(err)
memLimits := filepath.Join(state.CgroupPaths["memory"], "memory.limit_in_bytes")
data, err := ioutil.ReadFile(memLimits)
r.NoError(err)
expectedMemLim := strconv.Itoa(int(execCmd.Resources.NomadResources.Memory.MemoryMB * 1024 * 1024))
actualMemLim := strings.TrimSpace(string(data))
r.Equal(actualMemLim, expectedMemLim)
// Check that namespaces were applied to the container config
config := lexec.container.Config()
r.Contains(config.Namespaces, lconfigs.Namespace{Type: lconfigs.NEWNS})
r.Contains(config.Namespaces, lconfigs.Namespace{Type: lconfigs.NEWPID})
r.Contains(config.Namespaces, lconfigs.Namespace{Type: lconfigs.NEWIPC})
// Shut down executor
r.NoError(executor.Shutdown("", 0))
executor.Wait(context.Background()) executor.Wait(context.Background())
// Check if Nomad has actually removed the cgroups // Check if Nomad has actually removed the cgroups

View file

@ -41,6 +41,8 @@ type LaunchRequest struct {
Devices []*proto1.Device `protobuf:"bytes,12,rep,name=devices,proto3" json:"devices,omitempty"` Devices []*proto1.Device `protobuf:"bytes,12,rep,name=devices,proto3" json:"devices,omitempty"`
NetworkIsolation *proto1.NetworkIsolationSpec `protobuf:"bytes,13,opt,name=network_isolation,json=networkIsolation,proto3" json:"network_isolation,omitempty"` NetworkIsolation *proto1.NetworkIsolationSpec `protobuf:"bytes,13,opt,name=network_isolation,json=networkIsolation,proto3" json:"network_isolation,omitempty"`
NoPivotRoot bool `protobuf:"varint,14,opt,name=no_pivot_root,json=noPivotRoot,proto3" json:"no_pivot_root,omitempty"` NoPivotRoot bool `protobuf:"varint,14,opt,name=no_pivot_root,json=noPivotRoot,proto3" json:"no_pivot_root,omitempty"`
DefaultPidMode string `protobuf:"bytes,15,opt,name=default_pid_mode,json=defaultPidMode,proto3" json:"default_pid_mode,omitempty"`
DefaultIpcMode string `protobuf:"bytes,16,opt,name=default_ipc_mode,json=defaultIpcMode,proto3" json:"default_ipc_mode,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
@ -169,6 +171,20 @@ func (m *LaunchRequest) GetNoPivotRoot() bool {
return false return false
} }
func (m *LaunchRequest) GetDefaultPidMode() string {
if m != nil {
return m.DefaultPidMode
}
return ""
}
func (m *LaunchRequest) GetDefaultIpcMode() string {
if m != nil {
return m.DefaultIpcMode
}
return ""
}
type LaunchResponse struct { type LaunchResponse struct {
Process *ProcessState `protobuf:"bytes,1,opt,name=process,proto3" json:"process,omitempty"` Process *ProcessState `protobuf:"bytes,1,opt,name=process,proto3" json:"process,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
@ -834,68 +850,70 @@ func init() {
} }
var fileDescriptor_66b85426380683f3 = []byte{ var fileDescriptor_66b85426380683f3 = []byte{
// 963 bytes of a gzipped FileDescriptorProto // 1003 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0xdd, 0x6f, 0x1b, 0x45, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0x5b, 0x6f, 0x1b, 0x45,
0x10, 0xef, 0xc5, 0xf1, 0xd7, 0xd8, 0x4e, 0xcc, 0x0a, 0x85, 0xab, 0x79, 0xa8, 0xb9, 0x07, 0x6a, 0x14, 0xee, 0xc6, 0xf1, 0xed, 0xd8, 0x8e, 0xcd, 0x08, 0x85, 0xad, 0x79, 0xa8, 0xd9, 0x07, 0x6a,
0x41, 0x39, 0x47, 0xe9, 0x17, 0x12, 0x12, 0x45, 0x24, 0x05, 0x21, 0x85, 0x28, 0x3a, 0x17, 0x2a, 0x41, 0x59, 0x47, 0xe9, 0x0d, 0x09, 0x89, 0x22, 0x92, 0x82, 0x2a, 0xa5, 0x91, 0xb5, 0x2e, 0x54,
0xf1, 0xc0, 0xb1, 0xbd, 0x5b, 0x7c, 0xab, 0xd8, 0xb7, 0xc7, 0xee, 0x9e, 0x1b, 0x24, 0x24, 0x78, 0xe2, 0x81, 0x65, 0xba, 0x3b, 0xb5, 0x47, 0xb1, 0x77, 0x96, 0x99, 0x59, 0x37, 0x48, 0x48, 0x3c,
0xe1, 0x3f, 0x00, 0x89, 0x3f, 0x17, 0xed, 0xd7, 0xc5, 0x4e, 0x4b, 0x75, 0x0e, 0xea, 0x93, 0x77, 0xf1, 0x0f, 0x40, 0xe2, 0x87, 0xf1, 0x83, 0xd0, 0xdc, 0x36, 0x76, 0x5a, 0xaa, 0x75, 0x11, 0x4f,
0xe6, 0xe6, 0x37, 0xbf, 0xd9, 0xd9, 0x99, 0x9f, 0xe1, 0x5e, 0xca, 0xe9, 0x8a, 0x70, 0x31, 0x15, 0x9e, 0x39, 0xfe, 0xbe, 0x73, 0x99, 0x73, 0xce, 0xb7, 0x70, 0x27, 0xe5, 0x74, 0x4d, 0xb8, 0x98,
0x19, 0xe6, 0x24, 0x9d, 0x92, 0x4b, 0x92, 0x94, 0x92, 0xf1, 0x69, 0xc1, 0x99, 0x64, 0x95, 0x19, 0x88, 0x05, 0xe6, 0x24, 0x9d, 0x90, 0x4b, 0x92, 0x14, 0x92, 0xf1, 0x49, 0xce, 0x99, 0x64, 0xe5,
0x6a, 0x13, 0x7d, 0x98, 0x61, 0x91, 0xd1, 0x84, 0xf1, 0x22, 0xcc, 0xd9, 0x12, 0xa7, 0x61, 0xb1, 0x35, 0xd4, 0x57, 0xf4, 0xf1, 0x02, 0x8b, 0x05, 0x4d, 0x18, 0xcf, 0xc3, 0x8c, 0xad, 0x70, 0x1a,
0x28, 0xe7, 0x34, 0x17, 0xe1, 0x66, 0xdc, 0xe8, 0xce, 0x9c, 0xb1, 0xf9, 0x82, 0x98, 0x24, 0x2f, 0xe6, 0xcb, 0x62, 0x4e, 0x33, 0x11, 0x6e, 0xe3, 0x86, 0xb7, 0xe6, 0x8c, 0xcd, 0x97, 0xc4, 0x38,
0xca, 0x9f, 0xa7, 0x92, 0x2e, 0x89, 0x90, 0x78, 0x59, 0xd8, 0x80, 0xc0, 0x02, 0xa7, 0x8e, 0xde, 0x79, 0x51, 0xbc, 0x9c, 0x48, 0xba, 0x22, 0x42, 0xe2, 0x55, 0x6e, 0x01, 0x81, 0x25, 0x4e, 0x5c,
0xd0, 0x19, 0xcb, 0xc4, 0x04, 0x7f, 0x34, 0x61, 0x70, 0x8a, 0xcb, 0x3c, 0xc9, 0x22, 0xf2, 0x4b, 0x78, 0x13, 0xce, 0xdc, 0x0c, 0x26, 0xf8, 0xbb, 0x0e, 0xbd, 0x33, 0x5c, 0x64, 0xc9, 0x22, 0x22,
0x49, 0x84, 0x44, 0x43, 0x68, 0x24, 0xcb, 0xd4, 0xf7, 0xc6, 0xde, 0xa4, 0x1b, 0xa9, 0x23, 0x42, 0x3f, 0x17, 0x44, 0x48, 0x34, 0x80, 0x5a, 0xb2, 0x4a, 0x7d, 0x6f, 0xe4, 0x8d, 0xdb, 0x91, 0x3a,
0xb0, 0x8b, 0xf9, 0x5c, 0xf8, 0x3b, 0xe3, 0xc6, 0xa4, 0x1b, 0xe9, 0x33, 0x3a, 0x83, 0x2e, 0x27, 0x22, 0x04, 0xfb, 0x98, 0xcf, 0x85, 0xbf, 0x37, 0xaa, 0x8d, 0xdb, 0x91, 0x3e, 0xa3, 0x73, 0x68,
0x82, 0x95, 0x3c, 0x21, 0xc2, 0x6f, 0x8c, 0xbd, 0x49, 0xef, 0xe8, 0x30, 0xfc, 0xaf, 0xc2, 0x2d, 0x73, 0x22, 0x58, 0xc1, 0x13, 0x22, 0xfc, 0xda, 0xc8, 0x1b, 0x77, 0x8e, 0x8f, 0xc2, 0x7f, 0x4b,
0xbf, 0xa1, 0x0c, 0x23, 0x87, 0x8b, 0xae, 0x52, 0xa0, 0x3b, 0xd0, 0x13, 0x32, 0x65, 0xa5, 0x8c, 0xdc, 0xc6, 0x37, 0x21, 0xc3, 0xc8, 0xf1, 0xa2, 0x2b, 0x17, 0xe8, 0x16, 0x74, 0x84, 0x4c, 0x59,
0x0b, 0x2c, 0x33, 0x7f, 0x57, 0xb3, 0x83, 0x71, 0x9d, 0x63, 0x99, 0xd9, 0x00, 0xc2, 0xb9, 0x09, 0x21, 0xe3, 0x1c, 0xcb, 0x85, 0xbf, 0xaf, 0xa3, 0x83, 0x31, 0x4d, 0xb1, 0x5c, 0x58, 0x00, 0xe1,
0x68, 0x56, 0x01, 0x84, 0x73, 0x1d, 0x30, 0x84, 0x06, 0xc9, 0x57, 0x7e, 0x4b, 0x17, 0xa9, 0x8e, 0xdc, 0x00, 0xea, 0x25, 0x80, 0x70, 0xae, 0x01, 0x03, 0xa8, 0x91, 0x6c, 0xed, 0x37, 0x74, 0x92,
0xaa, 0xee, 0x52, 0x10, 0xee, 0xb7, 0x75, 0xac, 0x3e, 0xa3, 0xdb, 0xd0, 0x91, 0x58, 0x5c, 0xc4, 0xea, 0xa8, 0xf2, 0x2e, 0x04, 0xe1, 0x7e, 0x53, 0x63, 0xf5, 0x19, 0xdd, 0x84, 0x96, 0xc4, 0xe2,
0x29, 0xe5, 0x7e, 0x47, 0xfb, 0xdb, 0xca, 0x3e, 0xa1, 0x1c, 0xdd, 0x85, 0x7d, 0x57, 0x4f, 0xbc, 0x22, 0x4e, 0x29, 0xf7, 0x5b, 0xda, 0xde, 0x54, 0xf7, 0x53, 0xca, 0xd1, 0x6d, 0xe8, 0xbb, 0x7c,
0xa0, 0x4b, 0x2a, 0x85, 0xdf, 0x1d, 0x7b, 0x93, 0x4e, 0xb4, 0xe7, 0xdc, 0xa7, 0xda, 0x8b, 0x0e, 0xe2, 0x25, 0x5d, 0x51, 0x29, 0xfc, 0xf6, 0xc8, 0x1b, 0xb7, 0xa2, 0x03, 0x67, 0x3e, 0xd3, 0x56,
0xe1, 0xdd, 0x17, 0x58, 0xd0, 0x24, 0x2e, 0x38, 0x4b, 0x88, 0x10, 0x71, 0x32, 0xe7, 0xac, 0x2c, 0x74, 0x04, 0xef, 0xbf, 0xc0, 0x82, 0x26, 0x71, 0xce, 0x59, 0x42, 0x84, 0x88, 0x93, 0x39, 0x67,
0x7c, 0xd0, 0xd1, 0x48, 0x7f, 0x3b, 0x37, 0x9f, 0x8e, 0xf5, 0x17, 0x74, 0x02, 0xad, 0x25, 0x2b, 0x45, 0xee, 0x83, 0x46, 0x23, 0xfd, 0xdf, 0xd4, 0xfc, 0x75, 0xa2, 0xff, 0x41, 0xa7, 0xd0, 0x58,
0x73, 0x29, 0xfc, 0xde, 0xb8, 0x31, 0xe9, 0x1d, 0xdd, 0xab, 0xd9, 0xaa, 0x6f, 0x15, 0x28, 0xb2, 0xb1, 0x22, 0x93, 0xc2, 0xef, 0x8c, 0x6a, 0xe3, 0xce, 0xf1, 0x9d, 0x8a, 0x4f, 0xf5, 0x54, 0x91,
0x58, 0xf4, 0x35, 0xb4, 0x53, 0xb2, 0xa2, 0xaa, 0xe3, 0x7d, 0x9d, 0xe6, 0x93, 0x9a, 0x69, 0x4e, 0x22, 0xcb, 0x45, 0xdf, 0x42, 0x33, 0x25, 0x6b, 0xaa, 0x5e, 0xbc, 0xab, 0xdd, 0x7c, 0x56, 0xd1,
0x34, 0x2a, 0x72, 0x68, 0x94, 0xc1, 0x3b, 0x39, 0x91, 0x2f, 0x19, 0xbf, 0x88, 0xa9, 0x60, 0x0b, 0xcd, 0xa9, 0x66, 0x45, 0x8e, 0x8d, 0x16, 0xf0, 0x5e, 0x46, 0xe4, 0x2b, 0xc6, 0x2f, 0x62, 0x2a,
0x2c, 0x29, 0xcb, 0xfd, 0x81, 0x7e, 0xc4, 0xcf, 0x6a, 0xa6, 0x3c, 0x33, 0xf8, 0x6f, 0x1c, 0x7c, 0xd8, 0x12, 0x4b, 0xca, 0x32, 0xbf, 0xa7, 0x9b, 0xf8, 0x45, 0x45, 0x97, 0xe7, 0x86, 0xff, 0xc4,
0x56, 0x90, 0x24, 0x1a, 0xe6, 0xd7, 0xbc, 0x28, 0x80, 0x41, 0xce, 0xe2, 0x82, 0xae, 0x98, 0x8c, 0xd1, 0x67, 0x39, 0x49, 0xa2, 0x41, 0x76, 0xcd, 0x8a, 0x02, 0xe8, 0x65, 0x2c, 0xce, 0xe9, 0x9a,
0x39, 0x63, 0xd2, 0xdf, 0xd3, 0x3d, 0xea, 0xe5, 0xec, 0x5c, 0xf9, 0x22, 0xc6, 0x64, 0xf0, 0x13, 0xc9, 0x98, 0x33, 0x26, 0xfd, 0x03, 0xfd, 0x46, 0x9d, 0x8c, 0x4d, 0x95, 0x2d, 0x62, 0x4c, 0xa2,
0xec, 0xb9, 0x09, 0x14, 0x05, 0xcb, 0x05, 0x41, 0x67, 0xd0, 0xb6, 0xad, 0xd5, 0x63, 0xd8, 0x3b, 0x31, 0x0c, 0x52, 0xf2, 0x12, 0x17, 0x4b, 0x19, 0xe7, 0x34, 0x8d, 0x57, 0x2c, 0x25, 0x7e, 0x5f,
0x7a, 0x10, 0xd6, 0xdb, 0x89, 0xd0, 0xb6, 0x7d, 0x26, 0xb1, 0x24, 0x91, 0x4b, 0x12, 0x0c, 0xa0, 0xb7, 0xe6, 0xc0, 0xda, 0xa7, 0x34, 0x7d, 0xca, 0x52, 0xb2, 0x89, 0xa4, 0x79, 0x62, 0x90, 0x83,
0xf7, 0x1c, 0x53, 0x69, 0x27, 0x3c, 0xf8, 0x11, 0xfa, 0xc6, 0x7c, 0x4b, 0x74, 0xa7, 0xb0, 0x3f, 0x2d, 0xe4, 0x93, 0x3c, 0x51, 0xc8, 0xe0, 0x27, 0x38, 0x70, 0x53, 0x2d, 0x72, 0x96, 0x09, 0x82,
0xcb, 0x4a, 0x99, 0xb2, 0x97, 0xb9, 0x5b, 0xaa, 0x03, 0x68, 0x09, 0x3a, 0xcf, 0xf1, 0xc2, 0xee, 0xce, 0xa1, 0x69, 0xdb, 0xa5, 0x47, 0xbb, 0x73, 0x7c, 0x2f, 0xac, 0xb6, 0x67, 0xa1, 0x6d, 0xe5,
0x95, 0xb5, 0xd0, 0x07, 0xd0, 0x9f, 0x73, 0x9c, 0x90, 0xb8, 0x20, 0x9c, 0xb2, 0xd4, 0xdf, 0x19, 0x4c, 0x62, 0x49, 0x22, 0xe7, 0x24, 0xe8, 0x41, 0xe7, 0x39, 0xa6, 0xd2, 0x6e, 0x4d, 0xf0, 0x23,
0x7b, 0x93, 0x46, 0xd4, 0xd3, 0xbe, 0x73, 0xed, 0x0a, 0x10, 0x0c, 0xaf, 0xb2, 0x99, 0x8a, 0x83, 0x74, 0xcd, 0xf5, 0x7f, 0x0a, 0x77, 0x06, 0xfd, 0xd9, 0xa2, 0x90, 0x29, 0x7b, 0x95, 0xb9, 0x45,
0x0c, 0x0e, 0xbe, 0x2b, 0x52, 0x45, 0x5a, 0xed, 0x92, 0x25, 0xda, 0xd8, 0x4b, 0xef, 0x7f, 0xef, 0x3d, 0x84, 0x86, 0xa0, 0xf3, 0x0c, 0x2f, 0xed, 0xae, 0xda, 0x1b, 0xfa, 0x08, 0xba, 0x73, 0x8e,
0x65, 0x70, 0x1b, 0xde, 0x7b, 0x85, 0xc9, 0x16, 0x31, 0x84, 0xbd, 0xef, 0x09, 0x17, 0x94, 0xb9, 0x13, 0x12, 0xe7, 0x84, 0x53, 0x96, 0xfa, 0x7b, 0x23, 0x6f, 0x5c, 0x8b, 0x3a, 0xda, 0x36, 0xd5,
0x5b, 0x06, 0x1f, 0xc3, 0x7e, 0xe5, 0xb1, 0xbd, 0xf5, 0xa1, 0xbd, 0x32, 0x2e, 0x7b, 0x73, 0x67, 0xa6, 0x00, 0xc1, 0xe0, 0xca, 0x9b, 0xc9, 0x38, 0x58, 0xc0, 0xe1, 0x77, 0x79, 0xaa, 0x82, 0x96,
0x06, 0x1f, 0x41, 0x5f, 0xf5, 0xad, 0xaa, 0x7c, 0x04, 0x1d, 0x9a, 0x4b, 0xc2, 0x57, 0xb6, 0x49, 0xfb, 0x69, 0x03, 0x6d, 0xed, 0xba, 0xf7, 0x9f, 0x77, 0x3d, 0xb8, 0x09, 0x1f, 0xbc, 0x16, 0xc9,
0x8d, 0xa8, 0xb2, 0x83, 0xe7, 0x30, 0xb0, 0xb1, 0x36, 0xed, 0x57, 0xd0, 0x14, 0xca, 0xb1, 0xe5, 0x26, 0x31, 0x80, 0x83, 0xef, 0x09, 0x17, 0x94, 0xb9, 0x2a, 0x83, 0x4f, 0xa1, 0x5f, 0x5a, 0xec,
0x15, 0x9f, 0x61, 0x71, 0x61, 0x12, 0x19, 0x78, 0x70, 0x17, 0x06, 0x33, 0xfd, 0x12, 0xaf, 0x7f, 0xdb, 0xfa, 0xd0, 0x5c, 0x1b, 0x93, 0xad, 0xdc, 0x5d, 0x83, 0x4f, 0xa0, 0xab, 0xde, 0xad, 0xcc,
0xa8, 0xa6, 0x7b, 0x28, 0x75, 0x59, 0x17, 0x68, 0xaf, 0x7f, 0x01, 0xbd, 0xa7, 0x97, 0x24, 0x71, 0x7c, 0x08, 0x2d, 0x9a, 0x49, 0xc2, 0xd7, 0xf6, 0x91, 0x6a, 0x51, 0x79, 0x0f, 0x9e, 0x43, 0xcf,
0xc0, 0x47, 0xd0, 0x49, 0x09, 0x4e, 0x17, 0x34, 0x27, 0xb6, 0xa8, 0x51, 0x68, 0x04, 0x3a, 0x74, 0x62, 0xad, 0xdb, 0x6f, 0xa0, 0x2e, 0x94, 0x61, 0xc7, 0x12, 0x9f, 0x61, 0x71, 0x61, 0x1c, 0x19,
0x02, 0x1d, 0x3e, 0x73, 0x02, 0x1d, 0x55, 0xb1, 0x4e, 0x6e, 0x77, 0x5e, 0x95, 0xdb, 0xc6, 0x95, 0x7a, 0x70, 0x1b, 0x7a, 0x33, 0xdd, 0x89, 0x37, 0x37, 0xaa, 0xee, 0x1a, 0xa5, 0x8a, 0x75, 0x40,
0xdc, 0x06, 0xc7, 0xd0, 0x37, 0x64, 0xf6, 0xfe, 0x07, 0xd0, 0x62, 0xa5, 0x2c, 0x4a, 0xa9, 0xb9, 0x5b, 0xfe, 0x05, 0x74, 0x1e, 0x5f, 0x92, 0xc4, 0x11, 0x1f, 0x40, 0x2b, 0x25, 0x38, 0x5d, 0xd2,
0xfa, 0x91, 0xb5, 0xd0, 0xfb, 0xd0, 0x25, 0x97, 0x54, 0xc6, 0x09, 0x4b, 0x89, 0xce, 0xd9, 0x8c, 0x8c, 0xd8, 0xa4, 0x86, 0xa1, 0x11, 0xfd, 0xd0, 0x89, 0x7e, 0xf8, 0xcc, 0x89, 0x7e, 0x54, 0x62,
0x3a, 0xca, 0x71, 0xcc, 0x52, 0x12, 0xfc, 0xe9, 0x41, 0x7f, 0x7d, 0x62, 0x15, 0x77, 0x41, 0x53, 0x9d, 0x84, 0xef, 0xbd, 0x2e, 0xe1, 0xb5, 0x2b, 0x09, 0x0f, 0x4e, 0xa0, 0x6b, 0x82, 0xd9, 0xfa,
0x7b, 0x53, 0x75, 0x7c, 0x23, 0x7e, 0xad, 0x37, 0x8d, 0xf5, 0xde, 0xa0, 0x10, 0x76, 0xd5, 0x5f, 0x0f, 0xa1, 0xc1, 0x0a, 0x99, 0x17, 0x52, 0xc7, 0xea, 0x46, 0xf6, 0x86, 0x3e, 0x84, 0x36, 0xb9,
0x8f, 0x16, 0xed, 0x37, 0x5f, 0x5b, 0xc7, 0x1d, 0xfd, 0xdd, 0x85, 0xce, 0x53, 0xbb, 0x48, 0xe8, 0xa4, 0x32, 0x4e, 0xd4, 0xba, 0xed, 0xe9, 0x0a, 0x5a, 0xca, 0x70, 0xa2, 0x16, 0xed, 0x77, 0x0f,
0x57, 0x68, 0x99, 0xed, 0x47, 0x0f, 0xeb, 0x6e, 0xdd, 0xc6, 0xff, 0xd5, 0xe8, 0xd1, 0xb6, 0x30, 0xba, 0x9b, 0x13, 0xab, 0x62, 0xe7, 0x34, 0xb5, 0x95, 0xaa, 0xe3, 0x5b, 0xf9, 0x1b, 0x6f, 0x53,
0xfb, 0x7e, 0xb7, 0x90, 0x80, 0x5d, 0xa5, 0x03, 0xe8, 0x7e, 0xdd, 0x0c, 0x6b, 0x22, 0x32, 0x7a, 0xdb, 0x7c, 0x1b, 0x14, 0xc2, 0xbe, 0xfa, 0x9c, 0xe9, 0x0f, 0xc1, 0xdb, 0xcb, 0xd6, 0xb8, 0xe3,
0xb0, 0x1d, 0xa8, 0x22, 0xfd, 0x1d, 0x3a, 0x6e, 0x9d, 0xd1, 0xe3, 0xba, 0x39, 0xae, 0xc9, 0xc9, 0x3f, 0xdb, 0xd0, 0x7a, 0x6c, 0x17, 0x09, 0xfd, 0x02, 0x0d, 0xb3, 0xfd, 0xe8, 0x7e, 0xd5, 0xad,
0xe8, 0xd3, 0xed, 0x81, 0x55, 0x01, 0x7f, 0x79, 0xb0, 0x7f, 0x6d, 0xa5, 0xd1, 0xe7, 0x75, 0xf3, 0xdb, 0xfa, 0x06, 0x0e, 0x1f, 0xec, 0x4a, 0xb3, 0xfd, 0xbb, 0x81, 0x04, 0xec, 0x2b, 0x1d, 0x40,
0xbd, 0x5e, 0x75, 0x46, 0x4f, 0x6e, 0x8c, 0xaf, 0xca, 0xfa, 0x0d, 0xda, 0x56, 0x3b, 0x50, 0xed, 0x77, 0xab, 0x7a, 0xd8, 0x10, 0x91, 0xe1, 0xbd, 0xdd, 0x48, 0x65, 0xd0, 0xdf, 0xa0, 0xe5, 0xd6,
0x17, 0xdd, 0x94, 0x9f, 0xd1, 0xe3, 0xad, 0x71, 0x15, 0xfb, 0x25, 0x34, 0xb5, 0x2e, 0xa0, 0xda, 0x19, 0x3d, 0xac, 0xea, 0xe3, 0x9a, 0x9c, 0x0c, 0x3f, 0xdf, 0x9d, 0x58, 0x26, 0xf0, 0x87, 0x07,
0xcf, 0xba, 0xae, 0x5d, 0xa3, 0x87, 0x5b, 0xa2, 0x1c, 0xef, 0xa1, 0xa7, 0xe6, 0xdf, 0x08, 0x4b, 0xfd, 0x6b, 0x2b, 0x8d, 0xbe, 0xac, 0xea, 0xef, 0xcd, 0xaa, 0x33, 0x7c, 0xf4, 0xce, 0xfc, 0x32,
0xfd, 0xf9, 0xdf, 0x50, 0xac, 0xfa, 0xf3, 0x7f, 0x4d, 0xbf, 0xf4, 0xfc, 0xab, 0x35, 0xac, 0x3f, 0xad, 0x5f, 0xa1, 0x69, 0xb5, 0x03, 0x55, 0xee, 0xe8, 0xb6, 0xfc, 0x0c, 0x1f, 0xee, 0xcc, 0x2b,
0xff, 0x6b, 0x7a, 0x57, 0x7f, 0xfe, 0xd7, 0x75, 0x2b, 0xb8, 0x85, 0xfe, 0xf1, 0x60, 0xa0, 0x5c, 0xa3, 0x5f, 0x42, 0x5d, 0xeb, 0x02, 0xaa, 0xdc, 0xd6, 0x4d, 0xed, 0x1a, 0xde, 0xdf, 0x91, 0xe5,
0x33, 0xc9, 0x09, 0x5e, 0xd2, 0x7c, 0x8e, 0x9e, 0xd4, 0x14, 0x6f, 0x85, 0x32, 0x02, 0x6e, 0x91, 0xe2, 0x1e, 0x79, 0x6a, 0xfe, 0x8d, 0xb0, 0x54, 0x9f, 0xff, 0x2d, 0xc5, 0xaa, 0x3e, 0xff, 0xd7,
0xae, 0x94, 0x2f, 0x6e, 0x9e, 0xc0, 0x95, 0x35, 0xf1, 0x0e, 0xbd, 0x2f, 0xdb, 0x3f, 0x34, 0x8d, 0xf4, 0x4b, 0xcf, 0xbf, 0x5a, 0xc3, 0xea, 0xf3, 0xbf, 0xa1, 0x77, 0xd5, 0xe7, 0x7f, 0x53, 0xb7,
0x66, 0xb5, 0xf4, 0xcf, 0xfd, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x7a, 0x58, 0x36, 0xd5, 0xb8, 0x82, 0x1b, 0xe8, 0x2f, 0x0f, 0x7a, 0xca, 0x34, 0x93, 0x9c, 0xe0, 0x15, 0xcd, 0xe6, 0xe8, 0x51,
0x0b, 0x00, 0x00, 0x45, 0xf1, 0x56, 0x2c, 0x23, 0xe0, 0x96, 0xe9, 0x52, 0xf9, 0xea, 0xdd, 0x1d, 0xb8, 0xb4, 0xc6,
0xde, 0x91, 0xf7, 0x75, 0xf3, 0x87, 0xba, 0xd1, 0xac, 0x86, 0xfe, 0xb9, 0xfb, 0x4f, 0x00, 0x00,
0x00, 0xff, 0xff, 0x4a, 0xf7, 0x34, 0xf9, 0x0c, 0x0c, 0x00, 0x00,
} }
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.

View file

@ -42,6 +42,8 @@ message LaunchRequest {
repeated hashicorp.nomad.plugins.drivers.proto.Device devices = 12; repeated hashicorp.nomad.plugins.drivers.proto.Device devices = 12;
hashicorp.nomad.plugins.drivers.proto.NetworkIsolationSpec network_isolation = 13; hashicorp.nomad.plugins.drivers.proto.NetworkIsolationSpec network_isolation = 13;
bool no_pivot_root = 14; bool no_pivot_root = 14;
string default_pid_mode = 15;
string default_ipc_mode = 16;
} }
message LaunchResponse { message LaunchResponse {

View file

@ -35,6 +35,8 @@ func (s *grpcExecutorServer) Launch(ctx context.Context, req *proto.LaunchReques
Mounts: drivers.MountsFromProto(req.Mounts), Mounts: drivers.MountsFromProto(req.Mounts),
Devices: drivers.DevicesFromProto(req.Devices), Devices: drivers.DevicesFromProto(req.Devices),
NetworkIsolation: drivers.NetworkIsolationSpecFromProto(req.NetworkIsolation), NetworkIsolation: drivers.NetworkIsolationSpecFromProto(req.NetworkIsolation),
DefaultModePID: req.DefaultPidMode,
DefaultModeIPC: req.DefaultIpcMode,
}) })
if err != nil { if err != nil {

View file

@ -107,7 +107,21 @@ This also applies for running Nomad in -dev mode.
## Plugin Options ## Plugin Options
- `no_pivot_root` - Defaults to `false`. When `true`, the driver uses `chroot` - `default_pid_mode` `(string: optional)` - Defaults to `"private"`. Set to
`"private"` to enable namespace isolation for tasks by default, or `"host"` to
disable isolation.
!> **Warning:** If set to `"host"`, other processes running as the same user will
be able to access sensitive process information like environment variables.
- `default_ipc_mode` `(string: optional)` - Defaults to `"private"`. Set to
`"private"` to enable inter-process-communication isolation for tasks by default,
or `"host"` to disable isolation.
!> **Warning:** If set to `"host"`, other processes running as the same user will be
able to make use of IPC features, like sending unexpected posix signals.
- `no_pivot_root` `(bool: optional)` - Defaults to `false`. When `true`, the driver uses `chroot`
for file system isolation without `pivot_root`. This is useful for systems for file system isolation without `pivot_root`. This is useful for systems
where the root is on a ramdisk. where the root is on a ramdisk.

View file

@ -109,6 +109,22 @@ The `java` driver implements the following [capabilities](/docs/internals/plugin
| network isolation | host, group | | network isolation | host, group |
| volume mounting | none, all (only for linux) | | volume mounting | none, all (only for linux) |
## Plugin Options
- `default_pid_mode` `(string: optional)` - Defaults to `"private"`. Set to
`"private"` to enable namespace isolation for tasks by default, or `"host"` to
disable isolation.
!> **Warning:** If set to `"host"`, other processes running as the same user will
be able to access sensitive process information like environment variables.
- `default_ipc_mode` `(string: optional)` - Defaults to `"private"`. Set to
`"private"` to enable inter-process-communication isolation for tasks by default,
or `"host"` to disable isolation.
!> **Warning:** If set to `"host"`, other processes running as the same user will be
able to make use of IPC features, like sending unexpected posix signals.
## Client Requirements ## Client Requirements
The `java` driver requires Java to be installed and in your system's `$PATH`. On The `java` driver requires Java to be installed and in your system's `$PATH`. On