@@ -23,6 +23,7 @@ var killTimeout = 5 * time.Second
2323const (
2424 actionRun = "run"
2525 actionExec = "exec"
26+ actionStop = "stop"
2627)
2728
2829// A Docker engine executes a specific sandbox command
@@ -125,9 +126,9 @@ func (e *Docker) execStep(step *config.Step, req Request, dir string, files File
125126
126127// getBox selects an appropriate box for the step (if any).
127128func (e * Docker ) getBox (step * config.Step , req Request ) (* config.Box , error ) {
128- if step .Action == actionExec {
129- // exec steps use existing instances
130- // and do not spin up new boxes
129+ if step .Action != actionRun {
130+ // steps other than "run" use existing containers
131+ // and do not spin up new ones
131132 return nil , nil
132133 }
133134 var boxName string
@@ -244,11 +245,14 @@ func (e *Docker) exec(box *config.Box, step *config.Step, req Request, dir strin
244245// buildArgs prepares the arguments for the `docker` command.
245246func (e * Docker ) buildArgs (box * config.Box , step * config.Step , req Request , dir string ) []string {
246247 var args []string
247- if step .Action == actionRun {
248+ switch step .Action {
249+ case actionRun :
248250 args = dockerRunArgs (box , step , req , dir )
249- } else if step .Action == actionExec {
250- args = dockerExecArgs (step )
251- } else {
251+ case actionExec :
252+ args = dockerExecArgs (step , req )
253+ case actionStop :
254+ args = dockerStopArgs (step , req )
255+ default :
252256 // should never happen if the config is valid
253257 args = []string {"version" }
254258 }
@@ -271,12 +275,15 @@ func dockerRunArgs(box *config.Box, step *config.Step, req Request, dir string)
271275 "--pids-limit" , strconv .Itoa (box .NProc ),
272276 "--user" , step .User ,
273277 }
274- if ! box . Writable {
275- args = append (args , "--read-only " )
278+ if step . Detach {
279+ args = append (args , "--detach " )
276280 }
277281 if step .Stdin {
278282 args = append (args , "--interactive" )
279283 }
284+ if ! box .Writable {
285+ args = append (args , "--read-only" )
286+ }
280287 if box .Storage != "" {
281288 args = append (args , "--storage-opt" , fmt .Sprintf ("size=%s" , box .Storage ))
282289 }
@@ -300,14 +307,23 @@ func dockerRunArgs(box *config.Box, step *config.Step, req Request, dir string)
300307}
301308
302309// dockerExecArgs prepares the arguments for the `docker exec` command.
303- func dockerExecArgs (step * config.Step ) []string {
310+ func dockerExecArgs (step * config.Step , req Request ) []string {
311+ // :name means executing in the container passed in the request
312+ box := strings .Replace (step .Box , ":name" , req .ID , 1 )
304313 return []string {
305314 actionExec , "--interactive" ,
306315 "--user" , step .User ,
307- step . Box ,
316+ box ,
308317 }
309318}
310319
320+ // dockerStopArgs prepares the arguments for the `docker stop` command.
321+ func dockerStopArgs (step * config.Step , req Request ) []string {
322+ // :name means executing in the container passed in the request
323+ box := strings .Replace (step .Box , ":name" , req .ID , 1 )
324+ return []string {actionStop , box }
325+ }
326+
311327// filesReader creates a reader over an in-memory collection of files.
312328func filesReader (files Files ) io.Reader {
313329 var input strings.Builder
0 commit comments