diff --git a/probe/docker/container.go b/probe/docker/container.go index db2c3e291..42bee395d 100644 --- a/probe/docker/container.go +++ b/probe/docker/container.go @@ -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 -} diff --git a/probe/docker/labels.go b/probe/docker/labels.go new file mode 100644 index 000000000..2cc6a8dd4 --- /dev/null +++ b/probe/docker/labels.go @@ -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 +} diff --git a/probe/docker/labels_test.go b/probe/docker/labels_test.go new file mode 100644 index 000000000..45c295e0d --- /dev/null +++ b/probe/docker/labels_test.go @@ -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)) + } +} diff --git a/probe/docker/reporter.go b/probe/docker/reporter.go index 587fcff28..5f499557f 100644 --- a/probe/docker/reporter.go +++ b/probe/docker/reporter.go @@ -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] diff --git a/render/detailed_node.go b/render/detailed_node.go index 24bd51a6d..c5fd927b9 100644 --- a/render/detailed_node.go +++ b/render/detailed_node.go @@ -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 }{ diff --git a/test/report_fixture.go b/test/report_fixture.go index 1c64cef40..cb9ac84a4 100644 --- a/test/report_fixture.go +++ b/test/report_fixture.go @@ -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", }), }, },