@@ -56,7 +56,7 @@ const (
56
56
57
57
// List returns all containers created inside the provided runc root directory
58
58
func (r * Runc ) List (context context.Context ) ([]* Container , error ) {
59
- data , err := cmdOutput (r .command (context , "list" , "--format=json" ), false )
59
+ data , err := cmdOutput (r .command (context , "list" , "--format=json" ), false , nil )
60
60
defer putBuf (data )
61
61
if err != nil {
62
62
return nil , err
@@ -70,7 +70,7 @@ func (r *Runc) List(context context.Context) ([]*Container, error) {
70
70
71
71
// State returns the state for the container provided by id
72
72
func (r * Runc ) State (context context.Context , id string ) (* Container , error ) {
73
- data , err := cmdOutput (r .command (context , "state" , id ), true )
73
+ data , err := cmdOutput (r .command (context , "state" , id ), true , nil )
74
74
defer putBuf (data )
75
75
if err != nil {
76
76
return nil , fmt .Errorf ("%s: %s" , err , data .String ())
@@ -95,6 +95,7 @@ type CreateOpts struct {
95
95
NoPivot bool
96
96
NoNewKeyring bool
97
97
ExtraFiles []* os.File
98
+ Started chan <- int
98
99
}
99
100
100
101
func (o * CreateOpts ) args () (out []string , err error ) {
@@ -140,7 +141,7 @@ func (r *Runc) Create(context context.Context, id, bundle string, opts *CreateOp
140
141
cmd .ExtraFiles = opts .ExtraFiles
141
142
142
143
if cmd .Stdout == nil && cmd .Stderr == nil {
143
- data , err := cmdOutput (cmd , true )
144
+ data , err := cmdOutput (cmd , true , nil )
144
145
defer putBuf (data )
145
146
if err != nil {
146
147
return fmt .Errorf ("%s: %s" , err , data .String ())
@@ -175,6 +176,7 @@ type ExecOpts struct {
175
176
PidFile string
176
177
ConsoleSocket ConsoleSocket
177
178
Detach bool
179
+ Started chan <- int
178
180
}
179
181
180
182
func (o * ExecOpts ) args () (out []string , err error ) {
@@ -197,6 +199,9 @@ func (o *ExecOpts) args() (out []string, err error) {
197
199
// Exec executes an additional process inside the container based on a full
198
200
// OCI Process specification
199
201
func (r * Runc ) Exec (context context.Context , id string , spec specs.Process , opts * ExecOpts ) error {
202
+ if opts .Started != nil {
203
+ defer close (opts .Started )
204
+ }
200
205
f , err := ioutil .TempFile (os .Getenv ("XDG_RUNTIME_DIR" ), "runc-process" )
201
206
if err != nil {
202
207
return err
@@ -220,7 +225,7 @@ func (r *Runc) Exec(context context.Context, id string, spec specs.Process, opts
220
225
opts .Set (cmd )
221
226
}
222
227
if cmd .Stdout == nil && cmd .Stderr == nil {
223
- data , err := cmdOutput (cmd , true )
228
+ data , err := cmdOutput (cmd , true , opts . Started )
224
229
defer putBuf (data )
225
230
if err != nil {
226
231
return fmt .Errorf ("%w: %s" , err , data .String ())
@@ -231,6 +236,9 @@ func (r *Runc) Exec(context context.Context, id string, spec specs.Process, opts
231
236
if err != nil {
232
237
return err
233
238
}
239
+ if opts .Started != nil {
240
+ opts .Started <- cmd .Process .Pid
241
+ }
234
242
if opts != nil && opts .IO != nil {
235
243
if c , ok := opts .IO .(StartCloser ); ok {
236
244
if err := c .CloseAfterStart (); err != nil {
@@ -248,6 +256,9 @@ func (r *Runc) Exec(context context.Context, id string, spec specs.Process, opts
248
256
// Run runs the create, start, delete lifecycle of the container
249
257
// and returns its exit status after it has exited
250
258
func (r * Runc ) Run (context context.Context , id , bundle string , opts * CreateOpts ) (int , error ) {
259
+ if opts .Started != nil {
260
+ defer close (opts .Started )
261
+ }
251
262
args := []string {"run" , "--bundle" , bundle }
252
263
if opts != nil {
253
264
oargs , err := opts .args ()
@@ -264,6 +275,9 @@ func (r *Runc) Run(context context.Context, id, bundle string, opts *CreateOpts)
264
275
if err != nil {
265
276
return - 1 , err
266
277
}
278
+ if opts .Started != nil {
279
+ opts .Started <- cmd .Process .Pid
280
+ }
267
281
status , err := Monitor .Wait (cmd , ec )
268
282
if err == nil && status != 0 {
269
283
err = fmt .Errorf ("%s did not terminate successfully: %w" , cmd .Args [0 ], & ExitError {status })
@@ -387,7 +401,7 @@ func (r *Runc) Resume(context context.Context, id string) error {
387
401
388
402
// Ps lists all the processes inside the container returning their pids
389
403
func (r * Runc ) Ps (context context.Context , id string ) ([]int , error ) {
390
- data , err := cmdOutput (r .command (context , "ps" , "--format" , "json" , id ), true )
404
+ data , err := cmdOutput (r .command (context , "ps" , "--format" , "json" , id ), true , nil )
391
405
defer putBuf (data )
392
406
if err != nil {
393
407
return nil , fmt .Errorf ("%s: %s" , err , data .String ())
@@ -401,7 +415,7 @@ func (r *Runc) Ps(context context.Context, id string) ([]int, error) {
401
415
402
416
// Top lists all the processes inside the container returning the full ps data
403
417
func (r * Runc ) Top (context context.Context , id string , psOptions string ) (* TopResults , error ) {
404
- data , err := cmdOutput (r .command (context , "ps" , "--format" , "table" , id , psOptions ), true )
418
+ data , err := cmdOutput (r .command (context , "ps" , "--format" , "table" , id , psOptions ), true , nil )
405
419
defer putBuf (data )
406
420
if err != nil {
407
421
return nil , fmt .Errorf ("%s: %s" , err , data .String ())
@@ -613,7 +627,7 @@ type Version struct {
613
627
614
628
// Version returns the runc and runtime-spec versions
615
629
func (r * Runc ) Version (context context.Context ) (Version , error ) {
616
- data , err := cmdOutput (r .command (context , "--version" ), false )
630
+ data , err := cmdOutput (r .command (context , "--version" ), false , nil )
617
631
defer putBuf (data )
618
632
if err != nil {
619
633
return Version {}, err
@@ -685,7 +699,7 @@ func (r *Runc) runOrError(cmd *exec.Cmd) error {
685
699
}
686
700
return err
687
701
}
688
- data , err := cmdOutput (cmd , true )
702
+ data , err := cmdOutput (cmd , true , nil )
689
703
defer putBuf (data )
690
704
if err != nil {
691
705
return fmt .Errorf ("%s: %s" , err , data .String ())
@@ -695,7 +709,7 @@ func (r *Runc) runOrError(cmd *exec.Cmd) error {
695
709
696
710
// callers of cmdOutput are expected to call putBuf on the returned Buffer
697
711
// to ensure it is released back to the shared pool after use.
698
- func cmdOutput (cmd * exec.Cmd , combined bool ) (* bytes.Buffer , error ) {
712
+ func cmdOutput (cmd * exec.Cmd , combined bool , started chan <- int ) (* bytes.Buffer , error ) {
699
713
b := getBuf ()
700
714
701
715
cmd .Stdout = b
@@ -706,6 +720,9 @@ func cmdOutput(cmd *exec.Cmd, combined bool) (*bytes.Buffer, error) {
706
720
if err != nil {
707
721
return nil , err
708
722
}
723
+ if started != nil {
724
+ started <- cmd .Process .Pid
725
+ }
709
726
710
727
status , err := Monitor .Wait (cmd , ec )
711
728
if err == nil && status != 0 {
0 commit comments