mirror of
https://github.com/kemko/nomad.git
synced 2026-01-02 00:15:43 +03:00
On Windows, if the `raw_exec` driver's executor exits, the child processes are not also killed. Create a Windows "job object" (not to be confused with a Nomad job) and add the executor to it. Child processes of the executor will inherit the job automatically. When the handle to the job object is freed (on executor exit), the job itself is destroyed and this causes all processes in that job to exit. Fixes: https://github.com/hashicorp/nomad/issues/23668 Ref: https://learn.microsoft.com/en-us/windows/win32/procthread/job-objects
79 lines
1.8 KiB
Go
79 lines
1.8 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
package executor
|
|
|
|
import (
|
|
"bytes"
|
|
"io"
|
|
"os"
|
|
"sync"
|
|
"testing"
|
|
|
|
"github.com/hashicorp/nomad/client/allocdir"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestUtils_IsolationMode(t *testing.T) {
|
|
private := IsolationModePrivate
|
|
host := IsolationModeHost
|
|
blank := ""
|
|
|
|
for _, tc := range []struct {
|
|
plugin, task, exp string
|
|
}{
|
|
{plugin: private, task: private, exp: private},
|
|
{plugin: private, task: host, exp: host},
|
|
{plugin: private, task: blank, exp: private}, // default to private
|
|
|
|
{plugin: host, task: private, exp: private},
|
|
{plugin: host, task: host, exp: host},
|
|
{plugin: host, task: blank, exp: host}, // default to host
|
|
} {
|
|
result := IsolationMode(tc.plugin, tc.task)
|
|
require.Equal(t, tc.exp, result)
|
|
}
|
|
}
|
|
|
|
type testExecCmd struct {
|
|
command *ExecCommand
|
|
allocDir *allocdir.AllocDir
|
|
|
|
stdout *bytes.Buffer
|
|
stderr *bytes.Buffer
|
|
outputCopyDone *sync.WaitGroup
|
|
}
|
|
|
|
// configureTLogging configures a test command executor with buffer as
|
|
// Std{out|err} but using os.Pipe so it mimics non-test case where cmd is set
|
|
// with files as Std{out|err} the buffers can be used to read command output
|
|
func configureTLogging(t *testing.T, testcmd *testExecCmd) {
|
|
t.Helper()
|
|
var stdout, stderr bytes.Buffer
|
|
var copyDone sync.WaitGroup
|
|
|
|
stdoutPr, stdoutPw, err := os.Pipe()
|
|
require.NoError(t, err)
|
|
|
|
stderrPr, stderrPw, err := os.Pipe()
|
|
require.NoError(t, err)
|
|
|
|
copyDone.Add(2)
|
|
go func() {
|
|
defer copyDone.Done()
|
|
io.Copy(&stdout, stdoutPr)
|
|
}()
|
|
go func() {
|
|
defer copyDone.Done()
|
|
io.Copy(&stderr, stderrPr)
|
|
}()
|
|
|
|
testcmd.stdout = &stdout
|
|
testcmd.stderr = &stderr
|
|
testcmd.outputCopyDone = ©Done
|
|
|
|
testcmd.command.stdout = stdoutPw
|
|
testcmd.command.stderr = stderrPw
|
|
return
|
|
}
|