1
1
package commands
2
2
3
3
import (
4
+ "context"
4
5
"fmt"
5
6
"io/ioutil"
6
7
"os/exec"
7
8
"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
- cmdConfig , ok := commands [command ]
91
+ cmd , 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 (cmdConfig .Command )
96
+ cmdArgs , err := ParseCommandLine (cmd .Command )
97
97
if err != nil {
98
98
return nil , nil , errors .Wrap (err , "parse command error" )
99
99
}
@@ -105,27 +105,28 @@ 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" : cmdConfig .MaxExecutionDuration ,
108
+ "max_execution_duration" : cmd .MaxExecutionDuration ,
109
109
}).Info ("commands: executing command" )
110
110
111
- cmd := exec . Command ( cmdArgs [ 0 ], cmdArgs [ 1 :] ... )
112
- cmd . SysProcAttr = & syscall. SysProcAttr { Setpgid : true }
111
+ ctx , cancel := context . WithDeadline ( context . Background (), time . Now (). Add ( cmd . MaxExecutionDuration ) )
112
+ defer cancel ()
113
113
114
+ cmdCtx := exec .CommandContext (ctx , cmdArgs [0 ], cmdArgs [1 :]... )
114
115
for k , v := range environment {
115
- cmd .Env = append (cmd .Env , fmt .Sprintf ("%s=%s" , k , v ))
116
+ cmdCtx .Env = append (cmdCtx .Env , fmt .Sprintf ("%s=%s" , k , v ))
116
117
}
117
118
118
- stdinPipe , err := cmd .StdinPipe ()
119
+ stdinPipe , err := cmdCtx .StdinPipe ()
119
120
if err != nil {
120
121
return nil , nil , errors .Wrap (err , "get stdin pipe error" )
121
122
}
122
123
123
- stdoutPipe , err := cmd .StdoutPipe ()
124
+ stdoutPipe , err := cmdCtx .StdoutPipe ()
124
125
if err != nil {
125
126
return nil , nil , errors .Wrap (err , "get stdout pipe error" )
126
127
}
127
128
128
- stderrPipe , err := cmd .StderrPipe ()
129
+ stderrPipe , err := cmdCtx .StderrPipe ()
129
130
if err != nil {
130
131
return nil , nil , errors .Wrap (err , "get stderr pipe error" )
131
132
}
@@ -137,23 +138,14 @@ func execute(command string, stdin []byte, environment map[string]string) ([]byt
137
138
}
138
139
}()
139
140
140
- if err := cmd .Start (); err != nil {
141
+ if err := cmdCtx .Start (); err != nil {
141
142
return nil , nil , errors .Wrap (err , "starting command error" )
142
143
}
143
144
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
-
153
145
stdoutB , _ := ioutil .ReadAll (stdoutPipe )
154
146
stderrB , _ := ioutil .ReadAll (stderrPipe )
155
147
156
- if err := cmd .Wait (); err != nil {
148
+ if err := cmdCtx .Wait (); err != nil {
157
149
return nil , nil , errors .Wrap (err , "waiting for command to finish error" )
158
150
}
159
151
0 commit comments