Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove unnecessary metadata propagation #3007

Merged
merged 13 commits into from
Dec 29, 2017
30 changes: 12 additions & 18 deletions render/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func (c connectionJoin) Render(rpt report.Report) Nodes {
// Nodes without a hostid may be pseudo nodes - if so, pass through to result
if _, ok := m.Latest.Lookup(report.HostNodeID); !ok {
if id, ok := externalNodeID(m, addr, local); ok {
ret.addChild(m, id, newPseudoNode)
ret.addChild(m, id, Pseudo)
continue
}
}
Expand All @@ -94,8 +94,9 @@ func (c connectionJoin) Render(rpt report.Report) Nodes {
id, found = ipNodes[report.MakeScopedEndpointNodeID(scope, addr, port)]
}
if found && id != "" { // not one we blanked out earlier
// We are guaranteed to find the id, so no need to pass a node constructor.
ret.addChild(m, id, nil)
// We are guaranteed to find the id, so really this should
// never end up creating a node.
ret.addChild(m, id, report.Container)
}
}
return ret.result(endpoints)
Expand Down Expand Up @@ -268,9 +269,7 @@ func MapProcess2Container(n report.Node) report.Nodes {
}

// Otherwise, if the process is not in a container, group it into
// an per-host "Uncontained" node. If for whatever reason this
// node doesn't have a host id in their node metadata, it'll all
// get grouped into a single uncontained node.
// a per-host "Uncontained" node.
var (
id string
node report.Node
Expand All @@ -279,10 +278,9 @@ func MapProcess2Container(n report.Node) report.Nodes {
id = report.MakeContainerNodeID(containerID)
node = NewDerivedNode(id, n).WithTopology(report.Container)
} else {
id = MakePseudoNodeID(UncontainedID, report.ExtractHostID(n))
hostID, _, _ := report.ParseProcessNodeID(n.ID)
id = MakePseudoNodeID(UncontainedID, hostID)
node = NewDerivedPseudoNode(id, n)
node = propagateLatest(report.HostNodeID, n, node)
node = propagateLatest(IsConnectedMark, n, node)
}
return report.Nodes{id: node}
}
Expand All @@ -307,7 +305,7 @@ func MapContainer2ContainerImage(n report.Node) report.Nodes {

// Otherwise, if some some reason the container doesn't have a image_id
// (maybe slightly out of sync reports), just drop it
imageID, timestamp, ok := n.Latest.LookupEntry(docker.ImageID)
imageID, ok := n.Latest.Lookup(docker.ImageID)
if !ok {
return report.Nodes{}
}
Expand All @@ -316,7 +314,6 @@ func MapContainer2ContainerImage(n report.Node) report.Nodes {
// counted to produce the minor label
id := report.MakeContainerImageNodeID(imageID)
result := NewDerivedNode(id, n).WithTopology(report.ContainerImage)
result.Latest = result.Latest.Set(docker.ImageID, timestamp, imageID)
result.Counters = result.Counters.Add(n.Topology, 1)
return report.Nodes{id: result}
}
Expand All @@ -336,13 +333,11 @@ func MapContainerImage2Name(n report.Node) report.Nodes {
imageNameWithoutVersion := docker.ImageNameWithoutVersion(imageName)
n.ID = report.MakeContainerImageNodeID(imageNameWithoutVersion)

if imageID, ok := report.ParseContainerImageNodeID(n.ID); ok {
n.Sets = n.Sets.Add(docker.ImageID, report.MakeStringSet(imageID))
}

return report.Nodes{n.ID: n}
}

var containerHostnameTopology = MakeGroupNodeTopology(report.Container, docker.ContainerHostname)

// MapContainer2Hostname maps container Nodes to 'hostname' renderabled nodes..
func MapContainer2Hostname(n report.Node) report.Nodes {
// Propagate all pseudo nodes
Expand All @@ -352,13 +347,12 @@ func MapContainer2Hostname(n report.Node) report.Nodes {

// Otherwise, if some some reason the container doesn't have a hostname
// (maybe slightly out of sync reports), just drop it
id, timestamp, ok := n.Latest.LookupEntry(docker.ContainerHostname)
id, ok := n.Latest.Lookup(docker.ContainerHostname)
if !ok {
return report.Nodes{}
}

node := NewDerivedNode(id, n).WithTopology(MakeGroupNodeTopology(n.Topology, docker.ContainerHostname))
node.Latest = node.Latest.Set(docker.ContainerHostname, timestamp, id)
node := NewDerivedNode(id, n).WithTopology(containerHostnameTopology)
node.Counters = node.Counters.Add(n.Topology, 1)
return report.Nodes{id: node}
}
Expand Down
20 changes: 5 additions & 15 deletions render/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@ var HostRenderer = MakeReduce(
endpoints2Hosts{},
)

func newHostNode(id string) report.Node {
return report.MakeNode(id).WithTopology(report.Host)
}

// nodes2Hosts maps any Nodes to host Nodes.
//
// If this function is given a node without a hostname
Expand All @@ -45,9 +41,9 @@ func nodes2Hosts(nodes Nodes) Nodes {
// hosts, and hence mapping these adjacencies to host
// adjacencies would produce edges that aren't present
// in reality.
ret.addUnmappedChild(n, id, newHostNode)
ret.addUnmappedChild(n, id, report.Host)
} else {
ret.addChild(n, id, newHostNode)
ret.addChild(n, id, report.Host)
}
}
}
Expand All @@ -67,18 +63,12 @@ func (e endpoints2Hosts) Render(rpt report.Report) Nodes {

for _, n := range endpoints.Nodes {
// Nodes without a hostid are treated as pseudo nodes
if hostNodeID, timestamp, ok := n.Latest.LookupEntry(report.HostNodeID); !ok {
if hostNodeID, ok := n.Latest.Lookup(report.HostNodeID); !ok {
if id, ok := pseudoNodeID(n, local); ok {
ret.addChild(n, id, newPseudoNode)
ret.addChild(n, id, Pseudo)
}
} else {
id := report.MakeHostNodeID(report.ExtractHostID(n))
ret.addChild(n, id, func(id string) report.Node {
// we have a hostNodeID, but no matching host node;
// create a new one rather than dropping the data
return newHostNode(id).
WithLatest(report.HostNodeID, timestamp, hostNodeID)
})
ret.addChild(n, hostNodeID, report.Host)
}
}
return ret.result(endpoints)
Expand Down
4 changes: 0 additions & 4 deletions render/id.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,6 @@ func NewDerivedPseudoNode(id string, node report.Node) report.Node {
return output
}

func newPseudoNode(id string) report.Node {
return report.MakeNode(id).WithTopology(Pseudo)
}

func pseudoNodeID(n report.Node, local report.Networks) (string, bool) {
_, addr, _, ok := report.ParseEndpointNodeID(n.ID)
if !ok {
Expand Down
2 changes: 1 addition & 1 deletion render/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ func Map2Parent(
return func(n report.Node) report.Nodes {
// Uncontained becomes Unmanaged/whatever if noParentsPseudoID is set
if noParentsPseudoID != "" && strings.HasPrefix(n.ID, UncontainedIDPrefix) {
id := MakePseudoNodeID(noParentsPseudoID, report.ExtractHostID(n))
id := MakePseudoNodeID(noParentsPseudoID, n.ID[len(UncontainedIDPrefix):])
node := NewDerivedPseudoNode(id, n)
return report.Nodes{id: node}
}
Expand Down
27 changes: 9 additions & 18 deletions render/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,18 +45,15 @@ func (r processWithContainerNameRenderer) Render(rpt report.Report) Nodes {
outputs := make(report.Nodes, len(processes.Nodes))
for id, p := range processes.Nodes {
outputs[id] = p
containerID, timestamp, ok := p.Latest.LookupEntry(docker.ContainerID)
containerID, ok := p.Latest.Lookup(docker.ContainerID)
if !ok {
continue
}
container, ok := containers.Nodes[report.MakeContainerNodeID(containerID)]
if !ok {
continue
}
p.Latest = p.Latest.Set(docker.ContainerID, timestamp, containerID)
if containerName, timestamp, ok := container.Latest.LookupEntry(docker.ContainerName); ok {
p.Latest = p.Latest.Set(docker.ContainerName, timestamp, containerName)
}
propagateLatest(docker.ContainerName, container, p)
outputs[id] = p
}
return Nodes{Nodes: outputs, Filtered: processes.Filtered}
Expand Down Expand Up @@ -92,10 +89,10 @@ func (e endpoints2Processes) Render(rpt report.Report) Nodes {
// Nodes without a hostid are treated as pseudo nodes
if hostNodeID, ok := n.Latest.Lookup(report.HostNodeID); !ok {
if id, ok := pseudoNodeID(n, local); ok {
ret.addChild(n, id, newPseudoNode)
ret.addChild(n, id, Pseudo)
}
} else {
pid, timestamp, ok := n.Latest.LookupEntry(process.PID)
pid, ok := n.Latest.Lookup(process.PID)
if !ok {
continue
}
Expand All @@ -105,12 +102,7 @@ func (e endpoints2Processes) Render(rpt report.Report) Nodes {

hostID, _ := report.ParseHostNodeID(hostNodeID)
id := report.MakeProcessNodeID(hostID, pid)
ret.addChild(n, id, func(id string) report.Node {
// we have a pid, but no matching process node;
// create a new one rather than dropping the data
return report.MakeNode(id).WithTopology(report.Process).
WithLatest(process.PID, timestamp, pid)
})
ret.addChild(n, id, report.Process)
}
}
return ret.result(endpoints)
Expand Down Expand Up @@ -143,18 +135,17 @@ func hasMoreThanOneConnection(n report.Node, endpoints report.Nodes) bool {
return false
}

var processNameTopology = MakeGroupNodeTopology(report.Process, process.Name)

// processes2Names maps process Nodes to Nodes for each process name.
func processes2Names(processes Nodes) Nodes {
ret := newJoinResults(nil)

for _, n := range processes.Nodes {
if n.Topology == Pseudo {
ret.passThrough(n)
} else if name, timestamp, ok := n.Latest.LookupEntry(process.Name); ok {
ret.addChildAndChildren(n, name, func(id string) report.Node {
return report.MakeNode(id).WithTopology(MakeGroupNodeTopology(n.Topology, process.Name)).
WithLatest(process.Name, timestamp, name)
})
} else if name, ok := n.Latest.Lookup(process.Name); ok {
ret.addChildAndChildren(n, name, processNameTopology)
}
}
return ret.result(processes)
Expand Down
21 changes: 11 additions & 10 deletions render/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,12 +184,12 @@ func (ret *joinResults) mapChild(from, to string) {
}
}

// Add m as a child of the node at id, creating a new result node if
// not already there.
func (ret *joinResults) addUnmappedChild(m report.Node, id string, create func(string) report.Node) {
// Add m as a child of the node at id, creating a new result node in
// the specified topology if not already there.
func (ret *joinResults) addUnmappedChild(m report.Node, id string, topology string) {
result, exists := ret.nodes[id]
if !exists {
result = create(id)
result = report.MakeNode(id).WithTopology(topology)
}
result.Children = result.Children.Add(m)
if m.Topology != report.Endpoint { // optimisation: we never look at endpoint counts
Expand All @@ -198,16 +198,17 @@ func (ret *joinResults) addUnmappedChild(m report.Node, id string, create func(s
ret.nodes[id] = result
}

// Add m as a child of the node at id, creating a new result node if
// not already there, and updating the mapping from old ID to new ID.
func (ret *joinResults) addChild(m report.Node, id string, create func(string) report.Node) {
ret.addUnmappedChild(m, id, create)
// Add m as a child of the node at id, creating a new result node in
// the specified topology if not already there, and updating the
// mapping from old ID to new ID.
func (ret *joinResults) addChild(m report.Node, id string, topology string) {
ret.addUnmappedChild(m, id, topology)
ret.mapChild(m.ID, id)
}

// Like addChild, but also add m's children.
func (ret *joinResults) addChildAndChildren(m report.Node, id string, create func(string) report.Node) {
ret.addUnmappedChild(m, id, create)
func (ret *joinResults) addChildAndChildren(m report.Node, id string, topology string) {
ret.addUnmappedChild(m, id, topology)
result := ret.nodes[id]
result.Children = result.Children.Merge(m.Children)
ret.nodes[id] = result
Expand Down