diff --git a/cmd/client/container.go b/cmd/client/container.go index 067f8178..de40641e 100644 --- a/cmd/client/container.go +++ b/cmd/client/container.go @@ -18,6 +18,7 @@ var containerCommand = cli.Command{ stopContainerCommand, removeContainerCommand, containerStatusCommand, + listContainersCommand, }, } @@ -164,6 +165,26 @@ var containerStatusCommand = cli.Command{ }, } +var listContainersCommand = cli.Command{ + Name: "list", + Usage: "list containers", + Action: func(context *cli.Context) error { + // Set up a connection to the server. + conn, err := getClientConnection(context) + if err != nil { + return fmt.Errorf("failed to connect: %v", err) + } + defer conn.Close() + client := pb.NewRuntimeServiceClient(conn) + + err = ListContainers(client) + if err != nil { + return fmt.Errorf("listing containers failed: %v", err) + } + return nil + }, +} + // CreateContainer sends a CreateContainerRequest to the server, and parses // the returned CreateContainerResponse. func CreateContainer(client pb.RuntimeServiceClient, sandbox string, path string) error { @@ -264,3 +285,24 @@ func ContainerStatus(client pb.RuntimeServiceClient, ID string) error { return nil } + +// ListContainers sends a ListContainerRequest to the server, and parses +// the returned ListContainerResponse. +func ListContainers(client pb.RuntimeServiceClient) error { + r, err := client.ListContainers(context.Background(), &pb.ListContainersRequest{}) + if err != nil { + return err + } + for _, c := range r.GetContainers() { + fmt.Printf("ID: %s\n", *c.Id) + fmt.Printf("Pod: %s\n", *c.PodSandboxId) + if c.State != nil { + fmt.Printf("Status: %s\n", *c.State) + } + if c.CreatedAt != nil { + ctm := time.Unix(*c.CreatedAt, 0) + fmt.Printf("Created: %v\n", ctm) + } + } + return nil +} diff --git a/server/container.go b/server/container.go index c2003a40..1853dd60 100644 --- a/server/container.go +++ b/server/container.go @@ -367,8 +367,40 @@ func (s *Server) RemoveContainer(ctx context.Context, req *pb.RemoveContainerReq } // ListContainers lists all containers by filters. -func (s *Server) ListContainers(context.Context, *pb.ListContainersRequest) (*pb.ListContainersResponse, error) { - return nil, nil +func (s *Server) ListContainers(ctx context.Context, req *pb.ListContainersRequest) (*pb.ListContainersResponse, error) { + var ctrs []*pb.Container + for _, ctr := range s.state.containers.List() { + if err := s.runtime.UpdateStatus(ctr); err != nil { + return nil, err + } + + podSandboxID := ctr.Sandbox() + cState := s.runtime.ContainerStatus(ctr) + created := cState.Created.Unix() + rState := pb.ContainerState_UNKNOWN + + c := &pb.Container{ + Id: &cState.ID, + PodSandboxId: &podSandboxID, + CreatedAt: int64Ptr(created), + } + + switch cState.Status { + case ContainerStateCreated: + rState = pb.ContainerState_CREATED + case ContainerStateRunning: + rState = pb.ContainerState_RUNNING + case ContainerStateStopped: + rState = pb.ContainerState_EXITED + } + c.State = &rState + + ctrs = append(ctrs, c) + } + + return &pb.ListContainersResponse{ + Containers: ctrs, + }, nil } // ContainerStatus returns status of the container.