From 327b909956534601ee33bee7b0f1392e9c0fa2ed Mon Sep 17 00:00:00 2001 From: Mike Lang Date: Wed, 12 Apr 2017 17:01:20 -0700 Subject: [PATCH] probe/docker: Populate SwarmService topology based on docker labels This isn't the best way to do it, but it will work well enough for an initial implementation --- probe/docker/reporter.go | 10 ++++++++++ probe/docker/tagger.go | 27 +++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/probe/docker/reporter.go b/probe/docker/reporter.go index 44efb69e4..7b68e5eda 100644 --- a/probe/docker/reporter.go +++ b/probe/docker/reporter.go @@ -21,6 +21,7 @@ const ( ImageLabelPrefix = "docker_image_label_" IsInHostNetwork = "docker_is_in_host_network" ImageTableID = "image_table" + ServiceName = "service_name" ) // Exposed for testing @@ -132,6 +133,10 @@ var ( Rank: 8, }, } + + SwarmServiceMetadataTemplates = report.MetadataTemplates{ + ServiceName: {ID: ServiceName, Label: "Service Name", From: report.FromLatest, Priority: 0}, + } ) // Reporter generate Reports containing Container and ContainerImage topologies @@ -177,6 +182,7 @@ func (r *Reporter) Report() (report.Report, error) { result.Container = result.Container.Merge(r.containerTopology(localAddrs)) result.ContainerImage = result.ContainerImage.Merge(r.containerImageTopology()) result.Overlay = result.Overlay.Merge(r.overlayTopology()) + result.SwarmService = result.SwarmService.Merge(r.swarmServiceTopology()) return result, nil } @@ -298,6 +304,10 @@ func (r *Reporter) overlayTopology() report.Topology { return report.MakeTopology().AddNode(node) } +func (r *Reporter) swarmServiceTopology() report.Topology { + return report.MakeTopology().WithMetadataTemplates(SwarmServiceMetadataTemplates) +} + // Docker sometimes prefixes ids with a "type" annotation, but it renders a bit // ugly and isn't necessary, so we should strip it off func trimImageID(id string) string { diff --git a/probe/docker/tagger.go b/probe/docker/tagger.go index 79f515ca4..df4e00930 100644 --- a/probe/docker/tagger.go +++ b/probe/docker/tagger.go @@ -2,6 +2,7 @@ package docker import ( "strconv" + "strings" "github.com/weaveworks/scope/probe/process" "github.com/weaveworks/scope/report" @@ -21,6 +22,7 @@ var ( // Tagger is a tagger that tags Docker container information to process // nodes that have a PID. +// It also populates the SwarmService topology if any of the associated docker labels are present. type Tagger struct { registry Registry procWalker process.Walker @@ -44,6 +46,31 @@ func (t *Tagger) Tag(r report.Report) (report.Report, error) { return report.MakeReport(), err } t.tag(tree, &r.Process) + + // Scan for Swarm service info + for containerID, container := range r.Container.Nodes { + serviceID, ok := container.Latest.Lookup(LabelPrefix + "com.docker.swarm.service.id") + if !ok { + continue + } + serviceName, ok := container.Latest.Lookup(LabelPrefix + "com.docker.swarm.service.name") + if !ok { + continue + } + + if strings.HasPrefix(serviceName, "dockerswarm_") { + serviceName = serviceName[len("dockerswarm_"):] + } + + nodeID := report.MakeSwarmServiceNodeID(serviceID) + node := report.MakeNodeWith(nodeID, map[string]string{ + ServiceName: serviceName, + }) + r.SwarmService = r.SwarmService.AddNode(node) + + r.Container.Nodes[containerID] = container.WithParents(container.Parents.Add(report.SwarmService, report.MakeStringSet(nodeID))) + } + return r, nil }