This repository has been archived by the owner on Feb 1, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
cluster.go
113 lines (94 loc) · 2.2 KB
/
cluster.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
package cluster
import (
"errors"
"strings"
"sync"
log "github.com/Sirupsen/logrus"
)
var (
ErrNodeNotConnected = errors.New("node is not connected to docker's REST API")
ErrNodeAlreadyRegistered = errors.New("node was already added to the cluster")
)
type Cluster struct {
sync.RWMutex
eventHandlers []EventHandler
nodes map[string]*Node
}
func NewCluster() *Cluster {
return &Cluster{
nodes: make(map[string]*Node),
}
}
func (c *Cluster) Handle(e *Event) error {
for _, eventHandler := range c.eventHandlers {
if err := eventHandler.Handle(e); err != nil {
log.Error(err)
}
}
return nil
}
// Register a node within the cluster. The node must have been already
// initialized.
func (c *Cluster) AddNode(n *Node) error {
if !n.IsConnected() {
return ErrNodeNotConnected
}
c.Lock()
defer c.Unlock()
if _, exists := c.nodes[n.ID]; exists {
return ErrNodeAlreadyRegistered
}
c.nodes[n.ID] = n
return n.Events(c)
}
// Containers returns all the containers in the cluster.
func (c *Cluster) Containers() []*Container {
c.Lock()
defer c.Unlock()
out := []*Container{}
for _, n := range c.nodes {
containers := n.Containers()
for _, container := range containers {
out = append(out, container)
}
}
return out
}
// Container returns the container with ID in the cluster
func (c *Cluster) Container(IdOrName string) *Container {
for _, container := range c.Containers() {
// Match ID prefix.
if strings.HasPrefix(container.Id, IdOrName) {
return container
}
// Match name, /name or engine/name.
for _, name := range container.Names {
if name == IdOrName || name == "/"+IdOrName || container.node.ID+name == IdOrName || container.node.Name+name == IdOrName {
return container
}
}
}
return nil
}
// Nodes returns the list of nodes in the cluster
func (c *Cluster) Nodes() []*Node {
nodes := []*Node{}
c.RLock()
for _, node := range c.nodes {
nodes = append(nodes, node)
}
c.RUnlock()
return nodes
}
func (c *Cluster) Node(addr string) *Node {
for _, node := range c.nodes {
if node.Addr == addr {
return node
}
}
return nil
}
func (c *Cluster) Events(h EventHandler) error {
c.eventHandlers = append(c.eventHandlers, h)
return nil
}