diff --git a/daemon/mgr/cri.go b/daemon/mgr/cri.go index c16b621b8..6afdc619b 100644 --- a/daemon/mgr/cri.go +++ b/daemon/mgr/cri.go @@ -189,7 +189,30 @@ func (c *CriManager) PodSandboxStatus(ctx context.Context, r *runtime.PodSandbox // ListPodSandbox returns a list of Sandbox. func (c *CriManager) ListPodSandbox(ctx context.Context, r *runtime.ListPodSandboxRequest) (*runtime.ListPodSandboxResponse, error) { - return nil, fmt.Errorf("ListPodSandbox Not Implemented Yet") + opts := &ContainerListOption{All: true} + filter := func(c *ContainerMeta) bool { + return c.Config.Labels[containerTypeLabelKey] == containerTypeLabelSandbox + } + + // Filter *only* (sandbox) containers. + sandboxList, err := c.ContainerMgr.List(ctx, filter, opts) + if err != nil { + return nil, fmt.Errorf("failed to list sandbox: %v", err) + } + + sandboxes := make([]*runtime.PodSandbox, 0, len(sandboxList)) + for _, s := range sandboxList { + sandbox, err := toCriSandbox(s) + if err != nil { + // TODO: log an error message? + continue + } + sandboxes = append(sandboxes, sandbox) + } + + result := filterCRISandboxes(sandboxes, r.GetFilter()) + + return &runtime.ListPodSandboxResponse{Items: result}, nil } // CreateContainer creates a new container in the given PodSandbox. diff --git a/daemon/mgr/cri_test.go b/daemon/mgr/cri_test.go index 756cf2c5b..e7bb4d563 100644 --- a/daemon/mgr/cri_test.go +++ b/daemon/mgr/cri_test.go @@ -66,6 +66,21 @@ func TestSandboxNameRoundTrip(t *testing.T) { assert.Equal(t, config.Metadata, actualMetadata) } +func TestToCriSandboxState(t *testing.T) { + testCases := []struct { + input apitypes.Status + expected runtime.PodSandboxState + }{ + {input: apitypes.StatusRunning, expected: runtime.PodSandboxState_SANDBOX_READY}, + {input: apitypes.StatusExited, expected: runtime.PodSandboxState_SANDBOX_NOTREADY}, + } + + for _, test := range testCases { + actual := toCriSandboxState(test.input) + assert.Equal(t, test.expected, actual) + } +} + // Container related unit tests. func TestContainerNameRoundTrip(t *testing.T) { @@ -85,7 +100,7 @@ func TestContainerNameRoundTrip(t *testing.T) { assert.Equal(t, config.Metadata, actualMetadata) } -func TestConvertPouchStatusToCriContainerState(t *testing.T) { +func TestToCriContainerState(t *testing.T) { testCases := []struct { input apitypes.Status expected runtime.ContainerState diff --git a/daemon/mgr/cri_utils.go b/daemon/mgr/cri_utils.go index 1d41642e7..f042b2903 100644 --- a/daemon/mgr/cri_utils.go +++ b/daemon/mgr/cri_utils.go @@ -134,6 +134,64 @@ func makeSandboxPouchConfig(config *runtime.PodSandboxConfig, image string) (*ap return createConfig, nil } +func toCriSandboxState(status apitypes.Status) runtime.PodSandboxState { + switch status { + case apitypes.StatusRunning: + return runtime.PodSandboxState_SANDBOX_READY + default: + return runtime.PodSandboxState_SANDBOX_NOTREADY + } +} + +func toCriSandbox(c *ContainerMeta) (*runtime.PodSandbox, error) { + state := toCriSandboxState(c.State.Status) + metadata, err := parseSandboxName(c.Name) + if err != nil { + return nil, err + } + labels, annotations := extractLabels(c.Config.Labels) + return &runtime.PodSandbox{ + Id: c.ID, + Metadata: metadata, + State: state, + // TODO: fill "CreatedAt" when it is appropriate. + Labels: labels, + Annotations: annotations, + }, nil +} + +func filterCRISandboxes(sandboxes []*runtime.PodSandbox, filter *runtime.PodSandboxFilter) []*runtime.PodSandbox { + if filter == nil { + return sandboxes + } + + filtered := []*runtime.PodSandbox{} + for _, s := range sandboxes { + if filter.GetId() != "" && filter.GetId() != s.Id { + continue + } + if filter.GetState() != nil && filter.GetState().GetState() != s.State { + continue + } + if filter.GetLabelSelector() != nil { + match := true + for k, v := range filter.GetLabelSelector() { + value, ok := s.Labels[k] + if !ok || v != value { + match = false + break + } + } + if !match { + continue + } + } + filtered = append(filtered, s) + } + + return filtered +} + // Container related tool functions. func makeContainerName(s *runtime.PodSandboxConfig, c *runtime.ContainerConfig) string {