...
1
2
3
4
5
6
7
8
9
10
11
12
13
14 package containerd
15
16 import (
17 "context"
18 "fmt"
19 "syscall"
20
21 "github.com/containerd/containerd"
22
23 "github.com/chaos-mesh/chaos-mesh/pkg/mock"
24 )
25
26 const (
27 containerdProtocolPrefix = "containerd://"
28 )
29
30
31 type ContainerdClientInterface interface {
32 LoadContainer(ctx context.Context, id string) (containerd.Container, error)
33 }
34
35
36 type ContainerdClient struct {
37 client ContainerdClientInterface
38 }
39
40
41 func (c ContainerdClient) FormatContainerID(ctx context.Context, containerID string) (string, error) {
42 if len(containerID) < len(containerdProtocolPrefix) {
43 return "", fmt.Errorf("container id %s is not a containerd container id", containerID)
44 }
45 if containerID[0:len(containerdProtocolPrefix)] != containerdProtocolPrefix {
46 return "", fmt.Errorf("expected %s but got %s", containerdProtocolPrefix, containerID[0:len(containerdProtocolPrefix)])
47 }
48 return containerID[len(containerdProtocolPrefix):], nil
49 }
50
51
52 func (c ContainerdClient) GetPidFromContainerID(ctx context.Context, containerID string) (uint32, error) {
53 id, err := c.FormatContainerID(ctx, containerID)
54 if err != nil {
55 return 0, err
56 }
57 container, err := c.client.LoadContainer(ctx, id)
58 if err != nil {
59 return 0, err
60 }
61 task, err := container.Task(ctx, nil)
62 if err != nil {
63 return 0, err
64 }
65 return task.Pid(), nil
66 }
67
68
69 func (c ContainerdClient) ContainerKillByContainerID(ctx context.Context, containerID string) error {
70 containerID, err := c.FormatContainerID(ctx, containerID)
71 if err != nil {
72 return err
73 }
74
75 container, err := c.client.LoadContainer(ctx, containerID)
76 if err != nil {
77 return err
78 }
79 task, err := container.Task(ctx, nil)
80 if err != nil {
81 return err
82 }
83
84 err = task.Kill(ctx, syscall.SIGKILL)
85
86 return err
87 }
88
89 func New(address string, opts ...containerd.ClientOpt) (*ContainerdClient, error) {
90
91 if err := mock.On("NewContainerdClientError"); err != nil {
92 return nil, err.(error)
93 }
94 if client := mock.On("MockContainerdClient"); client != nil {
95 return &ContainerdClient{
96 client.(ContainerdClientInterface),
97 }, nil
98 }
99
100 c, err := containerd.New(address, opts...)
101 if err != nil {
102 return nil, err
103 }
104
105 return &ContainerdClient{
106 client: c,
107 }, nil
108 }
109
110
111 var WithDefaultNamespace = containerd.WithDefaultNamespace
112