Browse Source

First-pass rewrite of docker code

master
Chris Smith 5 years ago
parent
commit
ba43f3c7ed
1 changed files with 87 additions and 0 deletions
  1. 87
    0
      docker.go

+ 87
- 0
docker.go View File

@@ -0,0 +1,87 @@
1
+package main
2
+
3
+import (
4
+	"fmt"
5
+	"github.com/csmith/dotege/model"
6
+	"github.com/docker/docker/api/types"
7
+	"github.com/docker/docker/api/types/events"
8
+	"github.com/docker/docker/api/types/filters"
9
+	"golang.org/x/net/context"
10
+)
11
+
12
+type DockerClient interface {
13
+	Events(ctx context.Context, options types.EventsOptions) (<-chan events.Message, <-chan error)
14
+	ContainerList(ctx context.Context, options types.ContainerListOptions) ([]types.Container, error)
15
+	ContainerInspect(ctx context.Context, containerID string) (types.ContainerJSON, error)
16
+}
17
+
18
+func monitorContainers(client DockerClient, stop <-chan struct{}, addedFn func(model.Container), removedFn func(string)) error {
19
+	ctx, cancel := context.WithCancel(context.Background())
20
+	stream, errors := startEventStream(client, ctx)
21
+
22
+	if err := publishExistingContainers(client, ctx, addedFn); err != nil {
23
+		cancel()
24
+		return err
25
+	}
26
+
27
+	for {
28
+		select {
29
+		case event := <-stream:
30
+			if event.Action == "create" {
31
+				err, container := inspectContainer(client, ctx, event.Actor.ID)
32
+				if err != nil {
33
+					cancel()
34
+					return err
35
+				}
36
+				addedFn(container)
37
+			} else {
38
+				removedFn(event.Actor.Attributes["name"])
39
+			}
40
+
41
+		case err := <-errors:
42
+			cancel()
43
+			return err
44
+
45
+		case <-stop:
46
+			cancel()
47
+			return nil
48
+		}
49
+	}
50
+}
51
+
52
+func startEventStream(client DockerClient, ctx context.Context) (<-chan events.Message, <-chan error) {
53
+	args := filters.NewArgs()
54
+	args.Add("type", "container")
55
+	args.Add("event", "create")
56
+	args.Add("event", "destroy")
57
+	return client.Events(ctx, types.EventsOptions{Filters: args})
58
+}
59
+
60
+func publishExistingContainers(client DockerClient, ctx context.Context, addedFn func(model.Container)) error {
61
+	containers, err := client.ContainerList(ctx, types.ContainerListOptions{})
62
+	if err != nil {
63
+		return fmt.Errorf("unable to list containers: %s", err.Error())
64
+	}
65
+
66
+	for _, container := range containers {
67
+		addedFn(model.Container{
68
+			Id:     container.ID,
69
+			Name:   container.Names[0][1:],
70
+			Labels: container.Labels,
71
+		})
72
+	}
73
+	return nil
74
+}
75
+
76
+func inspectContainer(client DockerClient, ctx context.Context, id string) (error, model.Container) {
77
+	container, err := client.ContainerInspect(ctx, id)
78
+	if err != nil {
79
+		return err, model.Container{}
80
+	}
81
+
82
+	return nil, model.Container{
83
+		Id:     container.ID,
84
+		Name:   container.Name[1:],
85
+		Labels: container.Config.Labels,
86
+	}
87
+}

Loading…
Cancel
Save