Bug 2677 - améliorer la lisibilité du powerdiagram en regroupant les noeuds par rack
désormais, le powerdiagram est plus lisible car les noeuds sont regroupés par rack. J'aurais bien aimé que les serveurs soient ordonnés comme dans les racks mais graphviz ne sait pas bien mixer des positions forcées avec des positions libres (lorsque j'ai essayé de le faire, les positions fixées ne l'étaient plus)
This commit is contained in:
parent
e102d33a9d
commit
889712b356
|
@ -41,6 +41,7 @@ class Machine(object):
|
||||||
self.current_capacity_constraint = None # the maximum amperes in this connection
|
self.current_capacity_constraint = None # the maximum amperes in this connection
|
||||||
self.power_config = power_config
|
self.power_config = power_config
|
||||||
self.power_consumption = 0.0
|
self.power_consumption = 0.0
|
||||||
|
self.rack_id = None
|
||||||
|
|
||||||
def get_plug(self, plug_name):
|
def get_plug(self, plug_name):
|
||||||
plugs = {'i': self.input_plugs, 'o': self.output_plugs}[plug_name[0]]
|
plugs = {'i': self.input_plugs, 'o': self.output_plugs}[plug_name[0]]
|
||||||
|
@ -199,6 +200,14 @@ class PowerConfig(object):
|
||||||
|
|
||||||
machine_name = machine.name
|
machine_name = machine.name
|
||||||
|
|
||||||
|
# find its rack location
|
||||||
|
try:
|
||||||
|
rack_id, rack_slot_index = inventory.get_machine_rack_location(machine_name)
|
||||||
|
machine.rack_id = rack_id
|
||||||
|
machine.rack_slot_index = rack_slot_index
|
||||||
|
except SimpaDbUtil.TableAttrNotFound:
|
||||||
|
pass
|
||||||
|
|
||||||
if re.match('[a-z]+.._..', machine_name):
|
if re.match('[a-z]+.._..', machine_name):
|
||||||
# machine_name is a group of machines such as physix80_83
|
# machine_name is a group of machines such as physix80_83
|
||||||
# in this case, we use a hack : the type and power consumption is based on the first machine of this group (in this example physix80)
|
# in this case, we use a hack : the type and power consumption is based on the first machine of this group (in this example physix80)
|
||||||
|
@ -220,6 +229,7 @@ class PowerConfig(object):
|
||||||
if power_consumption is not None:
|
if power_consumption is not None:
|
||||||
machine.power_consumption = power_consumption
|
machine.power_consumption = power_consumption
|
||||||
|
|
||||||
|
|
||||||
def get_connection_to(self, to_plug):
|
def get_connection_to(self, to_plug):
|
||||||
for connection in self.connections:
|
for connection in self.connections:
|
||||||
if connection.to_plug == to_plug:
|
if connection.to_plug == to_plug:
|
||||||
|
@ -261,6 +271,7 @@ def power_config_to_svg(power_config, svg_file_path):
|
||||||
graph = pygraphviz.AGraph()
|
graph = pygraphviz.AGraph()
|
||||||
graph.graph_attr['overlap'] = 'false'
|
graph.graph_attr['overlap'] = 'false'
|
||||||
graph.graph_attr['splines'] = 'true'
|
graph.graph_attr['splines'] = 'true'
|
||||||
|
graph.graph_attr['rankdir'] = 'LR' # to get hrizontal tree rather than vertical
|
||||||
|
|
||||||
graph.edge_attr['colorscheme'] = 'rdylgn9' # 'brbg11'
|
graph.edge_attr['colorscheme'] = 'rdylgn9' # 'brbg11'
|
||||||
graph.node_attr['shape'] = 'box'
|
graph.node_attr['shape'] = 'box'
|
||||||
|
@ -280,6 +291,31 @@ def power_config_to_svg(power_config, svg_file_path):
|
||||||
# graph.add_node('b')
|
# graph.add_node('b')
|
||||||
# graph.add_edge(u'a',u'b',color='blue')
|
# graph.add_edge(u'a',u'b',color='blue')
|
||||||
# graph.add_edge(u'b',u'a',color='blue')
|
# graph.add_edge(u'b',u'a',color='blue')
|
||||||
|
racks = {}
|
||||||
|
|
||||||
|
for con in power_config.connections:
|
||||||
|
for machine in [con.from_plug.machine, con.to_plug.machine]:
|
||||||
|
rack_id = machine.rack_id
|
||||||
|
if rack_id is not None:
|
||||||
|
if rack_id not in racks.keys():
|
||||||
|
rack = {}
|
||||||
|
rack['name'] = rack_id
|
||||||
|
rack['machines'] = []
|
||||||
|
racks[rack_id] = rack
|
||||||
|
rack = racks[rack_id]
|
||||||
|
if machine.name not in rack['machines']:
|
||||||
|
rack['machines'].append(machine)
|
||||||
|
|
||||||
|
if False:
|
||||||
|
x = 0.0
|
||||||
|
for rack in racks.itervalues():
|
||||||
|
y = 0.0
|
||||||
|
for machine in rack['machines']:
|
||||||
|
graph.add_node(machine.name, pos='%f,%f!' % (x, y)) # https://observablehq.com/@magjac/placing-graphviz-nodes-in-fixed-positions
|
||||||
|
print(machine.name, x, y)
|
||||||
|
y += 1.0
|
||||||
|
x += 1.0
|
||||||
|
|
||||||
for con in power_config.connections:
|
for con in power_config.connections:
|
||||||
# print(con.from_plug.machine.name, con.to_plug.machine.name)
|
# print(con.from_plug.machine.name, con.to_plug.machine.name)
|
||||||
if not con.is_redundancy_cable(): # don't display redundancy cables, as they might overlap and hide the main one
|
if not con.is_redundancy_cable(): # don't display redundancy cables, as they might overlap and hide the main one
|
||||||
|
@ -306,5 +342,19 @@ def power_config_to_svg(power_config, svg_file_path):
|
||||||
# color='//%d' % int(9.0-amperes/capacity*8)
|
# color='//%d' % int(9.0-amperes/capacity*8)
|
||||||
|
|
||||||
graph.add_edge(con.from_plug.machine.name, con.to_plug.machine.name, color=color, label=label, penwidth=penwidth)
|
graph.add_edge(con.from_plug.machine.name, con.to_plug.machine.name, color=color, label=label, penwidth=penwidth)
|
||||||
graph.layout(prog='twopi')
|
|
||||||
|
if True:
|
||||||
|
for rack_id, rack in racks.iteritems():
|
||||||
|
# sub = graph.add_subgraph(rack, name='cluster_%s' % rack_id, rank='same')
|
||||||
|
machine_names = list(machine.name for machine in rack['machines'])
|
||||||
|
sub = graph.add_subgraph(machine_names, name='cluster_%s' % rack_id)
|
||||||
|
sub.graph_attr['label'] = rack_id
|
||||||
|
# sub.graph_attr['rank']='same'
|
||||||
|
# assert False
|
||||||
|
#graph.layout(prog='twopi')
|
||||||
|
with open('./toto.dot', 'w') as f:
|
||||||
|
f.write(graph.string())
|
||||||
|
|
||||||
|
|
||||||
|
graph.layout(prog='dot')
|
||||||
graph.draw(svg_file_path)
|
graph.draw(svg_file_path)
|
||||||
|
|
|
@ -130,6 +130,11 @@ class Inventory(object):
|
||||||
ordering_date = datetime.datetime.strptime(ordering_date_as_str, '%d/%m/%Y')
|
ordering_date = datetime.datetime.strptime(ordering_date_as_str, '%d/%m/%Y')
|
||||||
return ordering_date
|
return ordering_date
|
||||||
|
|
||||||
|
def get_machine_rack_location(self, machine_id):
|
||||||
|
rack_id = self._sql_reader.get_table_attr('rackable_machine_to_location', 'machine_id', machine_id, 'rack_id')
|
||||||
|
slot_index = self._sql_reader.get_table_attr('rackable_machine_to_location', 'machine_id', machine_id, 'slot_index')
|
||||||
|
return rack_id, slot_index
|
||||||
|
|
||||||
def get_cpu_dflops(self, cpu_model):
|
def get_cpu_dflops(self, cpu_model):
|
||||||
'''
|
'''
|
||||||
returns the number of double precision operation per second this cpu can achieve
|
returns the number of double precision operation per second this cpu can achieve
|
||||||
|
|
Loading…
Reference in New Issue