11package commands
22
33import (
4- "context"
54 "fmt"
65 "io/ioutil"
76 "os/exec"
87 "sync"
8+ "syscall"
99 "time"
1010
1111 "github.com/gofrs/uuid"
@@ -88,12 +88,12 @@ func execute(command string, stdin []byte, environment map[string]string) ([]byt
8888 mux .RLock ()
8989 defer mux .RUnlock ()
9090
91- cmd , ok := commands [command ]
91+ cmdConfig , ok := commands [command ]
9292 if ! ok {
9393 return nil , nil , errors .New ("command does not exist" )
9494 }
9595
96- cmdArgs , err := ParseCommandLine (cmd .Command )
96+ cmdArgs , err := ParseCommandLine (cmdConfig .Command )
9797 if err != nil {
9898 return nil , nil , errors .Wrap (err , "parse command error" )
9999 }
@@ -105,28 +105,27 @@ func execute(command string, stdin []byte, environment map[string]string) ([]byt
105105 "command" : command ,
106106 "exec" : cmdArgs [0 ],
107107 "args" : cmdArgs [1 :],
108- "max_execution_duration" : cmd .MaxExecutionDuration ,
108+ "max_execution_duration" : cmdConfig .MaxExecutionDuration ,
109109 }).Info ("commands: executing command" )
110110
111- ctx , cancel := context . WithDeadline ( context . Background (), time . Now (). Add ( cmd . MaxExecutionDuration ) )
112- defer cancel ()
111+ cmd := exec . Command ( cmdArgs [ 0 ], cmdArgs [ 1 :] ... )
112+ cmd . SysProcAttr = & syscall. SysProcAttr { Setpgid : true }
113113
114- cmdCtx := exec .CommandContext (ctx , cmdArgs [0 ], cmdArgs [1 :]... )
115114 for k , v := range environment {
116- cmdCtx .Env = append (cmdCtx .Env , fmt .Sprintf ("%s=%s" , k , v ))
115+ cmd .Env = append (cmd .Env , fmt .Sprintf ("%s=%s" , k , v ))
117116 }
118117
119- stdinPipe , err := cmdCtx .StdinPipe ()
118+ stdinPipe , err := cmd .StdinPipe ()
120119 if err != nil {
121120 return nil , nil , errors .Wrap (err , "get stdin pipe error" )
122121 }
123122
124- stdoutPipe , err := cmdCtx .StdoutPipe ()
123+ stdoutPipe , err := cmd .StdoutPipe ()
125124 if err != nil {
126125 return nil , nil , errors .Wrap (err , "get stdout pipe error" )
127126 }
128127
129- stderrPipe , err := cmdCtx .StderrPipe ()
128+ stderrPipe , err := cmd .StderrPipe ()
130129 if err != nil {
131130 return nil , nil , errors .Wrap (err , "get stderr pipe error" )
132131 }
@@ -138,14 +137,23 @@ func execute(command string, stdin []byte, environment map[string]string) ([]byt
138137 }
139138 }()
140139
141- if err := cmdCtx .Start (); err != nil {
140+ if err := cmd .Start (); err != nil {
142141 return nil , nil , errors .Wrap (err , "starting command error" )
143142 }
144143
144+ time .AfterFunc (cmdConfig .MaxExecutionDuration , func () {
145+ pgid , err := syscall .Getpgid (cmd .Process .Pid )
146+ if err == nil {
147+ if err := syscall .Kill (- pgid , syscall .SIGKILL ); err != nil {
148+ panic (err )
149+ }
150+ }
151+ })
152+
145153 stdoutB , _ := ioutil .ReadAll (stdoutPipe )
146154 stderrB , _ := ioutil .ReadAll (stderrPipe )
147155
148- if err := cmdCtx .Wait (); err != nil {
156+ if err := cmd .Wait (); err != nil {
149157 return nil , nil , errors .Wrap (err , "waiting for command to finish error" )
150158 }
151159
0 commit comments