40
process.go
40
process.go
@@ -11,20 +11,17 @@ import (
|
||||
)
|
||||
|
||||
type process struct {
|
||||
id string
|
||||
task *task
|
||||
|
||||
// this is a hack to make a blocking Wait work
|
||||
// exec does not have a create/start split so if a quick exiting process like `exit 1`
|
||||
// run, the wait does not have enough time to get the pid catch the event. So we need
|
||||
// to lock this on process struct create and only unlock it after the pid is set
|
||||
// this allow the wait to be called before calling process start and not race with the exit event
|
||||
pidSync chan struct{}
|
||||
|
||||
io *IO
|
||||
pid uint32
|
||||
io *IO
|
||||
spec *specs.Process
|
||||
}
|
||||
|
||||
func (p *process) ID() string {
|
||||
return p.id
|
||||
}
|
||||
|
||||
// Pid returns the pid of the process
|
||||
// The pid is not set until start is called and returns
|
||||
func (p *process) Pid() uint32 {
|
||||
@@ -38,7 +35,8 @@ func (p *process) Start(ctx context.Context) error {
|
||||
return err
|
||||
}
|
||||
request := &tasks.ExecProcessRequest{
|
||||
ContainerID: p.task.containerID,
|
||||
ContainerID: p.task.id,
|
||||
ExecID: p.id,
|
||||
Terminal: p.io.Terminal,
|
||||
Stdin: p.io.Stdin,
|
||||
Stdout: p.io.Stdout,
|
||||
@@ -50,17 +48,14 @@ func (p *process) Start(ctx context.Context) error {
|
||||
return err
|
||||
}
|
||||
p.pid = response.Pid
|
||||
close(p.pidSync)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *process) Kill(ctx context.Context, s syscall.Signal) error {
|
||||
_, err := p.task.client.TaskService().Kill(ctx, &tasks.KillRequest{
|
||||
Signal: uint32(s),
|
||||
ContainerID: p.task.containerID,
|
||||
PidOrAll: &tasks.KillRequest_Pid{
|
||||
Pid: p.pid,
|
||||
},
|
||||
ContainerID: p.task.id,
|
||||
ExecID: p.id,
|
||||
})
|
||||
return err
|
||||
}
|
||||
@@ -70,7 +65,6 @@ func (p *process) Wait(ctx context.Context) (uint32, error) {
|
||||
if err != nil {
|
||||
return UnknownExitStatus, err
|
||||
}
|
||||
<-p.pidSync
|
||||
evloop:
|
||||
for {
|
||||
evt, err := eventstream.Recv()
|
||||
@@ -86,7 +80,7 @@ evloop:
|
||||
if e.Type != eventsapi.RuntimeEvent_EXIT {
|
||||
continue evloop
|
||||
}
|
||||
if e.ID == p.task.containerID && e.Pid == p.pid {
|
||||
if e.ID == p.id && e.ContainerID == p.task.id {
|
||||
return e.ExitStatus, nil
|
||||
}
|
||||
}
|
||||
@@ -95,8 +89,8 @@ evloop:
|
||||
|
||||
func (p *process) CloseIO(ctx context.Context, opts ...IOCloserOpts) error {
|
||||
r := &tasks.CloseIORequest{
|
||||
ContainerID: p.task.containerID,
|
||||
Pid: p.pid,
|
||||
ContainerID: p.task.id,
|
||||
ExecID: p.id,
|
||||
}
|
||||
for _, o := range opts {
|
||||
o(r)
|
||||
@@ -111,10 +105,10 @@ func (p *process) IO() *IO {
|
||||
|
||||
func (p *process) Resize(ctx context.Context, w, h uint32) error {
|
||||
_, err := p.task.client.TaskService().ResizePty(ctx, &tasks.ResizePtyRequest{
|
||||
ContainerID: p.task.containerID,
|
||||
ContainerID: p.task.id,
|
||||
Width: w,
|
||||
Height: h,
|
||||
Pid: p.pid,
|
||||
ExecID: p.id,
|
||||
})
|
||||
return err
|
||||
}
|
||||
@@ -122,8 +116,8 @@ func (p *process) Resize(ctx context.Context, w, h uint32) error {
|
||||
func (p *process) Delete(ctx context.Context) (uint32, error) {
|
||||
cerr := p.io.Close()
|
||||
r, err := p.task.client.TaskService().DeleteProcess(ctx, &tasks.DeleteProcessRequest{
|
||||
ContainerID: p.task.containerID,
|
||||
Pid: p.pid,
|
||||
ContainerID: p.task.id,
|
||||
ExecID: p.id,
|
||||
})
|
||||
if err != nil {
|
||||
return UnknownExitStatus, err
|
||||
|
Reference in New Issue
Block a user