fix(inputs.exec): Clean up grandchildren processes (#13937)
This commit is contained in:
parent
a9ba23f41a
commit
b6d946da6e
|
|
@ -19,14 +19,22 @@ const KillGrace = 5 * time.Second
|
|||
func WaitTimeout(c *exec.Cmd, timeout time.Duration) error {
|
||||
var kill *time.Timer
|
||||
term := time.AfterFunc(timeout, func() {
|
||||
err := c.Process.Signal(syscall.SIGTERM)
|
||||
err := syscall.Kill(-c.Process.Pid, syscall.SIGTERM)
|
||||
if err != nil {
|
||||
log.Printf("E! [agent] Error terminating process children: %s", err)
|
||||
}
|
||||
err = c.Process.Signal(syscall.SIGTERM)
|
||||
if err != nil {
|
||||
log.Printf("E! [agent] Error terminating process: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
kill = time.AfterFunc(KillGrace, func() {
|
||||
err := c.Process.Kill()
|
||||
err := syscall.Kill(-c.Process.Pid, syscall.SIGKILL)
|
||||
if err != nil {
|
||||
log.Printf("E! [agent] Error terminating process children: %s", err)
|
||||
}
|
||||
err = c.Process.Kill()
|
||||
if err != nil {
|
||||
log.Printf("E! [agent] Error killing process: %s", err)
|
||||
return
|
||||
|
|
|
|||
|
|
@ -7,19 +7,14 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
osExec "os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/kballard/go-shellquote"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/config"
|
||||
"github.com/influxdata/telegraf/internal"
|
||||
"github.com/influxdata/telegraf/models"
|
||||
"github.com/influxdata/telegraf/plugins/inputs"
|
||||
"github.com/influxdata/telegraf/plugins/parsers/nagios"
|
||||
|
|
@ -61,40 +56,6 @@ type Runner interface {
|
|||
|
||||
type CommandRunner struct{}
|
||||
|
||||
func (c CommandRunner) Run(
|
||||
command string,
|
||||
environments []string,
|
||||
timeout time.Duration,
|
||||
) ([]byte, []byte, error) {
|
||||
splitCmd, err := shellquote.Split(command)
|
||||
if err != nil || len(splitCmd) == 0 {
|
||||
return nil, nil, fmt.Errorf("exec: unable to parse command: %w", err)
|
||||
}
|
||||
|
||||
cmd := osExec.Command(splitCmd[0], splitCmd[1:]...)
|
||||
|
||||
if len(environments) > 0 {
|
||||
cmd.Env = append(os.Environ(), environments...)
|
||||
}
|
||||
|
||||
var (
|
||||
out bytes.Buffer
|
||||
stderr bytes.Buffer
|
||||
)
|
||||
cmd.Stdout = &out
|
||||
cmd.Stderr = &stderr
|
||||
|
||||
runErr := internal.RunTimeout(cmd, timeout)
|
||||
|
||||
out = removeWindowsCarriageReturns(out)
|
||||
if stderr.Len() > 0 && !telegraf.Debug {
|
||||
stderr = removeWindowsCarriageReturns(stderr)
|
||||
stderr = c.truncate(stderr)
|
||||
}
|
||||
|
||||
return out.Bytes(), stderr.Bytes(), runErr
|
||||
}
|
||||
|
||||
func (c CommandRunner) truncate(buf bytes.Buffer) bytes.Buffer {
|
||||
// Limit the number of bytes.
|
||||
didTruncate := false
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
//go:build !windows
|
||||
|
||||
package exec
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
osExec "os/exec"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/internal"
|
||||
"github.com/kballard/go-shellquote"
|
||||
)
|
||||
|
||||
func (c CommandRunner) Run(
|
||||
command string,
|
||||
environments []string,
|
||||
timeout time.Duration,
|
||||
) ([]byte, []byte, error) {
|
||||
splitCmd, err := shellquote.Split(command)
|
||||
if err != nil || len(splitCmd) == 0 {
|
||||
return nil, nil, fmt.Errorf("exec: unable to parse command: %w", err)
|
||||
}
|
||||
|
||||
cmd := osExec.Command(splitCmd[0], splitCmd[1:]...)
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
|
||||
|
||||
if len(environments) > 0 {
|
||||
cmd.Env = append(os.Environ(), environments...)
|
||||
}
|
||||
|
||||
var (
|
||||
out bytes.Buffer
|
||||
stderr bytes.Buffer
|
||||
)
|
||||
cmd.Stdout = &out
|
||||
cmd.Stderr = &stderr
|
||||
|
||||
runErr := internal.RunTimeout(cmd, timeout)
|
||||
|
||||
out = removeWindowsCarriageReturns(out)
|
||||
if stderr.Len() > 0 && !telegraf.Debug {
|
||||
stderr = removeWindowsCarriageReturns(stderr)
|
||||
stderr = c.truncate(stderr)
|
||||
}
|
||||
|
||||
return out.Bytes(), stderr.Bytes(), runErr
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
//go:build windows
|
||||
|
||||
package exec
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
osExec "os/exec"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/internal"
|
||||
"github.com/kballard/go-shellquote"
|
||||
)
|
||||
|
||||
func (c CommandRunner) Run(
|
||||
command string,
|
||||
environments []string,
|
||||
timeout time.Duration,
|
||||
) ([]byte, []byte, error) {
|
||||
splitCmd, err := shellquote.Split(command)
|
||||
if err != nil || len(splitCmd) == 0 {
|
||||
return nil, nil, fmt.Errorf("exec: unable to parse command: %w", err)
|
||||
}
|
||||
|
||||
cmd := osExec.Command(splitCmd[0], splitCmd[1:]...)
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{
|
||||
CreationFlags: syscall.CREATE_NEW_PROCESS_GROUP,
|
||||
}
|
||||
|
||||
if len(environments) > 0 {
|
||||
cmd.Env = append(os.Environ(), environments...)
|
||||
}
|
||||
|
||||
var (
|
||||
out bytes.Buffer
|
||||
stderr bytes.Buffer
|
||||
)
|
||||
cmd.Stdout = &out
|
||||
cmd.Stderr = &stderr
|
||||
|
||||
runErr := internal.RunTimeout(cmd, timeout)
|
||||
|
||||
out = removeWindowsCarriageReturns(out)
|
||||
if stderr.Len() > 0 && !telegraf.Debug {
|
||||
stderr = removeWindowsCarriageReturns(stderr)
|
||||
stderr = c.truncate(stderr)
|
||||
}
|
||||
|
||||
return out.Bytes(), stderr.Bytes(), runErr
|
||||
}
|
||||
Loading…
Reference in New Issue