6 "github.com/Sirupsen/logrus"
7 "github.com/containerd/containerd/runtime"
10 // ExitTask holds needed parameters to execute the exit task
11 type ExitTask struct {
13 Process runtime.Process
16 func (s *Supervisor) exit(t *ExitTask) error {
19 status, err := proc.ExitStatus()
21 logrus.WithFields(logrus.Fields{
24 "id": proc.Container().ID(),
25 "systemPid": proc.SystemPid(),
26 }).Error("containerd: get exit status")
28 logrus.WithFields(logrus.Fields{
31 "id": proc.Container().ID(),
32 "systemPid": proc.SystemPid(),
33 }).Debug("containerd: process exited")
35 // if the process is the the init process of the container then
36 // fire a separate event for this process
37 if proc.ID() != runtime.InitProcessID {
39 ID: proc.Container().ID(),
47 container := proc.Container()
56 ExitProcessTimer.UpdateSince(start)
61 // ExecExitTask holds needed parameters to execute the exec exit task
62 type ExecExitTask struct {
67 Process runtime.Process
70 func (s *Supervisor) execExit(t *ExecExitTask) error {
71 container := t.Process.Container()
72 // exec process: we remove this process without notifying the main event loop
73 if err := container.RemoveProcess(t.PID); err != nil {
74 logrus.WithField("error", err).Error("containerd: find container for pid")
76 synCh := s.getExecSyncChannel(t.ID, t.PID)
77 // If the exec spawned children which are still using its IO
78 // waiting here will block until they die or close their IO
80 // Hence, we use a go routine to avoid blocking all other operations
83 s.notifySubscribers(Event{
84 Timestamp: time.Now(),