Skip to content

Commit

Permalink
client: support no_pivot_root in exec driver configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
th0m committed Feb 14, 2020
1 parent af59190 commit e645242
Show file tree
Hide file tree
Showing 9 changed files with 164 additions and 78 deletions.
26 changes: 25 additions & 1 deletion drivers/exec/driver.go
Expand Up @@ -59,7 +59,12 @@ var (
}

// configSpec is the hcl specification returned by the ConfigSchema RPC
configSpec = hclspec.NewObject(map[string]*hclspec.Spec{})
configSpec = hclspec.NewObject(map[string]*hclspec.Spec{
"no_pivot_root": hclspec.NewDefault(
hclspec.NewAttr("no_pivot_root", "bool", false),
hclspec.NewLiteral("false"),
),
})

// taskConfigSpec is the hcl specification for the driver config section of
// a task within a job. It is returned in the TaskConfigSchema RPC
Expand Down Expand Up @@ -88,6 +93,9 @@ type Driver struct {
// event can be broadcast to all callers
eventer *eventer.Eventer

// config is the driver configuration set by the SetConfig RPC
config Config

// nomadConfig is the client config from nomad
nomadConfig *base.ClientDriverConfig

Expand All @@ -111,6 +119,13 @@ type Driver struct {
fingerprintLock sync.Mutex
}

// Config is the driver configuration set by the SetConfig RPC call
type Config struct {
// NoPivotRoot disables the use of pivot_root, useful when the root partition
// is on ramdisk
NoPivotRoot bool `codec:"no_pivot_root"`
}

// TaskConfig is the driver configuration of a task within a job
type TaskConfig struct {
Command string `codec:"command"`
Expand Down Expand Up @@ -171,6 +186,14 @@ func (d *Driver) ConfigSchema() (*hclspec.Spec, error) {
}

func (d *Driver) SetConfig(cfg *base.Config) error {
var config Config
if len(cfg.PluginConfig) != 0 {
if err := base.MsgPackDecode(cfg.PluginConfig, &config); err != nil {
return err
}
}

d.config = config
if cfg != nil && cfg.AgentConfig != nil {
d.nomadConfig = cfg.AgentConfig.Driver
}
Expand Down Expand Up @@ -352,6 +375,7 @@ func (d *Driver) StartTask(cfg *drivers.TaskConfig) (*drivers.TaskHandle, *drive
Env: cfg.EnvList(),
User: user,
ResourceLimits: true,
NoPivotRoot: d.config.NoPivotRoot,
Resources: cfg.Resources,
TaskDir: cfg.TaskDir().Dir,
StdoutPath: cfg.StdoutPath,
Expand Down
34 changes: 34 additions & 0 deletions drivers/exec/driver_test.go
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/hashicorp/nomad/helper/testtask"
"github.com/hashicorp/nomad/helper/uuid"
"github.com/hashicorp/nomad/nomad/structs"
basePlug "github.com/hashicorp/nomad/plugins/base"
"github.com/hashicorp/nomad/plugins/drivers"
dtestutil "github.com/hashicorp/nomad/plugins/drivers/testutils"
"github.com/hashicorp/nomad/testutil"
Expand Down Expand Up @@ -671,3 +672,36 @@ config {

require.EqualValues(t, expected, tc)
}

func TestExecDriver_NoPivotRoot(t *testing.T) {
t.Parallel()
require := require.New(t)
ctestutils.ExecCompatible(t)

d := NewExecDriver(testlog.HCLogger(t))
harness := dtestutil.NewDriverHarness(t, d)

config := &Config{NoPivotRoot: true}
var data []byte
require.NoError(basePlug.MsgPackEncode(&data, config))
bconfig := &basePlug.Config{PluginConfig: data}
require.NoError(harness.SetConfig(bconfig))

task := &drivers.TaskConfig{
ID: uuid.Generate(),
Name: "sleep",
Resources: testResources,
}
cleanup := harness.MkAllocDir(task, false)
defer cleanup()

tc := &TaskConfig{
Command: "/bin/sleep",
Args: []string{"100"},
}
require.NoError(task.EncodeConcreteDriverConfig(&tc))

handle, _, err := harness.StartTask(task)
require.NoError(err)
require.NotNil(handle)
}
1 change: 1 addition & 0 deletions drivers/shared/executor/client.go
Expand Up @@ -41,6 +41,7 @@ func (c *grpcExecutorClient) Launch(cmd *ExecCommand) (*ProcessState, error) {
TaskDir: cmd.TaskDir,
ResourceLimits: cmd.ResourceLimits,
BasicProcessCgroup: cmd.BasicProcessCgroup,
NoPivotRoot: cmd.NoPivotRoot,
Mounts: drivers.MountsToProto(cmd.Mounts),
Devices: drivers.DevicesToProto(cmd.Devices),
NetworkIsolation: drivers.NetworkIsolationSpecToProto(cmd.NetworkIsolation),
Expand Down
5 changes: 5 additions & 0 deletions drivers/shared/executor/executor.go
Expand Up @@ -121,6 +121,11 @@ type ExecCommand struct {
// Using the cgroup does allow more precise cleanup of processes.
BasicProcessCgroup bool

// NoPivotRoot disables using pivot_root for isolation, useful when the root
// partition is on a ramdisk which does not support pivot_root,
// see man 2 pivot_root
NoPivotRoot bool

// Mounts are the host paths to be be made available inside rootfs
Mounts []*drivers.MountConfig

Expand Down
3 changes: 3 additions & 0 deletions drivers/shared/executor/executor_linux.go
Expand Up @@ -573,6 +573,9 @@ func configureIsolation(cfg *lconfigs.Config, command *ExecCommand) error {
// set the new root directory for the container
cfg.Rootfs = command.TaskDir

// disable pivot_root if set in the driver's configuration
cfg.NoPivotRoot = command.NoPivotRoot

// launch with mount namespace
cfg.Namespaces = lconfigs.Namespaces{
{Type: lconfigs.NEWNS},
Expand Down

0 comments on commit e645242

Please sign in to comment.