Remove container on load if it exited
If the shim gets sigkilled while containerd is down we need to be able to remove the container correctly so that it does not stay in a stopped state forever. Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
parent
94568b7a9b
commit
ca6ae2e64b
4 changed files with 26 additions and 12 deletions
|
@ -5,6 +5,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
|
@ -200,7 +201,9 @@ func (c *container) readSpec() (*specs.PlatformSpec, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *container) Delete() error {
|
func (c *container) Delete() error {
|
||||||
return os.RemoveAll(filepath.Join(c.root, c.id))
|
err := os.RemoveAll(filepath.Join(c.root, c.id))
|
||||||
|
exec.Command(c.runtime, "delete", c.id).Run()
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *container) Processes() ([]Process, error) {
|
func (c *container) Processes() ([]Process, error) {
|
||||||
|
|
|
@ -38,14 +38,10 @@ func getRootIDs(s *specs.PlatformSpec) (int, int, error) {
|
||||||
|
|
||||||
func (c *container) State() State {
|
func (c *container) State() State {
|
||||||
proc := c.processes["init"]
|
proc := c.processes["init"]
|
||||||
if proc == nil || proc.pid == 0 {
|
if proc == nil {
|
||||||
return Stopped
|
return Stopped
|
||||||
}
|
}
|
||||||
err := syscall.Kill(proc.pid, 0)
|
return proc.State()
|
||||||
if err != nil && err == syscall.ESRCH {
|
|
||||||
return Stopped
|
|
||||||
}
|
|
||||||
return Running
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *container) Runtime() string {
|
func (c *container) Runtime() string {
|
||||||
|
@ -53,11 +49,11 @@ func (c *container) Runtime() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *container) Pause() error {
|
func (c *container) Pause() error {
|
||||||
return exec.Command("runc", "pause", c.id).Run()
|
return exec.Command(c.runtime, "pause", c.id).Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *container) Resume() error {
|
func (c *container) Resume() error {
|
||||||
return exec.Command("runc", "resume", c.id).Run()
|
return exec.Command(c.runtime, "resume", c.id).Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *container) Checkpoints() ([]Checkpoint, error) {
|
func (c *container) Checkpoints() ([]Checkpoint, error) {
|
||||||
|
@ -336,6 +332,7 @@ func waitForStart(p *process, cmd *exec.Cmd) error {
|
||||||
return errNoPidFile
|
return errNoPidFile
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isAlive checks if the shim that launched the container is still alive
|
||||||
func isAlive(cmd *exec.Cmd) (bool, error) {
|
func isAlive(cmd *exec.Cmd) (bool, error) {
|
||||||
if err := syscall.Kill(cmd.Process.Pid, 0); err != nil {
|
if err := syscall.Kill(cmd.Process.Pid, 0); err != nil {
|
||||||
if err == syscall.ESRCH {
|
if err == syscall.ESRCH {
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
"github.com/docker/containerd/specs"
|
"github.com/docker/containerd/specs"
|
||||||
)
|
)
|
||||||
|
@ -36,6 +37,8 @@ type Process interface {
|
||||||
Stdio() Stdio
|
Stdio() Stdio
|
||||||
// SystemPid is the pid on the system
|
// SystemPid is the pid on the system
|
||||||
SystemPid() int
|
SystemPid() int
|
||||||
|
// State returns if the process is running or not
|
||||||
|
State() State
|
||||||
}
|
}
|
||||||
|
|
||||||
type processConfig struct {
|
type processConfig struct {
|
||||||
|
@ -178,6 +181,17 @@ func (p *process) Close() error {
|
||||||
return p.exitPipe.Close()
|
return p.exitPipe.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *process) State() State {
|
||||||
|
if p.pid == 0 {
|
||||||
|
return Stopped
|
||||||
|
}
|
||||||
|
err := syscall.Kill(p.pid, 0)
|
||||||
|
if err != nil && err == syscall.ESRCH {
|
||||||
|
return Stopped
|
||||||
|
}
|
||||||
|
return Running
|
||||||
|
}
|
||||||
|
|
||||||
func (p *process) getPidFromFile() (int, error) {
|
func (p *process) getPidFromFile() (int, error) {
|
||||||
data, err := ioutil.ReadFile(filepath.Join(p.root, "pid"))
|
data, err := ioutil.ReadFile(filepath.Join(p.root, "pid"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -272,12 +272,12 @@ func (s *Supervisor) restore() error {
|
||||||
logrus.WithField("id", id).Debug("containerd: container restored")
|
logrus.WithField("id", id).Debug("containerd: container restored")
|
||||||
var exitedProcesses []runtime.Process
|
var exitedProcesses []runtime.Process
|
||||||
for _, p := range processes {
|
for _, p := range processes {
|
||||||
if _, err := p.ExitStatus(); err == nil {
|
if p.State() == runtime.Running {
|
||||||
exitedProcesses = append(exitedProcesses, p)
|
|
||||||
} else {
|
|
||||||
if err := s.monitorProcess(p); err != nil {
|
if err := s.monitorProcess(p); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
exitedProcesses = append(exitedProcesses, p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(exitedProcesses) > 0 {
|
if len(exitedProcesses) > 0 {
|
||||||
|
|
Loading…
Reference in a new issue