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 {
|
func WaitTimeout(c *exec.Cmd, timeout time.Duration) error {
|
||||||
var kill *time.Timer
|
var kill *time.Timer
|
||||||
term := time.AfterFunc(timeout, func() {
|
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 {
|
if err != nil {
|
||||||
log.Printf("E! [agent] Error terminating process: %s", err)
|
log.Printf("E! [agent] Error terminating process: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
kill = time.AfterFunc(KillGrace, func() {
|
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 {
|
if err != nil {
|
||||||
log.Printf("E! [agent] Error killing process: %s", err)
|
log.Printf("E! [agent] Error killing process: %s", err)
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -7,19 +7,14 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
|
||||||
osExec "os/exec"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/kballard/go-shellquote"
|
|
||||||
|
|
||||||
"github.com/influxdata/telegraf"
|
"github.com/influxdata/telegraf"
|
||||||
"github.com/influxdata/telegraf/config"
|
"github.com/influxdata/telegraf/config"
|
||||||
"github.com/influxdata/telegraf/internal"
|
|
||||||
"github.com/influxdata/telegraf/models"
|
"github.com/influxdata/telegraf/models"
|
||||||
"github.com/influxdata/telegraf/plugins/inputs"
|
"github.com/influxdata/telegraf/plugins/inputs"
|
||||||
"github.com/influxdata/telegraf/plugins/parsers/nagios"
|
"github.com/influxdata/telegraf/plugins/parsers/nagios"
|
||||||
|
|
@ -61,40 +56,6 @@ type Runner interface {
|
||||||
|
|
||||||
type CommandRunner struct{}
|
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 {
|
func (c CommandRunner) truncate(buf bytes.Buffer) bytes.Buffer {
|
||||||
// Limit the number of bytes.
|
// Limit the number of bytes.
|
||||||
didTruncate := false
|
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