1
1
package commands
2
2
3
3
import (
4
- "context"
5
4
"fmt"
6
5
"io/ioutil"
7
6
"os/exec"
8
7
"sync"
8
+ "syscall"
9
9
"time"
10
10
11
11
"github.com/gofrs/uuid"
@@ -88,12 +88,12 @@ func execute(command string, stdin []byte, environment map[string]string) ([]byt
88
88
mux .RLock ()
89
89
defer mux .RUnlock ()
90
90
91
- cmd , ok := commands [command ]
91
+ cmdConfig , ok := commands [command ]
92
92
if ! ok {
93
93
return nil , nil , errors .New ("command does not exist" )
94
94
}
95
95
96
- cmdArgs , err := ParseCommandLine (cmd .Command )
96
+ cmdArgs , err := ParseCommandLine (cmdConfig .Command )
97
97
if err != nil {
98
98
return nil , nil , errors .Wrap (err , "parse command error" )
99
99
}
@@ -105,28 +105,27 @@ func execute(command string, stdin []byte, environment map[string]string) ([]byt
105
105
"command" : command ,
106
106
"exec" : cmdArgs [0 ],
107
107
"args" : cmdArgs [1 :],
108
- "max_execution_duration" : cmd .MaxExecutionDuration ,
108
+ "max_execution_duration" : cmdConfig .MaxExecutionDuration ,
109
109
}).Info ("commands: executing command" )
110
110
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 }
113
113
114
- cmdCtx := exec .CommandContext (ctx , cmdArgs [0 ], cmdArgs [1 :]... )
115
114
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 ))
117
116
}
118
117
119
- stdinPipe , err := cmdCtx .StdinPipe ()
118
+ stdinPipe , err := cmd .StdinPipe ()
120
119
if err != nil {
121
120
return nil , nil , errors .Wrap (err , "get stdin pipe error" )
122
121
}
123
122
124
- stdoutPipe , err := cmdCtx .StdoutPipe ()
123
+ stdoutPipe , err := cmd .StdoutPipe ()
125
124
if err != nil {
126
125
return nil , nil , errors .Wrap (err , "get stdout pipe error" )
127
126
}
128
127
129
- stderrPipe , err := cmdCtx .StderrPipe ()
128
+ stderrPipe , err := cmd .StderrPipe ()
130
129
if err != nil {
131
130
return nil , nil , errors .Wrap (err , "get stderr pipe error" )
132
131
}
@@ -138,14 +137,23 @@ func execute(command string, stdin []byte, environment map[string]string) ([]byt
138
137
}
139
138
}()
140
139
141
- if err := cmdCtx .Start (); err != nil {
140
+ if err := cmd .Start (); err != nil {
142
141
return nil , nil , errors .Wrap (err , "starting command error" )
143
142
}
144
143
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
+
145
153
stdoutB , _ := ioutil .ReadAll (stdoutPipe )
146
154
stderrB , _ := ioutil .ReadAll (stderrPipe )
147
155
148
- if err := cmdCtx .Wait (); err != nil {
156
+ if err := cmd .Wait (); err != nil {
149
157
return nil , nil , errors .Wrap (err , "waiting for command to finish error" )
150
158
}
151
159
0 commit comments