Actually enforce timeouts for command execution

This commit is contained in:
Emmanuel BENOîT 2021-12-05 18:53:21 +01:00
parent 256910bab2
commit 44dc6fb1db

View file

@ -4,6 +4,7 @@ import (
"context" "context"
"fmt" "fmt"
"os/exec" "os/exec"
"syscall"
"time" "time"
"unicode/utf8" "unicode/utf8"
@ -243,16 +244,24 @@ func (u *tUpdate) runCommands(timeout int, commands []string, log *logrus.Entry)
// Run a command through the `sh` shell. // Run a command through the `sh` shell.
func (b *tUpdate) runCommand(timeout int, command string, log *logrus.Entry) error { func (b *tUpdate) runCommand(timeout int, command string, log *logrus.Entry) error {
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second)
defer cancel()
log = log.WithFields(logrus.Fields{ log = log.WithFields(logrus.Fields{
"command": command, "command": command,
"timeout": timeout, "timeout": timeout,
}) })
log.Debug("Executing command") log.Debug("Executing command")
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second)
cmd := exec.CommandContext(ctx, "sh", "-c", command) cmd := exec.CommandContext(ctx, "sh", "-c", command)
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
go func() {
<-ctx.Done()
if ctx.Err() == context.DeadlineExceeded {
syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)
}
}()
output, err := cmd.CombinedOutput() output, err := cmd.CombinedOutput()
cancel()
if len(output) != 0 { if len(output) != 0 {
if utf8.Valid(output) { if utf8.Valid(output) {
log = log.WithField("output", string(output)) log = log.WithField("output", string(output))