From de6742db115ad8df6cc17b9b7e3fbba6858a9591 Mon Sep 17 00:00:00 2001 From: Tom Wilkie Date: Mon, 5 Oct 2015 15:01:58 +0000 Subject: [PATCH 1/2] Add containers by hostname view. --- app/router.go | 9 +++++++++ probe/docker/container.go | 12 +++++++----- probe/docker/container_linux_test.go | 2 +- render/mapping.go | 22 ++++++++++++++++++++++ render/topologies.go | 19 +++++++++++++++++++ 5 files changed, 58 insertions(+), 6 deletions(-) diff --git a/app/router.go b/app/router.go index a8a5c72b0..93f58a1cd 100644 --- a/app/router.go +++ b/app/router.go @@ -224,6 +224,15 @@ var topologyRegistry = ®istry{ {"hide", "System containers hidden", true, render.FilterSystem}, }}, }, + "containers-by-hostname": { + human: "by hostname", + parent: "containers", + renderer: render.ContainerHostnameRenderer, + options: optionParams{"system": { + {"show", "System containers shown", false, nop}, + {"hide", "System containers hidden", true, render.FilterSystem}, + }}, + }, "hosts": { human: "Hosts", parent: "", diff --git a/probe/docker/container.go b/probe/docker/container.go index 113a99a63..c56d9d186 100644 --- a/probe/docker/container.go +++ b/probe/docker/container.go @@ -22,11 +22,12 @@ import ( // These constants are keys used in node metadata const ( - ContainerName = "docker_container_name" - ContainerCommand = "docker_container_command" - ContainerPorts = "docker_container_ports" - ContainerCreated = "docker_container_created" - ContainerIPs = "docker_container_ips" + ContainerName = "docker_container_name" + ContainerCommand = "docker_container_command" + ContainerPorts = "docker_container_ports" + ContainerCreated = "docker_container_created" + ContainerIPs = "docker_container_ips" + ContainerHostname = "docker_container_hostname" NetworkRxDropped = "network_rx_dropped" NetworkRxBytes = "network_rx_bytes" @@ -221,6 +222,7 @@ func (c *container) GetNode(localAddrs []net.IP) report.Node { ImageID: c.container.Image, ContainerIPs: strings.Join(append(c.container.NetworkSettings.SecondaryIPAddresses, c.container.NetworkSettings.IPAddress), " "), + ContainerHostname: c.container.Config.Hostname, }) AddLabels(result, c.container.Config.Labels) diff --git a/probe/docker/container_linux_test.go b/probe/docker/container_linux_test.go index a7a027acd..a417ae2f1 100644 --- a/probe/docker/container_linux_test.go +++ b/probe/docker/container_linux_test.go @@ -80,7 +80,7 @@ func TestContainer(t *testing.T) { test.Poll(t, 100*time.Millisecond, want, func() interface{} { node := c.GetNode([]net.IP{}) for k, v := range node.Metadata { - if v == "0" { + if v == "0" || v == "" { delete(node.Metadata, k) } } diff --git a/render/mapping.go b/render/mapping.go index 5e024e3dd..65cc51b50 100644 --- a/render/mapping.go +++ b/render/mapping.go @@ -594,6 +594,28 @@ func MapContainer2Pod(n RenderableNode, _ report.Networks) RenderableNodes { return RenderableNodes{id: result} } +// MapContainer2Hostname maps container RenderableNodes to 'hostname' renderabled nodes.. +func MapContainer2Hostname(n RenderableNode, _ report.Networks) RenderableNodes { + // Propogate all pseudo nodes + if n.Pseudo { + return RenderableNodes{n.ID: n} + } + + // Otherwise, if some some reason the container doesn't have a hostname + // (maybe slightly out of sync reports), just drop it + id, ok := n.Node.Metadata[docker.ContainerHostname] + if !ok { + return RenderableNodes{} + } + + // Add container- key to NMD, which will later be counted to produce the minor label + result := NewDerivedNode(id, n) + result.LabelMajor = id + result.Rank = id + result.Node.Counters[containersKey] = 1 + return RenderableNodes{id: result} +} + // MapCountContainers maps 1:1 container image nodes, counting // the number of containers grouped together and putting // that info in the minor label. diff --git a/render/topologies.go b/render/topologies.go index 2e3734c73..9a5ce0c60 100644 --- a/render/topologies.go +++ b/render/topologies.go @@ -171,6 +171,25 @@ var ContainerImageRenderer = Map{ }, } +// ContainerHostnameRenderer is a Renderer which produces a renderable container +// by hostname graph.. +var ContainerHostnameRenderer = Map{ + MapFunc: MapCountContainers, + Renderer: Map{ + MapFunc: MapContainer2Hostname, + Renderer: MakeReduce( + Map{ + MapFunc: MapContainer2ContainerImage, + Renderer: ContainerRenderer, + }, + Map{ + MapFunc: MapContainerImageIdentity, + Renderer: SelectContainerImage, + }, + ), + }, +} + // AddressRenderer is a Renderer which produces a renderable address // graph from the address topology. var AddressRenderer = Map{ From eaf52f4769b9456e69d617746c9e0b87a9fc2ea3 Mon Sep 17 00:00:00 2001 From: Tom Wilkie Date: Fri, 9 Oct 2015 15:14:27 +0000 Subject: [PATCH 2/2] Review feedback --- probe/docker/container.go | 12 +++++++++++- probe/docker/registry_test.go | 4 ++++ render/mapping.go | 5 +++-- render/topologies.go | 13 ++----------- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/probe/docker/container.go b/probe/docker/container.go index c56d9d186..79eb7c0eb 100644 --- a/probe/docker/container.go +++ b/probe/docker/container.go @@ -71,6 +71,7 @@ type Container interface { ID() string Image() string PID() int + Hostname() string GetNode([]net.IP) report.Node StartGatheringStats() error @@ -101,6 +102,15 @@ func (c *container) PID() int { return c.container.State.Pid } +func (c *container) Hostname() string { + if c.container.Config.Domainname == "" { + return c.container.Config.Hostname + } + + return fmt.Sprintf("%s.%s", c.container.Config.Hostname, + c.container.Config.Domainname) +} + func (c *container) StartGatheringStats() error { c.Lock() defer c.Unlock() @@ -222,7 +232,7 @@ func (c *container) GetNode(localAddrs []net.IP) report.Node { ImageID: c.container.Image, ContainerIPs: strings.Join(append(c.container.NetworkSettings.SecondaryIPAddresses, c.container.NetworkSettings.IPAddress), " "), - ContainerHostname: c.container.Config.Hostname, + ContainerHostname: c.Hostname(), }) AddLabels(result, c.container.Config.Labels) diff --git a/probe/docker/registry_test.go b/probe/docker/registry_test.go index dae59098c..6beb3791a 100644 --- a/probe/docker/registry_test.go +++ b/probe/docker/registry_test.go @@ -31,6 +31,10 @@ func (c *mockContainer) Image() string { return c.c.Image } +func (c *mockContainer) Hostname() string { + return "" +} + func (c *mockContainer) StartGatheringStats() error { return nil } diff --git a/render/mapping.go b/render/mapping.go index 65cc51b50..3b42be4ab 100644 --- a/render/mapping.go +++ b/render/mapping.go @@ -484,7 +484,7 @@ func MapContainer2ContainerImage(n RenderableNode, _ report.Networks) Renderable return RenderableNodes{} } - // Add container- key to NMD, which will later be counted to produce the minor label + // Add container id key to the counters, which will later be counted to produce the minor label result := NewDerivedNode(id, n) result.Node.Counters[containersKey] = 1 return RenderableNodes{id: result} @@ -608,10 +608,11 @@ func MapContainer2Hostname(n RenderableNode, _ report.Networks) RenderableNodes return RenderableNodes{} } - // Add container- key to NMD, which will later be counted to produce the minor label result := NewDerivedNode(id, n) result.LabelMajor = id result.Rank = id + + // Add container id key to the counters, which will later be counted to produce the minor label result.Node.Counters[containersKey] = 1 return RenderableNodes{id: result} } diff --git a/render/topologies.go b/render/topologies.go index 9a5ce0c60..242d28230 100644 --- a/render/topologies.go +++ b/render/topologies.go @@ -176,17 +176,8 @@ var ContainerImageRenderer = Map{ var ContainerHostnameRenderer = Map{ MapFunc: MapCountContainers, Renderer: Map{ - MapFunc: MapContainer2Hostname, - Renderer: MakeReduce( - Map{ - MapFunc: MapContainer2ContainerImage, - Renderer: ContainerRenderer, - }, - Map{ - MapFunc: MapContainerImageIdentity, - Renderer: SelectContainerImage, - }, - ), + MapFunc: MapContainer2Hostname, + Renderer: ContainerRenderer, }, }