Report/render both image and container labels

Daemon labels will have to wait since the go client (Docker API v1.14) doesn't support
them yet (daemon labels were exposed in Docker API v1.16)

See https://godoc.org/github.com/fsouza/go-dockerclient#Client.Info for details.
This commit is contained in:
Alfonso Acosta
2015-08-26 16:41:42 +00:00
parent 529aa3d84f
commit 9ba37402cf
6 changed files with 91 additions and 44 deletions

View File

@@ -10,7 +10,6 @@ import (
"net/http"
"net/http/httputil"
"net/url"
"sort"
"strconv"
"strings"
"sync"
@@ -23,12 +22,11 @@ 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"
ContainerLabelPrefix = "docker_container_label_"
ContainerName = "docker_container_name"
ContainerCommand = "docker_container_command"
ContainerPorts = "docker_container_ports"
ContainerCreated = "docker_container_created"
ContainerIPs = "docker_container_ips"
NetworkRxDropped = "network_rx_dropped"
NetworkRxBytes = "network_rx_bytes"
@@ -218,17 +216,7 @@ func (c *container) GetNodeMetadata() report.NodeMetadata {
ContainerIPs: strings.Join(append(c.container.NetworkSettings.SecondaryIPAddresses,
c.container.NetworkSettings.IPAddress), " "),
})
// Add labels in alphabetical order
labels := c.container.Config.Labels
labelKeys := make([]string, 0, len(labels))
for k := range labels {
labelKeys = append(labelKeys, k)
}
sort.Strings(labelKeys)
for _, labelKey := range labelKeys {
result.Metadata[ContainerLabelPrefix+labelKey] = labels[labelKey]
}
AddLabels(result, c.container.Config.Labels)
if c.latestStats == nil {
return result
@@ -262,15 +250,3 @@ func (c *container) GetNodeMetadata() report.NodeMetadata {
func ExtractContainerIPs(nmd report.NodeMetadata) []string {
return strings.Fields(nmd.Metadata[ContainerIPs])
}
// ExtractContainerLabels returns the list of Docker container labels given a NodeMetadata from the Container topology.
func ExtractContainerLabels(nmd report.NodeMetadata) map[string]string {
result := map[string]string{}
for key, value := range nmd.Metadata {
if strings.HasPrefix(key, ContainerLabelPrefix) {
label := key[len(ContainerLabelPrefix):]
result[label] = value
}
}
return result
}

31
probe/docker/labels.go Normal file
View File

@@ -0,0 +1,31 @@
package docker
import (
"strings"
"github.com/weaveworks/scope/report"
)
// LabelPrefix is the key prefix used for Docker labels in NodeMetadata (e.g. a
// Docker label "labelKey"="labelValue" will get encoded as
// "docker_label_labelKey"="dockerValue" in the metadata)
const LabelPrefix = "docker_label_"
// AddLabels appends Docker labels to the NodeMetadata from a topology.
func AddLabels(nmd report.NodeMetadata, labels map[string]string) {
for key, value := range labels {
nmd.Metadata[LabelPrefix+key] = value
}
}
// ExtractLabels returns the list of Docker labels given a NodeMetadata from a topology.
func ExtractLabels(nmd report.NodeMetadata) map[string]string {
result := map[string]string{}
for key, value := range nmd.Metadata {
if strings.HasPrefix(key, LabelPrefix) {
label := key[len(LabelPrefix):]
result[label] = value
}
}
return result
}

View File

@@ -0,0 +1,25 @@
package docker_test
import (
"reflect"
"testing"
"github.com/weaveworks/scope/probe/docker"
"github.com/weaveworks/scope/report"
"github.com/weaveworks/scope/test"
)
func TestLabels(t *testing.T) {
want := map[string]string{
"foo1": "bar1",
"foo2": "bar2",
}
nmd := report.MakeNodeMetadata()
docker.AddLabels(nmd, want)
have := docker.ExtractLabels(nmd)
if !reflect.DeepEqual(want, have) {
t.Error(test.Diff(want, have))
}
}

View File

@@ -52,6 +52,7 @@ func (r *Reporter) containerImageTopology() report.Topology {
nmd := report.MakeNodeMetadataWith(map[string]string{
ImageID: image.ID,
})
AddLabels(nmd, image.Labels)
if len(image.RepoTags) > 0 {
nmd.Metadata[ImageName] = image.RepoTags[0]

View File

@@ -312,11 +312,7 @@ func containerOriginTable(nmd report.NodeMetadata, addHostTag bool) (Table, bool
for _, ip := range docker.ExtractContainerIPs(nmd) {
rows = append(rows, Row{Key: "IP Address", ValueMajor: ip, ValueMinor: ""})
}
for labelKey, labelValue := range docker.ExtractContainerLabels(nmd) {
rows = append(rows, Row{Key: fmt.Sprintf("Label %q", labelKey), ValueMajor: labelValue})
}
rows = append(rows, getDockerLabelRows(nmd)...)
if val, ok := nmd.Metadata[docker.MemoryUsage]; ok {
memory, err := strconv.ParseFloat(val, 64)
@@ -354,6 +350,7 @@ func containerImageOriginTable(nmd report.NodeMetadata) (Table, bool) {
rows = append(rows, Row{Key: tuple.human, ValueMajor: val, ValueMinor: ""})
}
}
rows = append(rows, getDockerLabelRows(nmd)...)
title := "Container Image"
var (
nameFound bool
@@ -370,6 +367,21 @@ func containerImageOriginTable(nmd report.NodeMetadata) (Table, bool) {
}, len(rows) > 0 || nameFound
}
func getDockerLabelRows(nmd report.NodeMetadata) []Row {
rows := []Row{}
// Add labels in alphabetical order
labels := docker.ExtractLabels(nmd)
labelKeys := make([]string, 0, len(labels))
for k := range labels {
labelKeys = append(labelKeys, k)
}
sort.Strings(labelKeys)
for _, labelKey := range labelKeys {
rows = append(rows, Row{Key: fmt.Sprintf("Label %q", labelKey), ValueMajor: labels[labelKey]})
}
return rows
}
func hostOriginTable(nmd report.NodeMetadata) (Table, bool) {
rows := []Row{}
for _, tuple := range []struct{ key, human string }{

View File

@@ -174,12 +174,12 @@ var (
report.HostNodeID: ClientHostNodeID,
}),
ServerContainerNodeID: report.MakeNodeMetadataWith(map[string]string{
docker.ContainerID: ServerContainerID,
docker.ContainerName: "server",
docker.ImageID: ServerContainerImageID,
report.HostNodeID: ServerHostNodeID,
docker.ContainerLabelPrefix + "foo1": "bar1",
docker.ContainerLabelPrefix + "foo2": "bar2",
docker.ContainerID: ServerContainerID,
docker.ContainerName: "server",
docker.ImageID: ServerContainerImageID,
report.HostNodeID: ServerHostNodeID,
docker.LabelPrefix + "foo1": "bar1",
docker.LabelPrefix + "foo2": "bar2",
}),
},
},
@@ -191,9 +191,11 @@ var (
report.HostNodeID: ClientHostNodeID,
}),
ServerContainerImageNodeID: report.MakeNodeMetadataWith(map[string]string{
docker.ImageID: ServerContainerImageID,
docker.ImageName: ServerContainerImageName,
report.HostNodeID: ServerHostNodeID,
docker.ImageID: ServerContainerImageID,
docker.ImageName: ServerContainerImageName,
report.HostNodeID: ServerHostNodeID,
docker.LabelPrefix + "foo1": "bar1",
docker.LabelPrefix + "foo2": "bar2",
}),
},
},