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

client: support no_pivot_root in exec driver configuration #7149

Merged
merged 1 commit into from
Feb 19, 2020
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
26 changes: 25 additions & 1 deletion drivers/exec/driver.go
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Loading