302 lines
7.9 KiB
Go
302 lines
7.9 KiB
Go
package isolation
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/hashicorp/nomad/api"
|
|
"github.com/hashicorp/nomad/e2e/e2eutil"
|
|
"github.com/hashicorp/nomad/e2e/framework"
|
|
"github.com/hashicorp/nomad/helper/uuid"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
type IsolationTest struct {
|
|
framework.TC
|
|
|
|
jobIDs []string
|
|
}
|
|
|
|
func init() {
|
|
framework.AddSuites(&framework.TestSuite{
|
|
Component: "Isolation",
|
|
CanRunLocal: true,
|
|
Cases: []framework.TestCase{
|
|
new(IsolationTest),
|
|
},
|
|
})
|
|
}
|
|
|
|
func (tc *IsolationTest) BeforeAll(f *framework.F) {
|
|
t := f.T()
|
|
e2eutil.WaitForLeader(t, tc.Nomad())
|
|
e2eutil.WaitForNodesReady(t, tc.Nomad(), 1)
|
|
}
|
|
|
|
func (tc *IsolationTest) TestIsolation_ExecDriver_PIDNamespacing(f *framework.F) {
|
|
t := f.T()
|
|
|
|
clientNodes, err := e2eutil.ListLinuxClientNodes(tc.Nomad())
|
|
require.Nil(t, err)
|
|
|
|
if len(clientNodes) == 0 {
|
|
t.Skip("no Linux clients")
|
|
}
|
|
|
|
jobID := "isolation-pid-namespace-" + uuid.Short()
|
|
file := "isolation/input/exec.nomad"
|
|
allocs := e2eutil.RegisterAndWaitForAllocs(t, tc.Nomad(), file, jobID, "")
|
|
require.Equal(t, len(allocs), 1, fmt.Sprintf("failed to register %s", jobID))
|
|
|
|
tc.jobIDs = append(tc.jobIDs, jobID)
|
|
defer func() {
|
|
_, _, err = tc.Nomad().Jobs().Deregister(jobID, true, nil)
|
|
require.NoError(t, err)
|
|
}()
|
|
|
|
allocID := allocs[0].ID
|
|
e2eutil.WaitForAllocStopped(t, tc.Nomad(), allocID)
|
|
|
|
out, err := e2eutil.AllocLogs(allocID, e2eutil.LogsStdOut)
|
|
require.NoError(t, err, fmt.Sprintf("could not get logs for alloc %s", allocID))
|
|
|
|
require.Contains(t, out, "my pid is 1\n")
|
|
}
|
|
|
|
func (tc *IsolationTest) TestIsolation_ExecDriver_PIDNamespacing_host(f *framework.F) {
|
|
t := f.T()
|
|
|
|
clientNodes, err := e2eutil.ListLinuxClientNodes(tc.Nomad())
|
|
require.Nil(t, err)
|
|
|
|
if len(clientNodes) == 0 {
|
|
t.Skip("no Linux clients")
|
|
}
|
|
|
|
jobID := "isolation-pid-namespace-" + uuid.Short()
|
|
file := "isolation/input/exec_host.nomad"
|
|
allocs := e2eutil.RegisterAndWaitForAllocs(t, tc.Nomad(), file, jobID, "")
|
|
require.Equal(t, len(allocs), 1, fmt.Sprintf("failed to register %s", jobID))
|
|
|
|
tc.jobIDs = append(tc.jobIDs, jobID)
|
|
defer func() {
|
|
_, _, err = tc.Nomad().Jobs().Deregister(jobID, true, nil)
|
|
require.NoError(t, err)
|
|
}()
|
|
|
|
allocID := allocs[0].ID
|
|
e2eutil.WaitForAllocStopped(t, tc.Nomad(), allocID)
|
|
|
|
out, err := e2eutil.AllocLogs(allocID, e2eutil.LogsStdOut)
|
|
require.NoError(t, err, fmt.Sprintf("could not get logs for alloc %s", allocID))
|
|
|
|
require.NotContains(t, out, "my pid is 1\n")
|
|
}
|
|
|
|
func (tc *IsolationTest) TestIsolation_ExecDriver_PIDNamespacing_AllocExec(f *framework.F) {
|
|
t := f.T()
|
|
|
|
clientNodes, err := e2eutil.ListLinuxClientNodes(tc.Nomad())
|
|
require.Nil(t, err)
|
|
|
|
if len(clientNodes) == 0 {
|
|
t.Skip("no Linux clients")
|
|
}
|
|
|
|
jobID := "isolation-pid-namespace-" + uuid.Short()
|
|
file := "isolation/input/alloc_exec.nomad"
|
|
allocs := e2eutil.RegisterAndWaitForAllocs(t, tc.Nomad(), file, jobID, "")
|
|
require.Equal(t, len(allocs), 1, fmt.Sprintf("failed to register %s", jobID))
|
|
|
|
defer func() {
|
|
_, _, err = tc.Nomad().Jobs().Deregister(jobID, true, nil)
|
|
require.NoError(t, err)
|
|
}()
|
|
|
|
allocID := allocs[0].ID
|
|
e2eutil.WaitForAllocRunning(t, tc.Nomad(), allocID)
|
|
|
|
alloc, _, err := tc.Nomad().Allocations().Info(allocID, nil)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, alloc)
|
|
|
|
resizeCh := make(chan api.TerminalSize)
|
|
var tty bool
|
|
|
|
ctx, cancelFn := context.WithTimeout(context.Background(), 15*time.Second)
|
|
defer cancelFn()
|
|
|
|
var stdout, stderr bytes.Buffer
|
|
|
|
exitCode, err := tc.Nomad().Allocations().Exec(
|
|
ctx,
|
|
alloc,
|
|
"main",
|
|
tty,
|
|
[]string{"ps", "ax"},
|
|
bytes.NewReader([]byte("")),
|
|
&stdout,
|
|
&stderr,
|
|
resizeCh,
|
|
nil,
|
|
)
|
|
require.NoError(t, err)
|
|
require.Equal(t, 0, exitCode)
|
|
|
|
lines := strings.Split(strings.TrimSpace(stdout.String()), "\n")
|
|
// header, sleep process, ps ax process are the only output lines expected
|
|
require.Len(t, lines, 3)
|
|
}
|
|
|
|
func (tc *IsolationTest) TestIsolation_JavaDriver_PIDNamespacing(f *framework.F) {
|
|
t := f.T()
|
|
|
|
clientNodes, err := e2eutil.ListLinuxClientNodes(tc.Nomad())
|
|
require.Nil(t, err)
|
|
|
|
if len(clientNodes) == 0 {
|
|
t.Skip("no Linux clients")
|
|
}
|
|
|
|
jobID := "isolation-pid-namespace-" + uuid.Short()
|
|
file := "isolation/input/java.nomad"
|
|
allocs := e2eutil.RegisterAndWaitForAllocs(t, tc.Nomad(), file, jobID, "")
|
|
require.Equal(t, len(allocs), 1, fmt.Sprintf("failed to register %s", jobID))
|
|
|
|
tc.jobIDs = append(tc.jobIDs, jobID)
|
|
defer func() {
|
|
_, _, err = tc.Nomad().Jobs().Deregister(jobID, true, nil)
|
|
require.NoError(t, err)
|
|
}()
|
|
|
|
allocID := allocs[0].ID
|
|
e2eutil.WaitForAllocStopped(t, tc.Nomad(), allocID)
|
|
|
|
out, err := e2eutil.AllocTaskLogs(allocID, "pid", e2eutil.LogsStdOut)
|
|
require.NoError(t, err, fmt.Sprintf("could not get logs for alloc %s", allocID))
|
|
|
|
require.Contains(t, out, "my pid is 1\n")
|
|
}
|
|
|
|
func (tc *IsolationTest) TestIsolation_JavaDriver_PIDNamespacing_host(f *framework.F) {
|
|
t := f.T()
|
|
|
|
clientNodes, err := e2eutil.ListLinuxClientNodes(tc.Nomad())
|
|
require.Nil(t, err)
|
|
|
|
if len(clientNodes) == 0 {
|
|
t.Skip("no Linux clients")
|
|
}
|
|
|
|
jobID := "isolation-pid-namespace-" + uuid.Short()
|
|
file := "isolation/input/java_host.nomad"
|
|
allocs := e2eutil.RegisterAndWaitForAllocs(t, tc.Nomad(), file, jobID, "")
|
|
require.Equal(t, len(allocs), 1, fmt.Sprintf("failed to register %s", jobID))
|
|
|
|
tc.jobIDs = append(tc.jobIDs, jobID)
|
|
defer func() {
|
|
_, _, err = tc.Nomad().Jobs().Deregister(jobID, true, nil)
|
|
require.NoError(t, err)
|
|
}()
|
|
|
|
allocID := allocs[0].ID
|
|
e2eutil.WaitForAllocStopped(t, tc.Nomad(), allocID)
|
|
|
|
out, err := e2eutil.AllocTaskLogs(allocID, "pid", e2eutil.LogsStdOut)
|
|
require.NoError(t, err, fmt.Sprintf("could not get logs for alloc %s", allocID))
|
|
|
|
require.NotContains(t, out, "my pid is 1\n")
|
|
}
|
|
|
|
func (tc *IsolationTest) TestIsolation_JavaDriver_PIDNamespacing_AllocExec(f *framework.F) {
|
|
t := f.T()
|
|
|
|
clientNodes, err := e2eutil.ListLinuxClientNodes(tc.Nomad())
|
|
require.Nil(t, err)
|
|
|
|
if len(clientNodes) == 0 {
|
|
t.Skip("no Linux clients")
|
|
}
|
|
|
|
jobID := "isolation-pid-namespace-" + uuid.Short()
|
|
file := "isolation/input/alloc_exec_java.nomad"
|
|
allocs := e2eutil.RegisterAndWaitForAllocs(t, tc.Nomad(), file, jobID, "")
|
|
require.Equal(t, len(allocs), 1, fmt.Sprintf("failed to register %s", jobID))
|
|
|
|
defer func() {
|
|
_, _, err = tc.Nomad().Jobs().Deregister(jobID, true, nil)
|
|
require.NoError(t, err)
|
|
}()
|
|
|
|
allocID := allocs[0].ID
|
|
e2eutil.WaitForAllocTaskRunning(t, tc.Nomad(), allocID, "sleep")
|
|
|
|
alloc, _, err := tc.Nomad().Allocations().Info(allocID, nil)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, alloc)
|
|
|
|
resizeCh := make(chan api.TerminalSize)
|
|
var tty bool
|
|
|
|
ctx, cancelFn := context.WithTimeout(context.Background(), 15*time.Second)
|
|
defer cancelFn()
|
|
|
|
var stdout, stderr bytes.Buffer
|
|
|
|
exitCode, err := tc.Nomad().Allocations().Exec(
|
|
ctx,
|
|
alloc,
|
|
"sleep",
|
|
tty,
|
|
[]string{"ps", "ax"},
|
|
bytes.NewReader([]byte("")),
|
|
&stdout,
|
|
&stderr,
|
|
resizeCh,
|
|
nil,
|
|
)
|
|
require.NoError(t, err)
|
|
require.Equal(t, 0, exitCode)
|
|
|
|
lines := strings.Split(strings.TrimSpace(stdout.String()), "\n")
|
|
// header, sleep process, ps ax process are the only output lines expected
|
|
require.Len(t, lines, 3)
|
|
}
|
|
|
|
func (tc *IsolationTest) TestIsolation_RawExecDriver_NoPIDNamespacing(f *framework.F) {
|
|
t := f.T()
|
|
|
|
clientNodes, err := e2eutil.ListLinuxClientNodes(tc.Nomad())
|
|
require.Nil(t, err)
|
|
|
|
if len(clientNodes) == 0 {
|
|
t.Skip("no Linux clients")
|
|
}
|
|
|
|
jobID := "isolation-pid-namespace-" + uuid.Short()
|
|
file := "isolation/input/raw_exec.nomad"
|
|
|
|
allocs := e2eutil.RegisterAndWaitForAllocs(t, tc.Nomad(), file, jobID, "")
|
|
require.Equal(t, len(allocs), 1, fmt.Sprintf("failed to register %s", jobID))
|
|
|
|
defer func() {
|
|
_, _, err = tc.Nomad().Jobs().Deregister(jobID, true, nil)
|
|
require.NoError(t, err)
|
|
}()
|
|
|
|
allocID := allocs[0].ID
|
|
e2eutil.WaitForAllocStopped(t, tc.Nomad(), allocID)
|
|
|
|
out, err := e2eutil.AllocLogs(allocID, e2eutil.LogsStdOut)
|
|
require.NoError(t, err, fmt.Sprintf("could not get logs for alloc %s", allocID))
|
|
|
|
var pid uint64
|
|
_, err = fmt.Sscanf(out, "my pid is %d", &pid)
|
|
require.NoError(t, err)
|
|
|
|
require.Greater(t, pid, uint64(1))
|
|
}
|