// Start runs a loop in charge of starting new containers func (w *worker) Start() { defer w.wg.Done() for t := range w.s.startTasks { started := time.Now() process, err := t.Container.Start(t.CheckpointPath, runtime.NewStdio(t.Stdin, t.Stdout, t.Stderr)) if err != nil { logrus.WithFields(logrus.Fields{ "error": err, "id": t.Container.ID(), }).Error("containerd: start container") t.Err <- err evt := &DeleteTask{ ID: t.Container.ID(), NoEvent: true, } w.s.SendTask(evt) continue } if err := w.s.monitor.MonitorOOM(t.Container); err != nil && err != runtime.ErrContainerExited { if process.State() != runtime.Stopped { logrus.WithField("error", err).Error("containerd: notify OOM events") } } if err := w.s.monitorProcess(process); err != nil { logrus.WithField("error", err).Error("containerd: add process to monitor") } if err := process.Start(); err != nil { logrus.WithField("error", err).Error("containerd: start init process") } ContainerStartTimer.UpdateSince(started) t.Err <- nil t.StartResponse <- StartResponse{ Container: t.Container, } w.s.notifySubscribers(Event{ Timestamp: time.Now(), ID: t.Container.ID(), Type: StateStart, }) } }
func (s *Supervisor) addProcess(t *AddProcessTask) error { start := time.Now() ci, ok := s.containers[t.ID] if !ok { return ErrContainerNotFound } process, err := ci.container.Exec(t.PID, *t.ProcessSpec, runtime.NewStdio(t.Stdin, t.Stdout, t.Stderr)) if err != nil { return err } if err := s.monitorProcess(process); err != nil { return err } ExecProcessTimer.UpdateSince(start) t.StartResponse <- StartResponse{} s.notifySubscribers(Event{ Timestamp: time.Now(), Type: StateStartProcess, PID: t.PID, ID: t.ID, }) return nil }