...
1
2
3
4
5
6
7
8
9
10
11
12
13
14 package docker
15
16 import (
17 "context"
18 "fmt"
19 "net/http"
20
21 "github.com/docker/docker/api/types"
22 dockerclient "github.com/docker/docker/client"
23
24 "github.com/chaos-mesh/chaos-mesh/pkg/mock"
25 )
26
27 const (
28 dockerProtocolPrefix = "docker://"
29 )
30
31
32 type DockerClientInterface interface {
33 ContainerInspect(ctx context.Context, containerID string) (types.ContainerJSON, error)
34 ContainerKill(ctx context.Context, containerID, signal string) error
35 }
36
37
38 type DockerClient struct {
39 client DockerClientInterface
40 }
41
42
43 func (c DockerClient) FormatContainerID(ctx context.Context, containerID string) (string, error) {
44 if len(containerID) < len(dockerProtocolPrefix) {
45 return "", fmt.Errorf("container id %s is not a docker container id", containerID)
46 }
47 if containerID[0:len(dockerProtocolPrefix)] != dockerProtocolPrefix {
48 return "", fmt.Errorf("expected %s but got %s", dockerProtocolPrefix, containerID[0:len(dockerProtocolPrefix)])
49 }
50 return containerID[len(dockerProtocolPrefix):], nil
51 }
52
53
54 func (c DockerClient) GetPidFromContainerID(ctx context.Context, containerID string) (uint32, error) {
55 id, err := c.FormatContainerID(ctx, containerID)
56 if err != nil {
57 return 0, err
58 }
59 container, err := c.client.ContainerInspect(ctx, id)
60 if err != nil {
61 return 0, err
62 }
63
64 if container.State.Pid == 0 {
65 return 0, fmt.Errorf("container is not running, status: %s", container.State.Status)
66 }
67
68 return uint32(container.State.Pid), nil
69 }
70
71
72 func (c DockerClient) ContainerKillByContainerID(ctx context.Context, containerID string) error {
73 id, err := c.FormatContainerID(ctx, containerID)
74 if err != nil {
75 return err
76 }
77 err = c.client.ContainerKill(ctx, id, "SIGKILL")
78
79 return err
80 }
81
82 func New(host string, version string, client *http.Client, httpHeaders map[string]string) (*DockerClient, error) {
83
84 if err := mock.On("NewDockerClientError"); err != nil {
85 return nil, err.(error)
86 }
87 if client := mock.On("MockDockerClient"); client != nil {
88 return &DockerClient{
89 client: client.(DockerClientInterface),
90 }, nil
91 }
92
93 c, err := dockerclient.NewClientWithOpts(
94 dockerclient.WithHost(host),
95 dockerclient.WithVersion(version),
96 dockerclient.WithHTTPClient(client),
97 dockerclient.WithHTTPHeaders(httpHeaders))
98 if err != nil {
99 return nil, err
100 }
101
102 return &DockerClient{
103 client: c,
104 }, nil
105 }
106