func waitForExit(c types.APIClient, events types.API_EventsClient, id, pid string, closer func()) { timestamp := time.Now() for { e, err := events.Recv() if err != nil { if grpc.ErrorDesc(err) == transport.ErrConnClosing.Desc { closer() os.Exit(128 + int(syscall.SIGHUP)) } time.Sleep(1 * time.Second) tsp, err := ptypes.TimestampProto(timestamp) if err != nil { closer() fmt.Fprintf(os.Stderr, "%s", err.Error()) os.Exit(1) } events, _ = c.Events(netcontext.Background(), &types.EventsRequest{Timestamp: tsp}) continue } timestamp, err = ptypes.Timestamp(e.Timestamp) if e.Id == id && e.Type == "exit" && e.Pid == pid { closer() os.Exit(int(e.Status)) } } }
func (r *remote) handleEventStream(events containerd.API_EventsClient) { live := false for { e, err := events.Recv() if err != nil { if grpc.ErrorDesc(err) == transport.ErrConnClosing.Desc && r.closeManually { // ignore error if grpc remote connection is closed manually return } logrus.Errorf("failed to receive event from containerd: %v", err) go r.startEventsMonitor() return } if live == false { logrus.Debugf("received past containerd event: %#v", e) // Pause/Resume events should never happens after exit one switch e.Type { case StateExit: r.pastEvents[e.Id] = e case StatePause: r.pastEvents[e.Id] = e case StateResume: r.pastEvents[e.Id] = e case stateLive: live = true r.updateEventTimestamp(time.Unix(int64(e.Timestamp), 0)) } } else { logrus.Debugf("received containerd event: %#v", e) var container *container var c *client r.RLock() for _, c = range r.clients { container, err = c.getContainer(e.Id) if err == nil { break } } r.RUnlock() if container == nil { logrus.Errorf("no state for container: %q", err) continue } if err := container.handleEvent(e); err != nil { logrus.Errorf("error processing state change for %s: %v", e.Id, err) } r.updateEventTimestamp(time.Unix(int64(e.Timestamp), 0)) } } }
func waitForExit(c types.APIClient, events types.API_EventsClient, id, pid string, closer func()) { timestamp := uint64(time.Now().Unix()) for { e, err := events.Recv() if err != nil { time.Sleep(1 * time.Second) events, _ = c.Events(netcontext.Background(), &types.EventsRequest{Timestamp: timestamp}) continue } timestamp = e.Timestamp if e.Id == id && e.Type == "exit" && e.Pid == pid { closer() os.Exit(int(e.Status)) } } }
func (r *remote) handleEventStream(events containerd.API_EventsClient) { for { e, err := events.Recv() if err != nil { if grpc.ErrorDesc(err) == transport.ErrConnClosing.Desc && r.closeManually { // ignore error if grpc remote connection is closed manually return } logrus.Errorf("libcontainerd: failed to receive event from containerd: %v", err) go r.startEventsMonitor() return } logrus.Debugf("libcontainerd: received containerd event: %#v", e) var container *container var c *client r.RLock() for _, c = range r.clients { container, err = c.getContainer(e.Id) if err == nil { break } } r.RUnlock() if container == nil { logrus.Warnf("libcontainerd: unknown container %s", e.Id) continue } if err := container.handleEvent(e); err != nil { logrus.Errorf("libcontainerd: error processing state change for %s: %v", e.Id, err) } tsp, err := ptypes.Timestamp(e.Timestamp) if err != nil { logrus.Errorf("libcontainerd: failed to convert event timestamp: %q", err) continue } r.updateEventTimestamp(tsp) } }
// ContainerdEventsHandler will process all events coming from // containerd. If a filter as been register for a given container id // via `SetContainerEventFilter()`, it will be invoked every time an // event for that id is received func (cs *ContainerdSuite) ContainerdEventsHandler(events types.API_EventsClient) { timestamp := uint64(time.Now().Unix()) for { e, err := events.Recv() if err != nil { time.Sleep(1 * time.Second) events, _ = cs.grpcClient.Events(context.Background(), &types.EventsRequest{Timestamp: timestamp}) continue } timestamp = e.Timestamp cs.eventFiltersMutex.Lock() if f, ok := cs.eventFilters[e.Id]; ok { f(e) if e.Type == "exit" && e.Pid == "init" { delete(cs.eventFilters, e.Id) } } cs.eventFiltersMutex.Unlock() } }
// ContainerdEventsHandler will process all events coming from // containerd. If a filter as been register for a given container id // via `SetContainerEventFilter()`, it will be invoked every time an // event for that id is received func (cs *ContainerdSuite) ContainerdEventsHandler(events types.API_EventsClient) { for { e, err := events.Recv() if err != nil { // If daemon died or exited, return if strings.Contains(err.Error(), "transport is closing") { break } time.Sleep(1 * time.Second) events, _ = cs.grpcClient.Events(context.Background(), &types.EventsRequest{Timestamp: cs.lastEventTs}) continue } cs.lastEventTs = e.Timestamp cs.eventFiltersMutex.Lock() if f, ok := cs.eventFilters[e.Id]; ok { f(e) if e.Type == "exit" && e.Pid == "init" { delete(cs.eventFilters, e.Id) } } cs.eventFiltersMutex.Unlock() } }