Handle case where shim is reaped before the call to the runtime start
This avoid erroring out with a false positive Signed-off-by: Kenfe-Mickael Laventure <mickael.laventure@gmail.com>
This commit is contained in:
parent
2e4e484237
commit
d8b9559d8e
4 changed files with 29 additions and 18 deletions
|
@ -258,13 +258,13 @@ func (cs *ContainerdSuite) TearDownTest(c *check.C) {
|
||||||
})
|
})
|
||||||
|
|
||||||
if err := cs.KillContainer(ctr.Id); err != nil {
|
if err := cs.KillContainer(ctr.Id); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "Failed to cleanup leftover test containers: %v", err)
|
fmt.Fprintf(os.Stderr, "Failed to cleanup leftover test containers: %v\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-ch:
|
case <-ch:
|
||||||
case <-time.After(3 * time.Second):
|
case <-time.After(3 * time.Second):
|
||||||
fmt.Fprintf(os.Stderr, "TearDownTest: Containerd %v didn't die after 3 seconds", ctr.Id)
|
fmt.Fprintf(os.Stderr, "TearDownTest: Containerd %v didn't die after 3 seconds\n", ctr.Id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -465,6 +465,7 @@ func (c *container) Exec(pid string, pspec specs.ProcessSpec, s Stdio) (pp Proce
|
||||||
func (c *container) createCmd(pid string, cmd *exec.Cmd, p *process) error {
|
func (c *container) createCmd(pid string, cmd *exec.Cmd, p *process) error {
|
||||||
p.cmd = cmd
|
p.cmd = cmd
|
||||||
if err := cmd.Start(); err != nil {
|
if err := cmd.Start(); err != nil {
|
||||||
|
close(p.cmdDoneCh)
|
||||||
if exErr, ok := err.(*exec.Error); ok {
|
if exErr, ok := err.(*exec.Error); ok {
|
||||||
if exErr.Err == exec.ErrNotFound || exErr.Err == os.ErrNotExist {
|
if exErr.Err == exec.ErrNotFound || exErr.Err == os.ErrNotExist {
|
||||||
return fmt.Errorf("%s not installed on system", c.shim)
|
return fmt.Errorf("%s not installed on system", c.shim)
|
||||||
|
@ -472,6 +473,13 @@ func (c *container) createCmd(pid string, cmd *exec.Cmd, p *process) error {
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
go func() {
|
||||||
|
err := p.cmd.Wait()
|
||||||
|
if err == nil {
|
||||||
|
p.cmdSuccess = true
|
||||||
|
}
|
||||||
|
close(p.cmdDoneCh)
|
||||||
|
}()
|
||||||
if err := c.waitForCreate(p, cmd); err != nil {
|
if err := c.waitForCreate(p, cmd); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,6 +67,7 @@ func newProcess(config *processConfig) (*process, error) {
|
||||||
container: config.c,
|
container: config.c,
|
||||||
spec: config.processSpec,
|
spec: config.processSpec,
|
||||||
stdio: config.stdio,
|
stdio: config.stdio,
|
||||||
|
cmdDoneCh: make(chan struct{}),
|
||||||
}
|
}
|
||||||
uid, gid, err := getRootIDs(config.spec)
|
uid, gid, err := getRootIDs(config.spec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -148,6 +149,8 @@ type process struct {
|
||||||
spec specs.ProcessSpec
|
spec specs.ProcessSpec
|
||||||
stdio Stdio
|
stdio Stdio
|
||||||
cmd *exec.Cmd
|
cmd *exec.Cmd
|
||||||
|
cmdSuccess bool
|
||||||
|
cmdDoneCh chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *process) ID() string {
|
func (p *process) ID() string {
|
||||||
|
@ -230,8 +233,8 @@ func (p *process) getPidFromFile() (int, error) {
|
||||||
|
|
||||||
// Wait will reap the shim process
|
// Wait will reap the shim process
|
||||||
func (p *process) Wait() {
|
func (p *process) Wait() {
|
||||||
if p.cmd != nil {
|
if p.cmdDoneCh != nil {
|
||||||
p.cmd.Wait()
|
<-p.cmdDoneCh
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,10 +264,9 @@ func (p *process) Signal(s os.Signal) error {
|
||||||
func (p *process) Start() error {
|
func (p *process) Start() error {
|
||||||
if p.ID() == InitProcessID {
|
if p.ID() == InitProcessID {
|
||||||
var (
|
var (
|
||||||
errC = make(chan error, 1)
|
errC = make(chan error, 1)
|
||||||
shimExit = make(chan struct{}, 1)
|
args = append(p.container.runtimeArgs, "start", p.container.id)
|
||||||
args = append(p.container.runtimeArgs, "start", p.container.id)
|
cmd = exec.Command(p.container.runtime, args...)
|
||||||
cmd = exec.Command(p.container.runtime, args...)
|
|
||||||
)
|
)
|
||||||
go func() {
|
go func() {
|
||||||
out, err := cmd.CombinedOutput()
|
out, err := cmd.CombinedOutput()
|
||||||
|
@ -273,19 +275,21 @@ func (p *process) Start() error {
|
||||||
}
|
}
|
||||||
errC <- nil
|
errC <- nil
|
||||||
}()
|
}()
|
||||||
go func() {
|
|
||||||
p.Wait()
|
|
||||||
close(shimExit)
|
|
||||||
}()
|
|
||||||
select {
|
select {
|
||||||
case err := <-errC:
|
case err := <-errC:
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
case <-shimExit:
|
case <-p.cmdDoneCh:
|
||||||
cmd.Process.Kill()
|
if !p.cmdSuccess {
|
||||||
cmd.Wait()
|
cmd.Process.Kill()
|
||||||
return ErrShimExited
|
cmd.Wait()
|
||||||
|
return ErrShimExited
|
||||||
|
}
|
||||||
|
err := <-errC
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package supervisor
|
package supervisor
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"flag"
|
||||||
"os"
|
"os"
|
||||||
"sort"
|
"sort"
|
||||||
"testing"
|
"testing"
|
||||||
"flag"
|
|
||||||
|
|
||||||
"github.com/docker/containerd/runtime"
|
"github.com/docker/containerd/runtime"
|
||||||
"github.com/docker/containerd/specs"
|
"github.com/docker/containerd/specs"
|
||||||
|
@ -71,7 +71,6 @@ func (p *testProcess) State() runtime.State {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *testProcess) Wait() {
|
func (p *testProcess) Wait() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSortProcesses(t *testing.T) {
|
func TestSortProcesses(t *testing.T) {
|
||||||
|
|
Loading…
Reference in a new issue