Add 'latest' CRDT; use it to store container state.

Also use same technique to merge the controls, returning the latest
set of controls instead of the union.
This commit is contained in:
Tom Wilkie
2015-11-05 18:00:15 +00:00
parent f7c75f9cd3
commit 43d0ce986f
23 changed files with 867 additions and 43 deletions

View File

@@ -264,12 +264,11 @@ func (c *container) GetNode(hostID string, localAddrs []net.IP) report.Node {
ContainerCommand: c.container.Path + " " + strings.Join(c.container.Args, " "),
ImageID: c.container.Image,
ContainerHostname: c.Hostname(),
ContainerState: state,
}).WithSets(report.Sets{
ContainerPorts: c.ports(localAddrs),
ContainerIPs: report.MakeStringSet(ips...),
ContainerIPsWithScopes: report.MakeStringSet(ipsWithScopes...),
})
}).WithLatest(ContainerState, state)
if c.container.State.Paused {
result = result.WithControls(UnpauseContainer)
@@ -285,7 +284,7 @@ func (c *container) GetNode(hostID string, localAddrs []net.IP) report.Node {
return result
}
result = result.Merge(report.MakeNodeWith(map[string]string{
result = result.WithMetadata(map[string]string{
NetworkRxDropped: strconv.FormatUint(c.latestStats.Network.RxDropped, 10),
NetworkRxBytes: strconv.FormatUint(c.latestStats.Network.RxBytes, 10),
NetworkRxErrors: strconv.FormatUint(c.latestStats.Network.RxErrors, 10),
@@ -305,7 +304,8 @@ func (c *container) GetNode(hostID string, localAddrs []net.IP) report.Node {
CPUTotalUsage: strconv.FormatUint(c.latestStats.CPUStats.CPUUsage.TotalUsage, 10),
CPUUsageInKernelmode: strconv.FormatUint(c.latestStats.CPUStats.CPUUsage.UsageInKernelmode, 10),
CPUSystemCPUUsage: strconv.FormatUint(c.latestStats.CPUStats.SystemCPUUsage, 10),
}))
})
return result
}

View File

@@ -74,12 +74,14 @@ func TestContainer(t *testing.T) {
"docker_label_foo1": "bar1",
"docker_label_foo2": "bar2",
"memory_usage": "12345",
"docker_container_state": "running",
}).WithSets(report.Sets{
"docker_container_ports": report.MakeStringSet("1.2.3.4:80->80/tcp", "81/tcp"),
"docker_container_ips": report.MakeStringSet("1.2.3.4"),
"docker_container_ips_with_scopes": report.MakeStringSet("scope;1.2.3.4"),
}).WithControls(docker.RestartContainer, docker.StopContainer, docker.PauseContainer)
}).WithControls(
docker.RestartContainer, docker.StopContainer, docker.PauseContainer,
).WithLatest("docker_container_state", "running")
test.Poll(t, 100*time.Millisecond, want, func() interface{} {
node := c.GetNode("scope", []net.IP{})
for k, v := range node.Metadata {

View File

@@ -23,16 +23,16 @@ func NewTagger(hostID, probeID string) Tagger {
// Tag implements Tagger.
func (t Tagger) Tag(r report.Report) (report.Report, error) {
other := report.MakeNodeWith(map[string]string{
metadata := map[string]string{
report.HostNodeID: t.hostNodeID,
report.ProbeID: t.probeID,
})
}
// Explicity don't tag Endpoints and Addresses - These topologies include pseudo nodes,
// and as such do their own host tagging
for _, topology := range []report.Topology{r.Process, r.Container, r.ContainerImage, r.Host, r.Overlay} {
for id := range topology.Nodes {
topology.AddNode(id, other)
for id, node := range topology.Nodes {
topology.AddNode(id, node.WithMetadata(metadata))
}
}
return r, nil

View File

@@ -57,9 +57,9 @@ func (topologyTagger) Tag(r report.Report) (report.Report, error) {
"host": &(r.Host),
"overlay": &(r.Overlay),
} {
other := report.MakeNodeWith(map[string]string{Topology: val})
for id := range topology.Nodes {
topology.AddNode(id, other)
metadata := map[string]string{Topology: val}
for id, node := range topology.Nodes {
topology.AddNode(id, node.WithMetadata(metadata))
}
}
return r, nil

View File

@@ -5,7 +5,6 @@ import (
"testing"
"github.com/weaveworks/scope/report"
"github.com/weaveworks/scope/test"
)
func TestApply(t *testing.T) {
@@ -38,11 +37,9 @@ func TestApply(t *testing.T) {
func TestTagMissingID(t *testing.T) {
const nodeID = "not-found"
r := report.MakeReport()
want := report.MakeNode()
rpt, _ := newTopologyTagger().Tag(r)
have := rpt.Endpoint.Nodes[nodeID].Copy()
if !reflect.DeepEqual(want, have) {
t.Error(test.Diff(want, have))
_, ok := rpt.Endpoint.Nodes[nodeID]
if ok {
t.Error("TopologyTagger erroneously tagged a missing node ID")
}
}