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

Add config field to specify chroot mapping for exec driver #1518

Merged
merged 6 commits into from
Aug 11, 2016
Merged
Show file tree
Hide file tree
Changes from 2 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
4 changes: 4 additions & 0 deletions client/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ type Config struct {
// devices and IPs.
GloballyReservedPorts []int

// A mapping of directories on the host OS to attempt to embed inside each
// task's chroot.
ChrootEnv map[string]string

// Options provides arbitrary key-value configuration for nomad internals,
// like fingerprinters and drivers. The format is:
//
Expand Down
1 change: 1 addition & 0 deletions client/driver/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ func (d *ExecDriver) Start(ctx *ExecContext, task *structs.Task) (DriverHandle,
Cmd: command,
Args: driverConfig.Args,
FSIsolation: true,
ChrootEnv: d.config.ChrootEnv,
ResourceLimits: true,
User: getExecutorUser(task),
}, executorCtx)
Expand Down
4 changes: 4 additions & 0 deletions client/driver/executor/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ type ExecCommand struct {
// FSIsolation determines whether the command would be run in a chroot.
FSIsolation bool

// A mapping of directories on the host OS to attempt to embed inside each
// task's chroot.
ChrootEnv map[string]string
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move this field to ExecutorContext


// User is the user which the executor uses to run the command.
User string

Expand Down
7 changes: 6 additions & 1 deletion client/driver/executor/executor_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,12 @@ func (e *UniversalExecutor) configureChroot() error {
return err
}

if err := allocDir.Embed(e.ctx.Task.Name, chrootEnv); err != nil {
chroot := chrootEnv
if e.command.ChrootEnv != nil && len(e.command.ChrootEnv) > 0 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if len(e.command.ChrootEnv) > 0 since len of nil maps are 0

chroot = e.command.ChrootEnv
}

if err := allocDir.Embed(e.ctx.Task.Name, chroot); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a test for this as well? It would be nice if the test asserts that only the specified top level directories specified by the operator are present in the chroot.

return err
}

Expand Down
1 change: 1 addition & 0 deletions client/driver/java.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ func (d *JavaDriver) Start(ctx *ExecContext, task *structs.Task) (DriverHandle,
Cmd: absPath,
Args: args,
FSIsolation: true,
ChrootEnv: d.config.ChrootEnv,
ResourceLimits: true,
User: getExecutorUser(task),
}, executorCtx)
Expand Down
1 change: 1 addition & 0 deletions command/agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ func (a *Agent) clientConfig() (*clientconfig.Config, error) {
if a.config.Client.NetworkInterface != "" {
conf.NetworkInterface = a.config.Client.NetworkInterface
}
conf.ChrootEnv = a.config.Client.ChrootEnv
conf.Options = a.config.Client.Options
// Logging deprecation messages about consul related configuration in client
// options
Expand Down
12 changes: 12 additions & 0 deletions command/agent/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,10 @@ type ClientConfig struct {
// Metadata associated with the node
Meta map[string]string `mapstructure:"meta"`

// A mapping of directories on the host OS to attempt to embed inside each
// task's chroot.
ChrootEnv map[string]string `mapstructure:"chroot_env"`

// Interface to use for network fingerprinting
NetworkInterface string `mapstructure:"network_interface"`

Expand Down Expand Up @@ -718,6 +722,14 @@ func (a *ClientConfig) Merge(b *ClientConfig) *ClientConfig {
result.Meta[k] = v
}

// Add the chroot_env map values
if result.ChrootEnv == nil {
result.ChrootEnv = make(map[string]string)
}
for k, v := range b.ChrootEnv {
result.ChrootEnv[k] = v
}

return &result
}

Expand Down
16 changes: 16 additions & 0 deletions command/agent/config_parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ func parseClient(result **ClientConfig, list *ast.ObjectList) error {
"node_class",
"options",
"meta",
"chroot_env",
"network_interface",
"network_speed",
"max_kill_timeout",
Expand All @@ -334,6 +335,7 @@ func parseClient(result **ClientConfig, list *ast.ObjectList) error {

delete(m, "options")
delete(m, "meta")
delete(m, "chroot_env")
delete(m, "reserved")
delete(m, "stats")

Expand Down Expand Up @@ -370,6 +372,20 @@ func parseClient(result **ClientConfig, list *ast.ObjectList) error {
}
}

// Parse out chroot_env fields. These are in HCL as a list so we need to
// iterate over them and merge them.
if chrootEnvO := listVal.Filter("chroot_env"); len(chrootEnvO.Items) > 0 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a test for this

for _, o := range chrootEnvO.Elem().Items {
var m map[string]interface{}
if err := hcl.DecodeObject(&m, o.Val); err != nil {
return err
}
if err := mapstructure.WeakDecode(m, &config.ChrootEnv); err != nil {
return err
}
}
}

// Parse reserved config
if o := listVal.Filter("reserved"); len(o.Items) > 0 {
if err := parseReserved(&config.Reserved, o); err != nil {
Expand Down