diff --git a/pkg/internal/testing/process/procattr_other.go b/pkg/internal/testing/process/procattr_other.go new file mode 100644 index 0000000000..03c0265483 --- /dev/null +++ b/pkg/internal/testing/process/procattr_other.go @@ -0,0 +1,28 @@ +//go:build (!aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !zos) || !go1.9 +// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!zos !go1.9 + +/* +Copyright 2016 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package process + +import "syscall" + +// getSysProcAttr returns the SysProcAttr to use for the process, +// for non-unix systems this returns nil. +func getSysProcAttr() *syscall.SysProcAttr { + return nil +} diff --git a/pkg/internal/testing/process/procattr_unix.go b/pkg/internal/testing/process/procattr_unix.go new file mode 100644 index 0000000000..531c2f8ed7 --- /dev/null +++ b/pkg/internal/testing/process/procattr_unix.go @@ -0,0 +1,34 @@ +//go:build (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos) && go1.9 +// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos +// +build go1.9 + +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package process + +import ( + "golang.org/x/sys/unix" +) + +// getSysProcAttr returns the SysProcAttr to use for the process, +// for unix systems this returns a SysProcAttr with Setpgid set to true, +// which inherits the parent's process group id. +func getSysProcAttr() *unix.SysProcAttr { + return &unix.SysProcAttr{ + Setpgid: true, + } +} diff --git a/pkg/internal/testing/process/process.go b/pkg/internal/testing/process/process.go index af83c70a2f..1ad2938802 100644 --- a/pkg/internal/testing/process/process.go +++ b/pkg/internal/testing/process/process.go @@ -155,6 +155,7 @@ func (ps *State) Start(stdout, stderr io.Writer) (err error) { ps.Cmd = exec.Command(ps.Path, ps.Args...) ps.Cmd.Stdout = stdout ps.Cmd.Stderr = stderr + ps.Cmd.SysProcAttr = getSysProcAttr() ready := make(chan bool) timedOut := time.After(ps.StartTimeout) @@ -265,6 +266,9 @@ func (ps *State) Stop() error { case <-ps.waitDone: break case <-timedOut: + if err := ps.Cmd.Process.Signal(syscall.SIGKILL); err != nil { + return fmt.Errorf("unable to kill process %s: %w", ps.Path, err) + } return fmt.Errorf("timeout waiting for process %s to stop", path.Base(ps.Path)) } ps.ready = false