// MapAddressIdentity maps an address topology node to an address renderable // node. As it is only ever run on address topology nodes, we expect that // certain keys are present. func MapAddressIdentity(m RenderableNode, local report.Networks) RenderableNodes { addr, ok := m.Metadata[endpoint.Addr] if !ok { return RenderableNodes{} } // Nodes without a hostid are treated as psuedo nodes _, ok = m.Metadata[report.HostNodeID] if !ok { // If the addr is not in a network local to this report, we emit an // internet node if !local.Contains(net.ParseIP(addr)) { return RenderableNodes{TheInternetID: newDerivedPseudoNode(TheInternetID, TheInternetMajor, m)} } // Otherwise generate a pseudo node for every outputID := MakePseudoNodeID(addr, "") if len(m.Adjacency) > 0 { _, dstAddr, _ := report.ParseAddressNodeID(m.Adjacency[0]) outputID = MakePseudoNodeID(addr, dstAddr) } return RenderableNodes{outputID: newDerivedPseudoNode(outputID, addr, m)} } var ( id = MakeAddressID(report.ExtractHostID(m.Node), addr) major = addr minor = report.ExtractHostID(m.Node) rank = major ) return RenderableNodes{id: NewRenderableNodeWith(id, major, minor, rank, m)} }
// MapEndpointIdentity maps an endpoint topology node to a single endpoint // renderable node. As it is only ever run on endpoint topology nodes, we // expect that certain keys are present. func MapEndpointIdentity(m RenderableNode, local report.Networks) RenderableNodes { addr, ok := m.Metadata[endpoint.Addr] if !ok { return RenderableNodes{} } port, ok := m.Metadata[endpoint.Port] if !ok { return RenderableNodes{} } // We only show nodes found through procspy in this view. _, procspied := m.Metadata[endpoint.Procspied] if !procspied { return RenderableNodes{} } // Nodes without a hostid are treated as psuedo nodes if _, ok = m.Metadata[report.HostNodeID]; !ok { // If the dstNodeAddr is not in a network local to this report, we emit an // internet node if ip := net.ParseIP(addr); ip != nil && !local.Contains(ip) { return RenderableNodes{TheInternetID: newDerivedPseudoNode(TheInternetID, TheInternetMajor, m)} } // We are a 'client' pseudo node if the port is in the ephemeral port range. // Linux uses 32768 to 61000, IANA suggests 49152 to 65535. if p, err := strconv.Atoi(port); err == nil && len(m.Adjacency) > 0 && p >= 32768 && p < 65535 { // We only exist if there is something in our adjacency // Generate a single pseudo node for every (client ip, server ip, server port) dstNodeID := m.Adjacency[0] serverIP, serverPort := trySplitAddr(dstNodeID) outputID := MakePseudoNodeID(addr, serverIP, serverPort) return RenderableNodes{outputID: newDerivedPseudoNode(outputID, addr, m)} } // Otherwise (the server node is missing), generate a pseudo node for every (server ip, server port) outputID := MakePseudoNodeID(addr, port) if port != "" { return RenderableNodes{outputID: newDerivedPseudoNode(outputID, addr+":"+port, m)} } return RenderableNodes{outputID: newDerivedPseudoNode(outputID, addr, m)} } var ( id = MakeEndpointID(report.ExtractHostID(m.Node), addr, port) major = fmt.Sprintf("%s:%s", addr, port) minor = report.ExtractHostID(m.Node) rank = major ) pid, pidOK := m.Metadata[process.PID] if pidOK { minor = fmt.Sprintf("%s (%s)", minor, pid) } return RenderableNodes{id: NewRenderableNodeWith(id, major, minor, rank, m)} }
// MapProcessIdentity maps a process topology node to process RenderableNode node. // As it is only ever run on process topology nodes, we can safely assume the // presence of certain keys. func MapProcessIdentity(m report.NodeMetadata) (RenderableNode, bool) { var ( id = MakeProcessID(report.ExtractHostID(m), m["pid"]) major = m["comm"] minor = fmt.Sprintf("%s (%s)", report.ExtractHostID(m), m["pid"]) rank = m["pid"] ) return NewRenderableNode(id, major, minor, rank, m), true }
// MapAddressIdentity maps a address topology node to address RenderableNode // node. As it is only ever run on address topology nodes, we can safely // assume the presence of certain keys. func MapAddressIdentity(m report.NodeMetadata) (RenderableNode, bool) { var ( id = MakeAddressID(report.ExtractHostID(m), m["addr"]) major = m["addr"] minor = report.ExtractHostID(m) rank = major ) return NewRenderableNode(id, major, minor, rank, m), true }
// MapAddressIdentity maps an address topology node to an address renderable // node. As it is only ever run on address topology nodes, we expect that // certain keys are present. func MapAddressIdentity(m report.NodeMetadata) (RenderableNode, bool) { addr, ok := m.Metadata[endpoint.Addr] if !ok { return RenderableNode{}, false } var ( id = MakeAddressID(report.ExtractHostID(m), addr) major = addr minor = report.ExtractHostID(m) rank = major ) return NewRenderableNode(id, major, minor, rank, m), true }
// MapProcessIdentity maps a process topology node to a process renderable // node. As it is only ever run on process topology nodes, we expect that // certain keys are present. func MapProcessIdentity(m RenderableNode, _ report.Networks) RenderableNodes { pid, ok := m.Latest.Lookup(process.PID) if !ok { return RenderableNodes{} } var ( id = MakeProcessID(report.ExtractHostID(m.Node), pid) major, _ = m.Latest.Lookup(process.Name) minor = fmt.Sprintf("%s (%s)", report.ExtractHostID(m.Node), pid) rank, _ = m.Latest.Lookup(process.Name) ) return RenderableNodes{id: NewRenderableNodeWith(id, major, minor, rank, m)} }
// MapEndpointIdentity maps a endpoint topology node to endpoint RenderableNode // node. As it is only ever run on endpoint topology nodes, we can safely // assume the presence of certain keys. func MapEndpointIdentity(m report.NodeMetadata) (RenderableNode, bool) { var ( id = MakeEndpointID(report.ExtractHostID(m), m["addr"], m["port"]) major = fmt.Sprintf("%s:%s", m["addr"], m["port"]) pid, ok = m["pid"] minor = report.ExtractHostID(m) rank = major ) if ok { minor = fmt.Sprintf("%s (%s)", report.ExtractHostID(m), pid) } return NewRenderableNode(id, major, minor, rank, m), true }
// MapProcessIdentity maps a process topology node to a process renderable // node. As it is only ever run on process topology nodes, we expect that // certain keys are present. func MapProcessIdentity(m RenderableNode, _ report.Networks) RenderableNodes { pid, ok := m.Metadata[process.PID] if !ok { return RenderableNodes{} } var ( id = MakeProcessID(report.ExtractHostID(m.Node), pid) major = m.Metadata["comm"] minor = fmt.Sprintf("%s (%s)", report.ExtractHostID(m.Node), pid) rank = m.Metadata["comm"] ) return RenderableNodes{id: NewRenderableNodeWith(id, major, minor, rank, m)} }
// MapProcessIdentity maps a process topology node to a process renderable // node. As it is only ever run on process topology nodes, we expect that // certain keys are present. func MapProcessIdentity(m report.NodeMetadata) (RenderableNode, bool) { pid, ok := m.Metadata[process.PID] if !ok { return RenderableNode{}, false } var ( id = MakeProcessID(report.ExtractHostID(m), pid) major = m.Metadata["comm"] minor = fmt.Sprintf("%s (%s)", report.ExtractHostID(m), pid) rank = m.Metadata["comm"] ) return NewRenderableNode(id, major, minor, rank, m), true }
func (r processWithContainerNameRenderer) Render(rpt report.Report) RenderableNodes { processes := r.Renderer.Render(rpt) containers := Map{ MapFunc: MapContainerIdentity, Renderer: SelectContainer, }.Render(rpt) for id, p := range processes { pid, ok := p.Node.Metadata[process.PID] if !ok { continue } containerID, ok := p.Node.Metadata[docker.ContainerID] if !ok { continue } container, ok := containers[MakeContainerID(containerID)] if !ok { continue } p.LabelMinor = fmt.Sprintf("%s (%s:%s)", report.ExtractHostID(p.Node), container.LabelMajor, pid) processes[id] = p } return processes }
// Render produces a process graph where the minor labels contain the // container name, if found. func (r ProcessWithContainerNameRenderer) Render(rpt report.Report) RenderableNodes { processes := ProcessRenderer.Render(rpt) containers := LeafMap{ Selector: report.SelectContainer, Mapper: MapContainerIdentity, Pseudo: PanicPseudoNode, }.Render(rpt) for id, p := range processes { pid, ok := p.NodeMetadata.Metadata[process.PID] if !ok { continue } containerID, ok := p.NodeMetadata.Metadata[docker.ContainerID] if !ok { continue } container, ok := containers[containerID] if !ok { continue } p.LabelMinor = fmt.Sprintf("%s (%s:%s)", report.ExtractHostID(p.NodeMetadata), container.LabelMajor, pid) processes[id] = p } return processes }
// MapProcess2Container maps process Nodes to container // Nodes. // // If this function is given a node without a docker_container_id // (including other pseudo nodes), it will produce an "Uncontained" // pseudo node. // // Otherwise, this function will produce a node with the correct ID // format for a container, but without any Major or Minor labels. // It does not have enough info to do that, and the resulting graph // must be merged with a container graph to get that info. func MapProcess2Container(n report.Node, _ report.Networks) report.Nodes { // Propagate pseudo nodes if n.Topology == Pseudo { return report.Nodes{n.ID: n} } // 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 nodemetadata, it'll // all get grouped into a single uncontained node. var ( id string node report.Node ) if containerID, ok := n.Latest.Lookup(docker.ContainerID); ok { id = report.MakeContainerNodeID(containerID) node = NewDerivedNode(id, n).WithTopology(report.Container) } else { id = MakePseudoNodeID(UncontainedID, report.ExtractHostID(n)) node = NewDerivedPseudoNode(id, n) node = propagateLatest(report.HostNodeID, n, node) node = propagateLatest(IsConnected, n, node) } return report.Nodes{id: node} }
// MapProcess2Container maps process RenderableNodes to container // RenderableNodes. // // If this function is given a node without a docker_container_id // (including other pseudo nodes), it will produce an "Uncontained" // pseudo node. // // Otherwise, this function will produce a node with the correct ID // format for a container, but without any Major or Minor labels. // It does not have enough info to do that, and the resulting graph // must be merged with a container graph to get that info. func MapProcess2Container(n RenderableNode, _ report.Networks) RenderableNodes { // Propogate the internet pseudo node if n.ID == TheInternetID { return RenderableNodes{n.ID: n} } // Don't propogate non-internet pseudo nodes if n.Pseudo { return RenderableNodes{} } // 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 nodemetadata, it'll // all get grouped into a single uncontained node. id, ok := n.Node.Metadata[docker.ContainerID] if !ok { hostID := report.ExtractHostID(n.Node) id = MakePseudoNodeID(UncontainedID, hostID) node := newDerivedPseudoNode(id, UncontainedMajor, n) node.LabelMinor = hostID return RenderableNodes{id: node} } return RenderableNodes{id: NewDerivedNode(id, n)} }
// MapProcess2Container maps process RenderableNodes to container // RenderableNodes. // // If this function is given a node without a docker_container_id // (including other pseudo nodes), it will produce an "Uncontained" // pseudo node. // // Otherwise, this function will produce a node with the correct ID // format for a container, but without any Major or Minor labels. // It does not have enough info to do that, and the resulting graph // must be merged with a container graph to get that info. func MapProcess2Container(n RenderableNode, _ report.Networks) RenderableNodes { // Propogate the internet pseudo node if n.ID == TheInternetID { return RenderableNodes{n.ID: n} } // Don't propogate non-internet pseudo nodes if n.Pseudo { return RenderableNodes{} } // 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 nodemetadata, it'll // all get grouped into a single uncontained node. var ( id string node RenderableNode hostID = report.ExtractHostID(n.Node) ) n = n.WithParents(report.EmptySets) if containerID, ok := n.Node.Latest.Lookup(docker.ContainerID); ok { id = MakeContainerID(containerID) node = NewDerivedNode(id, n) } else { nCopy := n.Copy() nCopy.Node = nCopy.Node.WithID("").WithTopology("") // Wipe the ID so it cannot be rendered. id = MakePseudoNodeID(UncontainedID, hostID) node = newDerivedPseudoNode(id, UncontainedMajor, nCopy) node.LabelMinor = hostID } node.Children = node.Children.Add(n.Node) return RenderableNodes{id: node} }
// MapAddress2Host maps address RenderableNodes to host RenderableNodes. // // Otherthan pseudo nodes, we can assume all nodes have a HostID func MapAddress2Host(n RenderableNode) (RenderableNode, bool) { if n.Pseudo { return n, true } id := MakeHostID(report.ExtractHostID(n.NodeMetadata)) return newDerivedNode(id, n), true }
// MapAddress2Host maps address RenderableNodes to host RenderableNodes. // // Otherthan pseudo nodes, we can assume all nodes have a HostID func MapAddress2Host(n RenderableNode, _ report.Networks) RenderableNodes { if n.Pseudo { return RenderableNodes{n.ID: n} } id := MakeHostID(report.ExtractHostID(n.Node)) return RenderableNodes{id: NewDerivedNode(id, n)} }
// MapContainerIdentity maps a container topology node to a container // RenderableNode node. As it is only ever run on container topology // nodes, we can safely assume the presences of certain keys. func MapContainerIdentity(m report.NodeMetadata) (RenderableNode, bool) { var ( id = m[docker.ContainerID] major = m[docker.ContainerName] minor = report.ExtractHostID(m) rank = m[docker.ImageID] ) return NewRenderableNode(id, major, minor, rank, m), true }
func containerOriginTable(nmd report.Node, addHostTag bool) (Table, bool) { rows := []Row{} for _, tuple := range []struct{ key, human string }{ {docker.ContainerState, "State"}, } { if val, ok := nmd.Latest.Lookup(tuple.key); ok && val != "" { rows = append(rows, Row{Key: tuple.human, ValueMajor: val, ValueMinor: ""}) } } for _, tuple := range []struct{ key, human string }{ {docker.ContainerID, "ID"}, {docker.ImageID, "Image ID"}, {docker.ContainerPorts, "Ports"}, {docker.ContainerCreated, "Created"}, {docker.ContainerCommand, "Command"}, {overlay.WeaveMACAddress, "Weave MAC"}, {overlay.WeaveDNSHostname, "Weave DNS Hostname"}, } { if val, ok := nmd.Metadata[tuple.key]; ok && val != "" { rows = append(rows, Row{Key: tuple.human, ValueMajor: val, ValueMinor: ""}) } } for _, ip := range docker.ExtractContainerIPs(nmd) { rows = append(rows, Row{Key: "IP Address", ValueMajor: ip, ValueMinor: ""}) } rows = append(rows, getDockerLabelRows(nmd)...) if addHostTag { rows = append([]Row{{Key: "Host", ValueMajor: report.ExtractHostID(nmd)}}, rows...) } if val, ok := nmd.Metrics[docker.MemoryUsage]; ok { rows = append(rows, sparklineRow("Memory Usage", val, formatMemory)) } if val, ok := nmd.Metrics[docker.CPUTotalUsage]; ok { rows = append(rows, sparklineRow("CPU Usage", val, formatPercent)) } var ( title = "Container" name, nameFound = GetRenderableContainerName(nmd) ) if nameFound { title += ` "` + name + `"` } return Table{ Title: title, Numeric: false, Rows: rows, Rank: containerRank, }, len(rows) > 0 || nameFound }
// MapAddressIdentity maps an address topology node to an address renderable // node. As it is only ever run on address topology nodes, we expect that // certain keys are present. func MapAddressIdentity(m RenderableNode, local report.Networks) RenderableNodes { addr, ok := m.Metadata[endpoint.Addr] if !ok { return RenderableNodes{} } // Conntracked connections don't have a host id unless // they were merged with a procspied connection. Filter // out those that weren't. _, hasHostID := m.Metadata[report.HostNodeID] _, conntracked := m.Metadata[endpoint.Conntracked] if !hasHostID && conntracked { return RenderableNodes{} } // Nodes without a hostid are treated as psuedo nodes if !hasHostID { // If the addr is not in a network local to this report, we emit an // internet node if !local.Contains(net.ParseIP(addr)) { return RenderableNodes{TheInternetID: newDerivedPseudoNode(TheInternetID, TheInternetMajor, m)} } // Otherwise generate a pseudo node for every outputID := MakePseudoNodeID(addr, "") if len(m.Adjacency) > 0 { _, dstAddr, _ := report.ParseAddressNodeID(m.Adjacency[0]) outputID = MakePseudoNodeID(addr, dstAddr) } return RenderableNodes{outputID: newDerivedPseudoNode(outputID, addr, m)} } var ( id = MakeAddressID(report.ExtractHostID(m.Node), addr) major = addr minor = report.ExtractHostID(m.Node) rank = major ) return RenderableNodes{id: NewRenderableNodeWith(id, major, minor, rank, m)} }
// MapEndpoint2Process maps endpoint RenderableNodes to process // RenderableNodes. // // If this function is given a pseudo node, then it will just return it; // Pseudo nodes will never have pids in them, and therefore will never // be able to be turned into a Process node. // // Otherwise, this function will produce a node with the correct ID // format for a process, but without any Major or Minor labels. // It does not have enough info to do that, and the resulting graph // must be merged with a process graph to get that info. func MapEndpoint2Process(n RenderableNode, _ report.Networks) RenderableNodes { if n.Pseudo { return RenderableNodes{n.ID: n} } pid, ok := n.Node.Latest.Lookup(process.PID) if !ok { return RenderableNodes{} } id := MakeProcessID(report.ExtractHostID(n.Node), pid) return RenderableNodes{id: NewDerivedNode(id, n.WithParents(report.EmptySets))} }
// MapX2Host maps any RenderableNodes to host // RenderableNodes. // // If this function is given a node without a hostname // (including other pseudo nodes), it will drop the node. // // Otherwise, this function will produce a node with the correct ID // format for a container, but without any Major or Minor labels. // It does not have enough info to do that, and the resulting graph // must be merged with a container graph to get that info. func MapX2Host(n RenderableNode, _ report.Networks) RenderableNodes { // Propogate all pseudo nodes if n.Pseudo { return RenderableNodes{n.ID: n} } if _, ok := n.Node.Latest.Lookup(report.HostNodeID); !ok { return RenderableNodes{} } id := MakeHostID(report.ExtractHostID(n.Node)) result := NewDerivedNode(id, n.WithParents(report.EmptySets)) result.Children = result.Children.Add(n.Node) return RenderableNodes{id: result} }
// MapEndpoint2Process maps endpoint RenderableNodes to process // RenderableNodes. // // If this function is given a pseudo node, then it will just return it; // Pseudo nodes will never have pids in them, and therefore will never // be able to be turned into a Process node. // // Otherwise, this function will produce a node with the correct ID // format for a process, but without any Major or Minor labels. // It does not have enough info to do that, and the resulting graph // must be merged with a process graph to get that info. func MapEndpoint2Process(n RenderableNode) (RenderableNode, bool) { if n.Pseudo { return n, true } pid, ok := n.NodeMetadata.Metadata[process.PID] if !ok { return RenderableNode{}, false } id := MakeProcessID(report.ExtractHostID(n.NodeMetadata), pid) return newDerivedNode(id, n), true }
// MapEndpoint2Process maps endpoint RenderableNodes to process // RenderableNodes. // // If this function is given a pseudo node, then it will just return it; // Pseudo nodes will never have pids in them, and therefore will never // be able to be turned into a Process node. // // Otherwise, this function will produce a node with the correct ID // format for a process, but without any Major or Minor labels. // It does not have enough info to do that, and the resulting graph // must be merged with a process graph to get that info. func MapEndpoint2Process(n RenderableNode, _ report.Networks) RenderableNodes { if n.Pseudo { return RenderableNodes{n.ID: n} } pid, ok := n.Node.Metadata[process.PID] if !ok { return RenderableNodes{} } id := MakeProcessID(report.ExtractHostID(n.Node), pid) return RenderableNodes{id: NewDerivedNode(id, n)} }
// MapContainerIdentity maps a container topology node to a container // renderable node. As it is only ever run on container topology nodes, we // expect that certain keys are present. func MapContainerIdentity(m report.NodeMetadata) (RenderableNode, bool) { id, ok := m.Metadata[docker.ContainerID] if !ok { return RenderableNode{}, false } var ( major = m.Metadata[docker.ContainerName] minor = report.ExtractHostID(m) rank = m.Metadata[docker.ImageID] ) return NewRenderableNode(id, major, minor, rank, m), true }
func processNodeSummary(nmd report.Node) NodeSummary { var ( id string label, nameFound = nmd.Latest.Lookup(process.Name) ) if pid, ok := nmd.Latest.Lookup(process.PID); ok { if !nameFound { label = fmt.Sprintf("(%s)", pid) } id = render.MakeProcessID(report.ExtractHostID(nmd), pid) } _, isConnected := nmd.Latest.Lookup(render.IsConnected) return baseNodeSummary(id, label, isConnected, nmd) }
// MapEndpointIdentity maps an endpoint topology node to an endpoint // renderable node. As it is only ever run on endpoint topology nodes, we // expect that certain keys are present. func MapEndpointIdentity(m report.NodeMetadata) (RenderableNode, bool) { addr, ok := m.Metadata[endpoint.Addr] if !ok { return RenderableNode{}, false } port, ok := m.Metadata[endpoint.Port] if !ok { return RenderableNode{}, false } var ( id = MakeEndpointID(report.ExtractHostID(m), addr, port) major = fmt.Sprintf("%s:%s", addr, port) minor = report.ExtractHostID(m) rank = major ) if pid, ok := m.Metadata[process.PID]; ok { minor = fmt.Sprintf("%s (%s)", minor, pid) } return NewRenderableNode(id, major, minor, rank, m), true }
func containerOriginTable(nmd report.Node, addHostTag bool) (Table, bool) { rows := []Row{} for _, tuple := range []struct{ key, human string }{ {docker.ContainerState, "State"}, {docker.ContainerID, "ID"}, {docker.ImageID, "Image ID"}, {docker.ContainerPorts, "Ports"}, {docker.ContainerCreated, "Created"}, {docker.ContainerCommand, "Command"}, {overlay.WeaveMACAddress, "Weave MAC"}, {overlay.WeaveDNSHostname, "Weave DNS Hostname"}, } { if val, ok := nmd.Metadata[tuple.key]; ok && val != "" { rows = append(rows, Row{Key: tuple.human, ValueMajor: val, ValueMinor: ""}) } } 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) if err == nil { memoryStr := fmt.Sprintf("%0.2f", memory/float64(mb)) rows = append(rows, Row{Key: "Memory Usage (MB):", ValueMajor: memoryStr, ValueMinor: ""}) } } if addHostTag { rows = append([]Row{{Key: "Host", ValueMajor: report.ExtractHostID(nmd)}}, rows...) } var ( title = "Container" name, nameFound = GetRenderableContainerName(nmd) ) if nameFound { title += ` "` + name + `"` } return Table{ Title: title, Numeric: false, Rows: rows, Rank: containerRank, }, len(rows) > 0 || nameFound }
// MapHostIdentity maps a host topology node to a host renderable node. As it // is only ever run on host topology nodes, we expect that certain keys are // present. func MapHostIdentity(m report.NodeMetadata) (RenderableNode, bool) { var ( id = MakeHostID(report.ExtractHostID(m)) hostname = m.Metadata[host.HostName] parts = strings.SplitN(hostname, ".", 2) major, minor, rank = "", "", "" ) if len(parts) == 2 { major, minor, rank = parts[0], parts[1], parts[1] } else { major = hostname } return NewRenderableNode(id, major, minor, rank, m), true }
// MapHostIdentity maps a host topology node to a host renderable node. As it // is only ever run on host topology nodes, we expect that certain keys are // present. func MapHostIdentity(m RenderableNode, _ report.Networks) RenderableNodes { var ( id = MakeHostID(report.ExtractHostID(m.Node)) hostname = m.Metadata[host.HostName] parts = strings.SplitN(hostname, ".", 2) major, minor, rank = "", "", "" ) if len(parts) == 2 { major, minor, rank = parts[0], parts[1], parts[1] } else { major = hostname } return RenderableNodes{id: NewRenderableNodeWith(id, major, minor, rank, m)} }
// MapContainerIdentity maps a container topology node to a container // renderable node. As it is only ever run on container topology nodes, we // expect that certain keys are present. func MapContainerIdentity(m RenderableNode, _ report.Networks) RenderableNodes { containerID, ok := m.Latest.Lookup(docker.ContainerID) if !ok { return RenderableNodes{} } var ( id = MakeContainerID(containerID) major, _ = GetRenderableContainerName(m.Node) minor = report.ExtractHostID(m.Node) rank, _ = m.Latest.Lookup(docker.ImageID) ) node := NewRenderableNodeWith(id, major, minor, rank, m) node.ControlNode = m.ID return RenderableNodes{id: node} }