Add wait API endpoint for waiting on process exit
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
@@ -30,7 +30,7 @@ import (
|
||||
const InitPidFile = "init.pid"
|
||||
|
||||
type initProcess struct {
|
||||
sync.WaitGroup
|
||||
wg sync.WaitGroup
|
||||
initState
|
||||
|
||||
// mu is used to ensure that `Start()` and `Exited()` calls return in
|
||||
@@ -39,6 +39,8 @@ type initProcess struct {
|
||||
// the reaper interface.
|
||||
mu sync.Mutex
|
||||
|
||||
waitBlock chan struct{}
|
||||
|
||||
workDir string
|
||||
|
||||
id string
|
||||
@@ -113,8 +115,10 @@ func (s *Service) newInitProcess(context context.Context, r *shimapi.CreateTaskR
|
||||
stderr: r.Stderr,
|
||||
terminal: r.Terminal,
|
||||
},
|
||||
rootfs: rootfs,
|
||||
workDir: s.config.WorkDir,
|
||||
rootfs: rootfs,
|
||||
workDir: s.config.WorkDir,
|
||||
status: 0,
|
||||
waitBlock: make(chan struct{}),
|
||||
}
|
||||
p.initState = &createdState{p: p}
|
||||
var (
|
||||
@@ -149,22 +153,24 @@ func (s *Service) newInitProcess(context context.Context, r *shimapi.CreateTaskR
|
||||
Detach: true,
|
||||
NoSubreaper: true,
|
||||
}
|
||||
if _, err := p.runtime.Restore(context, r.ID, r.Bundle, opts); err != nil {
|
||||
return nil, p.runtimeError(err, "OCI runtime restore failed")
|
||||
}
|
||||
} else {
|
||||
opts := &runc.CreateOpts{
|
||||
PidFile: pidFile,
|
||||
IO: p.io,
|
||||
NoPivot: options.NoPivotRoot,
|
||||
NoNewKeyring: options.NoNewKeyring,
|
||||
}
|
||||
if socket != nil {
|
||||
opts.ConsoleSocket = socket
|
||||
}
|
||||
if err := p.runtime.Create(context, r.ID, r.Bundle, opts); err != nil {
|
||||
return nil, p.runtimeError(err, "OCI runtime create failed")
|
||||
p.initState = &createdCheckpointState{
|
||||
p: p,
|
||||
opts: opts,
|
||||
}
|
||||
success = true
|
||||
return p, nil
|
||||
}
|
||||
opts := &runc.CreateOpts{
|
||||
PidFile: pidFile,
|
||||
IO: p.io,
|
||||
NoPivot: options.NoPivotRoot,
|
||||
NoNewKeyring: options.NoNewKeyring,
|
||||
}
|
||||
if socket != nil {
|
||||
opts.ConsoleSocket = socket
|
||||
}
|
||||
if err := p.runtime.Create(context, r.ID, r.Bundle, opts); err != nil {
|
||||
return nil, p.runtimeError(err, "OCI runtime create failed")
|
||||
}
|
||||
if r.Stdin != "" {
|
||||
sc, err := fifo.OpenFifo(context, r.Stdin, syscall.O_WRONLY|syscall.O_NONBLOCK, 0)
|
||||
@@ -180,13 +186,13 @@ func (s *Service) newInitProcess(context context.Context, r *shimapi.CreateTaskR
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to retrieve console master")
|
||||
}
|
||||
console, err = s.platform.copyConsole(context, console, r.Stdin, r.Stdout, r.Stderr, &p.WaitGroup, ©WaitGroup)
|
||||
console, err = s.platform.copyConsole(context, console, r.Stdin, r.Stdout, r.Stderr, &p.wg, ©WaitGroup)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to start console copy")
|
||||
}
|
||||
p.console = console
|
||||
} else if !hasNoIO(r) {
|
||||
if err := copyPipes(context, p.io, r.Stdin, r.Stdout, r.Stderr, &p.WaitGroup, ©WaitGroup); err != nil {
|
||||
if err := copyPipes(context, p.io, r.Stdin, r.Stdout, r.Stderr, &p.wg, ©WaitGroup); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to start io pipe copy")
|
||||
}
|
||||
}
|
||||
@@ -201,6 +207,10 @@ func (s *Service) newInitProcess(context context.Context, r *shimapi.CreateTaskR
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func (p *initProcess) Wait() {
|
||||
<-p.waitBlock
|
||||
}
|
||||
|
||||
func (p *initProcess) ID() string {
|
||||
return p.id
|
||||
}
|
||||
@@ -240,14 +250,15 @@ func (p *initProcess) start(context context.Context) error {
|
||||
}
|
||||
|
||||
func (p *initProcess) setExited(status int) {
|
||||
p.status = status
|
||||
p.exited = time.Now()
|
||||
p.status = status
|
||||
p.platform.shutdownConsole(context.Background(), p.console)
|
||||
close(p.waitBlock)
|
||||
}
|
||||
|
||||
func (p *initProcess) delete(context context.Context) error {
|
||||
p.killAll(context)
|
||||
p.Wait()
|
||||
p.wg.Wait()
|
||||
err := p.runtime.Delete(context, p.id, nil)
|
||||
// ignore errors if a runtime has already deleted the process
|
||||
// but we still hold metadata and pipes
|
||||
|
Reference in New Issue
Block a user