Reap toolsrv processes on shutdown

This commit is contained in:
Ollie Agent 2026-08-17 17:45:29 +02:00
parent 2352f2483a
commit 4ac3b2135a
1 changed files with 30 additions and 10 deletions

View File

@ -6,6 +6,7 @@ import (
"context"
"crypto/rand"
"encoding/hex"
"errors"
"fmt"
"io"
"net"
@ -27,6 +28,8 @@ type Process struct {
Secret string
Info ProcessInfo
cancel context.CancelFunc
waitOnce sync.Once
waitErr error
}
// ProcessInfo contains metadata about the toolsrv process.
@ -94,7 +97,9 @@ func Spawn(ctx context.Context, cwd string, opts ...Option) (*Process, error) {
// Wait for socket to be ready
if err := waitForSocket(socketPath, 5*time.Second); err != nil {
cancel()
cmd.Process.Kill()
_ = cmd.Process.Kill()
_ = cmd.Wait()
_ = os.Remove(socketPath)
return nil, fmt.Errorf("wait for socket: %w", err)
}
@ -115,10 +120,15 @@ func (p *Process) Kill() error {
if p.cancel != nil {
p.cancel()
}
var err error
if p.Cmd != nil && p.Cmd.Process != nil {
return p.Cmd.Process.Kill()
err = p.Cmd.Process.Kill()
}
return nil
waitErr := p.Wait()
if err != nil && !errors.Is(err, os.ErrProcessDone) {
return err
}
return waitErr
}
// Close terminates the process (alias for Kill).
@ -128,10 +138,16 @@ func (p *Process) Close() error {
// Wait waits for the process to exit.
func (p *Process) Wait() error {
if p.Cmd != nil {
return p.Cmd.Wait()
if p.Cmd == nil {
return nil
}
return nil
p.waitOnce.Do(func() {
p.waitErr = p.Cmd.Wait()
if p.SocketPath != "" {
_ = os.Remove(p.SocketPath)
}
})
return p.waitErr
}
// RemoteConfig configures remote toolsrv spawning.
@ -219,13 +235,15 @@ exec "$CACHE_DIR/bin/toolsrv" %s
// Send tarball of config dir over stdin
if err := writeTarball(stdin, cfgDir); err != nil {
cancel()
cmd.Process.Kill()
_ = cmd.Process.Kill()
_ = cmd.Wait()
return nil, fmt.Errorf("send tarball: %w", err)
}
// Send bootstrap script
if _, err := stdin.Write([]byte(bootstrap)); err != nil {
cancel()
cmd.Process.Kill()
_ = cmd.Process.Kill()
_ = cmd.Wait()
return nil, fmt.Errorf("send bootstrap: %w", err)
}
stdin.Close()
@ -248,14 +266,16 @@ exec "$CACHE_DIR/bin/toolsrv" %s
case <-readyCh:
case <-time.After(30 * time.Second):
cancel()
cmd.Process.Kill()
_ = cmd.Process.Kill()
_ = cmd.Wait()
return nil, fmt.Errorf("remote toolsrv startup timeout")
}
// Wait for local socket forwarding to be ready
if err := waitForSocket(localSock, 5*time.Second); err != nil {
cancel()
cmd.Process.Kill()
_ = cmd.Process.Kill()
_ = cmd.Wait()
return nil, fmt.Errorf("wait for forwarded socket: %w", err)
}