Merge pull request #400 from weaveworks/docker-labels

Report docker container labels and render them in the details pane
This commit is contained in:
Alfonso Acosta
2015-08-27 14:11:35 +01:00
8 changed files with 102 additions and 7 deletions

View File

@@ -216,6 +216,7 @@ func (c *container) GetNodeMetadata() report.NodeMetadata {
ContainerIPs: strings.Join(append(c.container.NetworkSettings.SecondaryIPAddresses,
c.container.NetworkSettings.IPAddress), " "),
})
AddLabels(result, c.container.Config.Labels)
if c.latestStats == nil {
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

@@ -106,12 +106,24 @@ var (
NetworkSettings: &client.NetworkSettings{
IPAddress: "1.2.3.4",
},
Config: &client.Config{
Labels: map[string]string{
"foo1": "bar1",
"foo2": "bar2",
},
},
}
container2 = &client.Container{
ID: "wiff",
Name: "waff",
Image: "baz",
State: client.State{Pid: 1, Running: true},
Config: &client.Config{
Labels: map[string]string{
"foo1": "bar1",
"foo2": "bar2",
},
},
}
apiContainer1 = client.APIContainers{ID: "ping"}
apiImage1 = client.APIImages{ID: "baz", RepoTags: []string{"bang", "not-chosen"}}

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,6 +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: ""})
}
rows = append(rows, getDockerLabelRows(nmd)...)
if val, ok := nmd.Metadata[docker.MemoryUsage]; ok {
memory, err := strconv.ParseFloat(val, 64)
@@ -349,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
@@ -365,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

@@ -58,6 +58,8 @@ func TestOriginTable(t *testing.T) {
{"Host", test.ServerHostID, "", false},
{"ID", test.ServerContainerID, "", false},
{"Image ID", test.ServerContainerImageID, "", false},
{`Label "foo1"`, `bar1`, "", false},
{`Label "foo2"`, `bar2`, "", false},
},
},
} {
@@ -146,6 +148,8 @@ func TestMakeDetailedContainerNode(t *testing.T) {
Rows: []render.Row{
{"ID", test.ServerContainerID, "", false},
{"Image ID", test.ServerContainerImageID, "", false},
{`Label "foo1"`, `bar1`, "", false},
{`Label "foo2"`, `bar2`, "", false},
},
},
{

View File

@@ -174,10 +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.ContainerID: ServerContainerID,
docker.ContainerName: "server",
docker.ImageID: ServerContainerImageID,
report.HostNodeID: ServerHostNodeID,
docker.LabelPrefix + "foo1": "bar1",
docker.LabelPrefix + "foo2": "bar2",
}),
},
},
@@ -189,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",
}),
},
},