github.com/georgethebeatle/containerd@v0.2.5/supervisor/worker.go (about) 1 package supervisor 2 3 import ( 4 "sync" 5 "time" 6 7 "github.com/Sirupsen/logrus" 8 "github.com/docker/containerd/runtime" 9 ) 10 11 // Worker interface 12 type Worker interface { 13 Start() 14 } 15 16 type startTask struct { 17 Container runtime.Container 18 CheckpointPath string 19 Stdin string 20 Stdout string 21 Stderr string 22 Err chan error 23 StartResponse chan StartResponse 24 } 25 26 // NewWorker return a new initialized worker 27 func NewWorker(s *Supervisor, wg *sync.WaitGroup) Worker { 28 return &worker{ 29 s: s, 30 wg: wg, 31 } 32 } 33 34 type worker struct { 35 wg *sync.WaitGroup 36 s *Supervisor 37 } 38 39 // Start runs a loop in charge of starting new containers 40 func (w *worker) Start() { 41 defer w.wg.Done() 42 for t := range w.s.startTasks { 43 started := time.Now() 44 process, err := t.Container.Start(t.CheckpointPath, runtime.NewStdio(t.Stdin, t.Stdout, t.Stderr)) 45 if err != nil { 46 logrus.WithFields(logrus.Fields{ 47 "error": err, 48 "id": t.Container.ID(), 49 }).Error("containerd: start container") 50 t.Err <- err 51 evt := &DeleteTask{ 52 ID: t.Container.ID(), 53 NoEvent: true, 54 Process: process, 55 } 56 w.s.SendTask(evt) 57 continue 58 } 59 if err := w.s.monitor.MonitorOOM(t.Container); err != nil && err != runtime.ErrContainerExited { 60 if process.State() != runtime.Stopped { 61 logrus.WithField("error", err).Error("containerd: notify OOM events") 62 } 63 } 64 if err := w.s.monitorProcess(process); err != nil { 65 logrus.WithField("error", err).Error("containerd: add process to monitor") 66 t.Err <- err 67 evt := &DeleteTask{ 68 ID: t.Container.ID(), 69 NoEvent: true, 70 Process: process, 71 } 72 w.s.SendTask(evt) 73 continue 74 } 75 // only call process start if we aren't restoring from a checkpoint 76 // if we have restored from a checkpoint then the process is already started 77 if t.CheckpointPath == "" { 78 if err := process.Start(); err != nil { 79 logrus.WithField("error", err).Error("containerd: start init process") 80 t.Err <- err 81 evt := &DeleteTask{ 82 ID: t.Container.ID(), 83 NoEvent: true, 84 Process: process, 85 } 86 w.s.SendTask(evt) 87 continue 88 } 89 } 90 ContainerStartTimer.UpdateSince(started) 91 t.Err <- nil 92 t.StartResponse <- StartResponse{ 93 Container: t.Container, 94 } 95 w.s.notifySubscribers(Event{ 96 Timestamp: time.Now(), 97 ID: t.Container.ID(), 98 Type: StateStart, 99 }) 100 } 101 }