func (s *apiServer) ListCheckpoint(ctx context.Context, r *types.ListCheckpointRequest) (*types.ListCheckpointResponse, error) { e := supervisor.NewEvent(supervisor.GetContainerEventType) s.sv.SendEvent(e) if err := <-e.Err; err != nil { return nil, err } var container runtime.Container for _, c := range e.Containers { if c.ID() == r.Id { container = c break } } if container == nil { return nil, grpc.Errorf(codes.NotFound, "no such containers") } checkpoints, err := container.Checkpoints() if err != nil { return nil, err } var out []*types.Checkpoint for _, c := range checkpoints { out = append(out, &types.Checkpoint{ Name: c.Name, Tcp: c.Tcp, Shell: c.Shell, UnixSockets: c.UnixSockets, // TODO: figure out timestamp //Timestamp: c.Timestamp, }) } return &types.ListCheckpointResponse{Checkpoints: out}, nil }
// stopCollection closes the channels for all subscribers and removes // the container from metrics collection. func (s *statsCollector) stopCollection(c runtime.Container) { s.m.Lock() if publisher, exists := s.publishers[c.ID()]; exists { publisher.pub.Close() delete(s.publishers, c.ID()) } s.m.Unlock() }
// unsubscribe removes a specific subscriber from receiving updates for a container's stats. func (s *statsCollector) unsubscribe(c runtime.Container, ch chan interface{}) { s.m.Lock() publisher := s.publishers[c.ID()] if publisher != nil { publisher.pub.Evict(ch) if publisher.pub.Len() == 0 { delete(s.publishers, c.ID()) } } s.m.Unlock() }
// collect registers the container with the collector and adds it to // the event loop for collection on the specified interval returning // a channel for the subscriber to receive on. func (s *statsCollector) collect(c runtime.Container) chan interface{} { s.m.Lock() defer s.m.Unlock() publisher, exists := s.publishers[c.ID()] if !exists { pub := pubsub.NewPublisher(100*time.Millisecond, 1024) publisher = &statsPair{ct: c, pub: pub} s.publishers[c.ID()] = publisher } return publisher.pub.Subscribe() }
func (m *Monitor) MonitorOOM(c runtime.Container) error { m.m.Lock() defer m.m.Unlock() o, err := c.OOM() if err != nil { return err } fd := o.FD() event := syscall.EpollEvent{ Fd: int32(fd), Events: syscall.EPOLLHUP | syscall.EPOLLIN, } if err := archutils.EpollCtl(m.epollFd, syscall.EPOLL_CTL_ADD, fd, &event); err != nil { return err } EpollFdCounter.Inc(1) m.receivers[fd] = o return nil }
func createAPIContainer(c runtime.Container, getPids bool) (*types.Container, error) { processes, err := c.Processes() if err != nil { return nil, grpc.Errorf(codes.Internal, "get processes for container: "+err.Error()) } var procs []*types.Process for _, p := range processes { oldProc := p.Spec() stdio := p.Stdio() appendToProcs := &types.Process{ Pid: p.ID(), SystemPid: uint32(p.SystemPid()), Terminal: oldProc.Terminal, Args: oldProc.Args, Env: oldProc.Env, Cwd: oldProc.Cwd, Stdin: stdio.Stdin, Stdout: stdio.Stdout, Stderr: stdio.Stderr, } setUserFieldsInProcess(appendToProcs, oldProc) procs = append(procs, appendToProcs) } var pids []int state := c.State() if getPids && (state == runtime.Running || state == runtime.Paused) { if pids, err = c.Pids(); err != nil { return nil, grpc.Errorf(codes.Internal, "get all pids for container: "+err.Error()) } } return &types.Container{ Id: c.ID(), BundlePath: c.Path(), Processes: procs, Labels: c.Labels(), Status: string(state), Pids: toUint32(pids), Runtime: c.Runtime(), }, nil }
func (h *DeleteEvent) deleteContainer(container runtime.Container) error { delete(h.s.containers, container.ID()) return container.Delete() }
func createAPIContainer(c runtime.Container, getPids bool) (*types.Container, error) { processes, err := c.Processes() if err != nil { return nil, grpc.Errorf(codes.Internal, "get processes for container: "+err.Error()) } var procs []*types.Process for _, p := range processes { oldProc := p.Spec() stdio := p.Stdio() proc := &types.Process{ Pid: p.ID(), SystemPid: uint32(p.SystemPid()), Terminal: oldProc.Terminal, Args: oldProc.Args, Env: oldProc.Env, Cwd: oldProc.Cwd, Stdin: stdio.Stdin, Stdout: stdio.Stdout, Stderr: stdio.Stderr, } proc.User = &types.User{ Uid: oldProc.User.UID, Gid: oldProc.User.GID, AdditionalGids: oldProc.User.AdditionalGids, } proc.Capabilities = oldProc.Capabilities proc.ApparmorProfile = oldProc.ApparmorProfile proc.SelinuxLabel = oldProc.SelinuxLabel proc.NoNewPrivileges = oldProc.NoNewPrivileges for _, rl := range oldProc.Rlimits { proc.Rlimits = append(proc.Rlimits, &types.Rlimit{ Type: rl.Type, Soft: rl.Soft, Hard: rl.Hard, }) } procs = append(procs, proc) } var pids []int state := c.State() if getPids && (state == runtime.Running || state == runtime.Paused) { if pids, err = c.Pids(); err != nil { return nil, grpc.Errorf(codes.Internal, "get all pids for container: "+err.Error()) } } return &types.Container{ Id: c.ID(), BundlePath: c.Path(), Processes: procs, Labels: c.Labels(), Status: string(state), Pids: toUint32(pids), Runtime: c.Runtime(), }, nil }
func (s *Supervisor) deleteContainer(container runtime.Container) error { delete(s.containers, container.ID()) return container.Delete() }