feat: complete Windows client control and recovery paths
This commit is contained in:
@@ -35,12 +35,26 @@ var (
|
||||
type NativeOptions struct {
|
||||
Shells ShellPaths
|
||||
WorkRoot string
|
||||
JobProfiles map[string]JobProfile
|
||||
MaxWrapperBytes uint64
|
||||
MaxOutputChunk uint64
|
||||
WindowsTermGrace time.Duration
|
||||
Now func() time.Time
|
||||
}
|
||||
|
||||
// JobProfile is the validated administrator policy for one protocol profile.
|
||||
// The native Windows adapter applies only controls it can set and read back
|
||||
// atomically on a Job Object; a requested unsupported required control rejects
|
||||
// the command before any child is created.
|
||||
type JobProfile struct {
|
||||
RequiredControls []string
|
||||
CPUPercent uint64
|
||||
MemoryMaxBytes uint64
|
||||
PIDsMax uint64
|
||||
IOReadBPS uint64
|
||||
IOWriteBPS uint64
|
||||
}
|
||||
|
||||
func (options NativeOptions) withDefaults() NativeOptions {
|
||||
if options.MaxWrapperBytes == 0 {
|
||||
options.MaxWrapperBytes = 10 << 20
|
||||
@@ -69,17 +83,19 @@ func newExecSupervisor(options NativeOptions) *execSupervisor {
|
||||
}
|
||||
|
||||
type execProcess struct {
|
||||
issue domain.UUID
|
||||
identity supervisor.EffectiveIdentity
|
||||
cmd *exec.Cmd
|
||||
stdin io.WriteCloser
|
||||
stdout io.ReadCloser
|
||||
stderr io.ReadCloser
|
||||
outputs chan outputResult
|
||||
done chan struct{}
|
||||
started time.Time
|
||||
waitFn func() (int32, bool, error)
|
||||
killFn func(uint32) error
|
||||
issue domain.UUID
|
||||
identity supervisor.EffectiveIdentity
|
||||
cmd *exec.Cmd
|
||||
pid uint32
|
||||
stdin io.WriteCloser
|
||||
stdout io.ReadCloser
|
||||
stderr io.ReadCloser
|
||||
outputs chan outputResult
|
||||
done chan struct{}
|
||||
started time.Time
|
||||
waitFn func() (int32, bool, error)
|
||||
killFn func(uint32) error
|
||||
snapshotFn func() (supervisor.ResourceSnapshot, error)
|
||||
|
||||
mu sync.Mutex
|
||||
finished bool
|
||||
@@ -219,7 +235,7 @@ func (process *execProcess) startReaders(maxChunk uint64, remove func()) {
|
||||
}
|
||||
|
||||
func materializeWrapper(directory string, wrapper Wrapper, now time.Time) (string, func(), error) {
|
||||
if directory == "" || !now.IsZero() && now.Location() == nil {
|
||||
if directory == "" {
|
||||
return "", nil, ErrInvalidWorkingDirectory
|
||||
}
|
||||
if err := os.MkdirAll(directory, 0o700); err != nil {
|
||||
@@ -441,7 +457,11 @@ func (manager *execSupervisor) startCommand(ctx context.Context, spec supervisor
|
||||
}
|
||||
|
||||
func (manager *execSupervisor) registerProcess(issue domain.UUID, identity supervisor.EffectiveIdentity, command *exec.Cmd, stdin io.WriteCloser, stdout, stderr io.ReadCloser, started time.Time, waitFn func() (int32, bool, error), killFn func(uint32) error, cleanup func()) *execProcess {
|
||||
process := &execProcess{issue: issue, identity: identity, cmd: command, stdin: stdin, stdout: stdout, stderr: stderr, outputs: make(chan outputResult, 32), done: make(chan struct{}), started: started, waitFn: waitFn, killFn: killFn}
|
||||
var pid uint32
|
||||
if command != nil && command.Process != nil && command.Process.Pid > 0 {
|
||||
pid = uint32(command.Process.Pid)
|
||||
}
|
||||
process := &execProcess{issue: issue, identity: identity, cmd: command, pid: pid, stdin: stdin, stdout: stdout, stderr: stderr, outputs: make(chan outputResult, 32), done: make(chan struct{}), started: started, waitFn: waitFn, killFn: killFn}
|
||||
manager.mu.Lock()
|
||||
manager.active[issue] = process
|
||||
manager.mu.Unlock()
|
||||
|
||||
Reference in New Issue
Block a user