@@ -2,12 +2,14 @@ package collect
22
33import (
44 "bytes"
5+ "context"
56 "encoding/json"
67 "fmt"
78 "os"
89 "os/exec"
910 "path/filepath"
1011 "strings"
12+ "time"
1113
1214 "github.com/pkg/errors"
1315 troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
@@ -49,7 +51,29 @@ func (c *CollectHostRun) Collect(progressChan chan<- interface{}) (map[string][]
4951 collectorName = "run-host"
5052 }
5153
52- cmd := exec .Command (c .attemptToConvertCmdToAbsPath (), runHostCollector .Args ... )
54+ var (
55+ timeout time.Duration
56+ cmd * exec.Cmd
57+ errInvalidDuration error
58+ )
59+
60+ ctx := context .Background ()
61+ cmdPath := c .attemptToConvertCmdToAbsPath ()
62+
63+ if runHostCollector .Timeout != "" {
64+ timeout , errInvalidDuration = time .ParseDuration (runHostCollector .Timeout )
65+ if errInvalidDuration != nil {
66+ return nil , errors .Wrapf (errInvalidDuration , "failed to parse timeout %q" , runHostCollector .Timeout )
67+ }
68+ }
69+
70+ if timeout <= time .Duration (0 ) {
71+ cmd = exec .Command (cmdPath , runHostCollector .Args ... )
72+ } else {
73+ timeoutCtx , cancel := context .WithTimeout (ctx , timeout )
74+ defer cancel ()
75+ cmd = exec .CommandContext (timeoutCtx , cmdPath , runHostCollector .Args ... )
76+ }
5377
5478 klog .V (2 ).Infof ("Run host collector command: %q" , cmd .String ())
5579 runInfo := & HostRunInfo {
@@ -118,6 +142,9 @@ func (c *CollectHostRun) Collect(progressChan chan<- interface{}) (map[string][]
118142 if werr , ok := err .(* exec.ExitError ); ok {
119143 runInfo .ExitCode = strings .TrimPrefix (werr .Error (), "exit status " )
120144 runInfo .Error = stderr .String ()
145+ } else if err == context .DeadlineExceeded {
146+ runInfo .ExitCode = "-1"
147+ runInfo .Error = fmt .Sprintf ("command timed out after %s" , timeout .String ())
121148 } else {
122149 return nil , errors .Wrap (err , "failed to run" )
123150 }
0 commit comments