-
Notifications
You must be signed in to change notification settings - Fork 1
/
docker.go
118 lines (104 loc) · 3.13 KB
/
docker.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
package main
import (
"context"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/client"
log "github.com/sirupsen/logrus"
"io"
"strings"
"time"
)
const (
mailPolicyLabel = "crony.mail_policy"
cronStringLabel = "crony.schedule"
hcUuidLabel = "crony.hcio_uuid"
)
type DockerClient struct {
cli *client.Client
evt context.CancelFunc
}
func NewDockerClient() *DockerClient {
cli, err := client.NewClientWithOpts(client.FromEnv)
cli.NegotiateAPIVersion(context.Background())
if err != nil {
log.Fatal("can't create docker client: ", err)
}
return &DockerClient{cli: cli}
}
func (d *DockerClient) ShutDown() {
_ = d.cli.Close()
if d.evt != nil {
d.evt()
}
}
type OnContainerEvent func(containerId string, containerName string)
func (d *DockerClient) RegisterDockerEventListeners(createFn OnContainerEvent, destroyFn OnContainerEvent) {
cxt, cancel := context.WithCancel(context.Background())
d.evt = cancel
go func() {
filter := filters.NewArgs()
filter.Add("type", "container")
filter.Add("event", "create")
filter.Add("event", "destroy")
msg, errChan := d.cli.Events(cxt, types.EventsOptions{
Filters: filter,
})
for {
select {
case err := <-errChan:
log.Error("got error on listening for new docker events: ", err)
case msg := <-msg:
containerName := msg.Actor.Attributes["name"]
containerId := msg.Actor.ID
log.Infof("received event: '%s' from '%s'", msg.Action, containerName)
switch msg.Action {
case "create":
createFn(containerId, containerName)
case "destroy":
destroyFn(containerId, containerName)
}
}
}
}()
}
type CronyContainer struct {
ID, Name, CronString, MailPolicy, HcUuid string
}
func (d *DockerClient) GetCronyContainers(containerId string) ([]CronyContainer, error) {
filterArgs := filters.NewArgs()
filterArgs.Add("label", cronStringLabel)
if containerId != "" {
filterArgs.Add("id", containerId)
}
containerList, err := d.cli.ContainerList(context.Background(), types.ContainerListOptions{
All: true,
Filters: filterArgs,
})
if err == nil {
var result []CronyContainer
for _, c := range containerList {
result = append(result, CronyContainer{
ID: c.ID,
Name: strings.Trim(c.Names[0], "/"),
CronString: strings.Trim(c.Labels[cronStringLabel], "\""),
MailPolicy: c.Labels[mailPolicyLabel],
HcUuid: c.Labels[hcUuidLabel],
})
}
return result, nil
}
return nil, err
}
func (d *DockerClient) ContainerWait(name string) (<-chan container.ContainerWaitOKBody, <-chan error) {
return d.cli.ContainerWait(context.Background(), name, container.WaitConditionNotRunning)
}
func (d *DockerClient) ContainerLogs(name string, startTime time.Time) (io.ReadCloser, error) {
return d.cli.ContainerLogs(context.Background(), name, types.ContainerLogsOptions{ShowStdout: true,
ShowStderr: true,
Since: startTime.Format("2006-01-02T15:04:05")})
}
func (d *DockerClient) ContainerStart(name string) error {
return d.cli.ContainerStart(context.Background(), name, types.ContainerStartOptions{})
}