@@ -56,7 +56,7 @@ const (
5656
5757// List returns all containers created inside the provided runc root directory
5858func (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 )
6060 defer putBuf (data )
6161 if err != nil {
6262 return nil , err
@@ -70,7 +70,7 @@ func (r *Runc) List(context context.Context) ([]*Container, error) {
7070
7171// State returns the state for the container provided by id
7272func (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 )
7474 defer putBuf (data )
7575 if err != nil {
7676 return nil , fmt .Errorf ("%s: %s" , err , data .String ())
@@ -95,6 +95,7 @@ type CreateOpts struct {
9595 NoPivot bool
9696 NoNewKeyring bool
9797 ExtraFiles []* os.File
98+ Started chan <- int
9899}
99100
100101func (o * CreateOpts ) args () (out []string , err error ) {
@@ -140,7 +141,7 @@ func (r *Runc) Create(context context.Context, id, bundle string, opts *CreateOp
140141 cmd .ExtraFiles = opts .ExtraFiles
141142
142143 if cmd .Stdout == nil && cmd .Stderr == nil {
143- data , err := cmdOutput (cmd , true )
144+ data , err := cmdOutput (cmd , true , nil )
144145 defer putBuf (data )
145146 if err != nil {
146147 return fmt .Errorf ("%s: %s" , err , data .String ())
@@ -175,6 +176,7 @@ type ExecOpts struct {
175176 PidFile string
176177 ConsoleSocket ConsoleSocket
177178 Detach bool
179+ Started chan <- int
178180}
179181
180182func (o * ExecOpts ) args () (out []string , err error ) {
@@ -197,6 +199,9 @@ func (o *ExecOpts) args() (out []string, err error) {
197199// Exec executes an additional process inside the container based on a full
198200// OCI Process specification
199201func (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+ }
200205 f , err := ioutil .TempFile (os .Getenv ("XDG_RUNTIME_DIR" ), "runc-process" )
201206 if err != nil {
202207 return err
@@ -220,7 +225,7 @@ func (r *Runc) Exec(context context.Context, id string, spec specs.Process, opts
220225 opts .Set (cmd )
221226 }
222227 if cmd .Stdout == nil && cmd .Stderr == nil {
223- data , err := cmdOutput (cmd , true )
228+ data , err := cmdOutput (cmd , true , opts . Started )
224229 defer putBuf (data )
225230 if err != nil {
226231 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
231236 if err != nil {
232237 return err
233238 }
239+ if opts .Started != nil {
240+ opts .Started <- cmd .Process .Pid
241+ }
234242 if opts != nil && opts .IO != nil {
235243 if c , ok := opts .IO .(StartCloser ); ok {
236244 if err := c .CloseAfterStart (); err != nil {
@@ -248,6 +256,9 @@ func (r *Runc) Exec(context context.Context, id string, spec specs.Process, opts
248256// Run runs the create, start, delete lifecycle of the container
249257// and returns its exit status after it has exited
250258func (r * Runc ) Run (context context.Context , id , bundle string , opts * CreateOpts ) (int , error ) {
259+ if opts .Started != nil {
260+ defer close (opts .Started )
261+ }
251262 args := []string {"run" , "--bundle" , bundle }
252263 if opts != nil {
253264 oargs , err := opts .args ()
@@ -264,6 +275,9 @@ func (r *Runc) Run(context context.Context, id, bundle string, opts *CreateOpts)
264275 if err != nil {
265276 return - 1 , err
266277 }
278+ if opts .Started != nil {
279+ opts .Started <- cmd .Process .Pid
280+ }
267281 status , err := Monitor .Wait (cmd , ec )
268282 if err == nil && status != 0 {
269283 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 {
387401
388402// Ps lists all the processes inside the container returning their pids
389403func (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 )
391405 defer putBuf (data )
392406 if err != nil {
393407 return nil , fmt .Errorf ("%s: %s" , err , data .String ())
@@ -401,7 +415,7 @@ func (r *Runc) Ps(context context.Context, id string) ([]int, error) {
401415
402416// Top lists all the processes inside the container returning the full ps data
403417func (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 )
405419 defer putBuf (data )
406420 if err != nil {
407421 return nil , fmt .Errorf ("%s: %s" , err , data .String ())
@@ -613,7 +627,7 @@ type Version struct {
613627
614628// Version returns the runc and runtime-spec versions
615629func (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 )
617631 defer putBuf (data )
618632 if err != nil {
619633 return Version {}, err
@@ -685,7 +699,7 @@ func (r *Runc) runOrError(cmd *exec.Cmd) error {
685699 }
686700 return err
687701 }
688- data , err := cmdOutput (cmd , true )
702+ data , err := cmdOutput (cmd , true , nil )
689703 defer putBuf (data )
690704 if err != nil {
691705 return fmt .Errorf ("%s: %s" , err , data .String ())
@@ -695,7 +709,7 @@ func (r *Runc) runOrError(cmd *exec.Cmd) error {
695709
696710// callers of cmdOutput are expected to call putBuf on the returned Buffer
697711// 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 ) {
699713 b := getBuf ()
700714
701715 cmd .Stdout = b
@@ -706,6 +720,9 @@ func cmdOutput(cmd *exec.Cmd, combined bool) (*bytes.Buffer, error) {
706720 if err != nil {
707721 return nil , err
708722 }
723+ if started != nil {
724+ started <- cmd .Process .Pid
725+ }
709726
710727 status , err := Monitor .Wait (cmd , ec )
711728 if err == nil && status != 0 {
0 commit comments