/
sandbox_list.go
128 lines (112 loc) · 3.9 KB
/
sandbox_list.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/*
Copyright 2021 Mirantis
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package core
import (
"context"
"github.com/Mirantis/cri-dockerd/libdocker"
"github.com/Mirantis/cri-dockerd/store"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/sirupsen/logrus"
v1 "k8s.io/cri-api/pkg/apis/runtime/v1"
)
// ListPodSandbox returns a list of Sandbox.
func (ds *dockerService) ListPodSandbox(
_ context.Context,
r *v1.ListPodSandboxRequest,
) (*v1.ListPodSandboxResponse, error) {
filter := r.GetFilter()
// By default, list all containers whether they are running or not.
opts := types.ContainerListOptions{All: true}
filterOutReadySandboxes := false
opts.Filters = filters.NewArgs()
f := NewDockerFilter(&opts.Filters)
// Add filter to select only sandbox containers.
f.AddLabel(containerTypeLabelKey, containerTypeLabelSandbox)
if filter != nil {
if filter.Id != "" {
f.Add("id", filter.Id)
}
if filter.State != nil {
if filter.GetState().State == v1.PodSandboxState_SANDBOX_READY {
// Only list running containers.
opts.All = false
} else {
// runtimeapi.PodSandboxState_SANDBOX_NOTREADY can mean the
// container is in any of the non-running state (e.g., created,
// exited). We can't tell docker to filter out running
// containers directly, so we'll need to filter them out
// ourselves after getting the results.
filterOutReadySandboxes = true
}
}
if filter.LabelSelector != nil {
for k, v := range filter.LabelSelector {
f.AddLabel(k, v)
}
}
}
// Make sure we get the list of checkpoints first so that we don't include
// new PodSandboxes that are being created right now.
var err error
checkpoints := []string{}
if filter == nil {
checkpoints, err = ds.checkpointManager.ListCheckpoints()
if err != nil {
logrus.Errorf("Failed to list checkpoints: %v", err)
}
}
containers, err := ds.client.ListContainers(opts)
if err != nil && !libdocker.IsContainerNotFoundError(err) {
return nil, err
}
// Convert docker containers to runtime api sandboxes.
result := []*v1.PodSandbox{}
// using map as set
sandboxIDs := make(map[string]bool)
for i := range containers {
c := containers[i]
converted, err := containerToRuntimeAPISandbox(&c)
if err != nil {
logrus.Infof("Unable to convert docker container(s) %v to runtime API sandbox: %v", c.Names, err)
continue
}
if filterOutReadySandboxes && converted.State == v1.PodSandboxState_SANDBOX_READY {
continue
}
sandboxIDs[converted.Id] = true
result = append(result, converted)
}
// Include sandbox that could only be found with its checkpoint if no filter is applied
// These PodSandbox will only include PodSandboxID, Name, Namespace.
// These PodSandbox will be in PodSandboxState_SANDBOX_NOTREADY state.
for _, id := range checkpoints {
if _, ok := sandboxIDs[id]; ok {
continue
}
checkpoint := NewPodSandboxCheckpoint("", "", &CheckpointData{})
err := ds.checkpointManager.GetCheckpoint(id, checkpoint)
if err != nil {
logrus.Errorf("Failed to retrieve checkpoint for sandbox %s: %v", id, err)
if err == store.ErrCorruptCheckpoint {
err = ds.checkpointManager.RemoveCheckpoint(id)
if err != nil {
logrus.Errorf("Failed to delete corrupt checkpoint for sandbox %s: %v", id, err)
}
}
continue
}
result = append(result, checkpointToRuntimeAPISandbox(id, checkpoint))
}
return &v1.ListPodSandboxResponse{Items: result}, nil
}