Merge pull request #816 from hashicorp/b-java-linux

Enabling cgroups and chroot on linux
This commit is contained in:
Diptanu Choudhury
2016-02-18 16:18:49 -08:00
2 changed files with 30 additions and 4 deletions

View File

@@ -61,8 +61,8 @@ func NewJavaDriver(ctx *DriverContext) Driver {
}
func (d *JavaDriver) Fingerprint(cfg *config.Config, node *structs.Node) (bool, error) {
// Only enable if we are root when running on non-windows systems.
if runtime.GOOS == "linux" && syscall.Geteuid() != 0 {
// Only enable if we are root and cgroups are mounted when running on linux systems.
if runtime.GOOS == "linux" && (syscall.Geteuid() != 0 || !d.cgroupsMounted(node)) {
d.logger.Printf("[DEBUG] driver.java: must run as root user on linux, disabling")
return false, nil
}
@@ -167,9 +167,12 @@ func (d *JavaDriver) Start(ctx *ExecContext, task *structs.Task) (DriverHandle,
AllocDir: ctx.AllocDir,
TaskName: task.Name,
TaskResources: task.Resources,
UnprivilegedUser: true,
LogConfig: task.LogConfig,
FSIsolation: true,
UnprivilegedUser: true,
ResourceLimits: true,
}
ps, err := exec.LaunchCmd(&executor.ExecCommand{Cmd: "java", Args: args}, executorCtx)
if err != nil {
pluginClient.Kill()
@@ -195,6 +198,13 @@ func (d *JavaDriver) Start(ctx *ExecContext, task *structs.Task) (DriverHandle,
return h, nil
}
// cgroupsMounted returns true if the cgroups are mounted on a system otherwise
// returns false
func (d *JavaDriver) cgroupsMounted(node *structs.Node) bool {
_, ok := node.Attributes["unique.cgroup.mountpoint"]
return ok
}
type javaId struct {
KillTimeout time.Duration
PluginConfig *PluginReattachConfig

View File

@@ -1,10 +1,13 @@
package driver
import (
"os"
"os/exec"
"path/filepath"
"testing"
"time"
"github.com/hashicorp/nomad/client/allocdir"
"github.com/hashicorp/nomad/client/config"
"github.com/hashicorp/nomad/nomad/structs"
"github.com/hashicorp/nomad/testutil"
@@ -25,7 +28,9 @@ func TestJavaDriver_Fingerprint(t *testing.T) {
driverCtx, _ := testDriverContexts(&structs.Task{Name: "foo"})
d := NewJavaDriver(driverCtx)
node := &structs.Node{
Attributes: make(map[string]string),
Attributes: map[string]string{
"unique.cgroup.mountpoint": "/sys/fs/cgroups",
},
}
apply, err := d.Fingerprint(&config.Config{}, node)
if err != nil {
@@ -137,6 +142,17 @@ func TestJavaDriver_Start_Wait(t *testing.T) {
break
}
// Get the stdout of the process and assrt that it's not empty
taskDir := execCtx.AllocDir.TaskDirs["demo-app"]
stdout := filepath.Join(taskDir, allocdir.TaskLocal, "demo-app.stdout.0")
fInfo, err := os.Stat(stdout)
if err != nil {
t.Fatalf("failed to get stdout of process: %v", err)
}
if fInfo.Size() == 0 {
t.Fatalf("stdout of process is empty")
}
// need to kill long lived process
err = handle.Kill()
if err != nil {