just fixed pylint warnings and errors

This commit is contained in:
Guillaume Raffy 2021-01-21 16:14:29 +00:00
parent 160bc22c3d
commit 82816e5193
2 changed files with 45 additions and 44 deletions

View File

@ -2,7 +2,7 @@
The goal of this application is to generate a power diagram that will help system administrators to:
- document the power supply architecture
- easily spot potential power overloads (for example if the power consumption exceeds the capacity of a cable)
This application takes its input from a database, currently in the form of an sql dump, but it could easily be adapted to read directly from a mysql database
'''
@ -16,7 +16,7 @@ from SimpaDbUtil import SqlFile, SqlDatabaseReader, TableAttrNotFound
def add_capacity_constraints(capacity1, capacity2):
"""
combines 2 capacity constraints (max amperes) together
:param float capacity1: max amperes for the first capacity, None if there are no constraints
:param float capacity2: max amperes for the second capacity, None if there are no constraints
:return float: max amperes for the combined capacity, None if there are no constraints
@ -95,7 +95,6 @@ class Machine(object):
return self.name == 'edf' or re.match('^ups[0-9]*$', self.name)
class Plug(object):
"""
represents a power plug (input or output) of a device
@ -131,20 +130,21 @@ class Plug(object):
# apply incoming connection amperes limitation
capacity = add_capacity_constraints(capacity, in_con.get_max_amperes())
if debug:
print(str(self)+ 'after incoming connection amperes limitation, capacity = ' + str(capacity))
print(str(self) + 'after incoming connection amperes limitation, capacity = ' + str(capacity))
else:
# apply the machine containing this plug's amperes limitation
capacity = add_capacity_constraints(capacity, self.machine.get_max_amperes())
if debug:
print(str(self)+'apply the machine containing this plug s amperes limitation, capacity = ' + str(capacity))
print(str(self) + 'apply the machine containing this plug s amperes limitation, capacity = ' + str(capacity))
# apply this plug's amperes limitation
capacity = add_capacity_constraints(capacity, self.current_capacity_constraint)
if debug:
print(str(self)+'after apply this plug s amperes limitation, capacity = ' + str(capacity), self.current_capacity_constraint)
print(str(self) + 'after apply this plug s amperes limitation, capacity = ' + str(capacity), self.current_capacity_constraint)
return capacity
class Connection(object):
"""
a power cable connecting an input power plug to an output power plug
@ -157,7 +157,7 @@ class Connection(object):
def __str__(self):
return str(self.from_plug) + ' -> ' + str(self.to_plug) + ' (' + str(self.from_plug.get_max_amperes()) + ' A, ' + str(self.get_max_amperes()) + ' A)'
def get_max_amperes(self):
# gLogger.debug('%s (%s A) -> %s (%s A): ' % (str(self.from_plug), str(self.from_plug.get_max_amperes()), str(self.to_plug), str(self.to_plug.current_capacity_constraint)))
capacity = self.from_plug.get_max_amperes()
@ -203,7 +203,7 @@ class Connection(object):
to_machine = self.to_plug.machine
power_consumption = None
if worst_case_scenario:
if False: # self.is_redundancy_cable():
if False: # self.is_redundancy_cable():
power_consumption = 0.0
else:
power_consumption = to_machine.get_power_consumption(worst_case_scenario)
@ -217,6 +217,7 @@ class Connection(object):
power_consumption = to_machine.get_power_consumption(worst_case_scenario) / num_input_cables
return power_consumption
class PowerConfig(object):
"""
the description of how machines are connected together (in terms of electric power)
@ -225,17 +226,17 @@ class PowerConfig(object):
def __init__(self, simpa_db_sql_file_path):
self.machines = {}
self.connections = []
sql_source = SqlFile(simpa_db_sql_file_path)
sql_reader = SqlDatabaseReader(sql_source)
inventory = Inventory(sql_reader)
self._parse_from_inventory(inventory)
def _parse_from_inventory(self, inventory):
"""
:param Inventory inventory:
"""
rows = inventory.query("SELECT * FROM machine_to_power")
for row in rows:
@ -255,7 +256,7 @@ class PowerConfig(object):
(to_plug_as_str, max_amps_as_str) = row
to_plug = self._get_plug(to_plug_as_str)
to_plug.set_current_capacity_constraint(float(max_amps_as_str))
for machine in self.machines.values():
machine_name = machine.name
@ -283,13 +284,12 @@ class PowerConfig(object):
machine_spec_id = None # some simple 'machines' such as powerext003 have undefined machine_spec_id
except MachineSpecIdNotFound:
pass
if machine_spec_id is not None:
power_consumption = inventory.machine_spec_id_to_power_consumption(machine_spec_id)
if power_consumption is not None:
machine.power_consumption = power_consumption
def get_connection_to(self, to_plug):
for connection in self.connections:
if connection.to_plug == to_plug:
@ -300,27 +300,28 @@ class PowerConfig(object):
if machine_name not in self.machines:
self.machines[machine_name] = Machine(machine_name, self)
return self.machines[machine_name]
def _get_plug(self, plug_as_str):
elements = plug_as_str.split('_')
plug_name = elements[-1]
machine_name = plug_as_str[0:-(len(plug_name) + 1)]
machine = self._get_machine(machine_name)
return machine.get_plug(plug_name)
def _add_connection(self, from_plug_as_str, to_plug_as_str):
from_plug = self._get_plug(from_plug_as_str)
to_plug = self._get_plug(to_plug_as_str)
conn = Connection(from_plug, to_plug)
self.connections.append(conn)
return conn
def __str__(self):
s = ''
for c in self.connections:
s += str(c) + '\n'
return s
class CableColorer(object):
def get_cable_color(self, cable, worst_case_scenario):
@ -329,6 +330,7 @@ class CableColorer(object):
"""
raise NotImplementedError
class SimpleColorer(CableColorer):
def get_cable_color(self, cable, worst_case_scenario):
@ -349,6 +351,7 @@ class SimpleColorer(CableColorer):
color = '/svg/green'
return color
class RampColorer(CableColorer):
@staticmethod
@ -384,24 +387,24 @@ class RampColorer(CableColorer):
color = '/svg/red' # draw overloaded cables in red
return color
def power_config_to_svg(power_config, svg_file_path, worst_case_scenario=True):
"""
creates a svg diagram representing the input power configuration
:param PowerConfig power_config: the input power config
"""
graph = pygraphviz.AGraph(strict=False) # strict=False allows more than one connection between 2 nodes
graph.graph_attr['overlap'] = 'false'
graph.graph_attr['splines'] = 'true'
graph.graph_attr['rankdir'] = 'LR' # to get hrizontal tree rather than vertical
graph.edge_attr['colorscheme'] = 'rdylgn9' # 'brbg11'
graph.node_attr['shape'] = 'box'
graph.node_attr['height'] = 0.3 # default 0.5 inches
graph.node_attr['fontname'] = 'Helvetica' # default : Times-Roman
graph.edge_attr['fontsize'] = 10 # default : 14 pt
graph.edge_attr['len'] = 1.5 # default : 1.0
# graph.add_node('a')
# graph.add_node('b')
@ -438,7 +441,6 @@ def power_config_to_svg(power_config, svg_file_path, worst_case_scenario=True):
</tr>\
</table>>' % (machine.name, machine_total_power_consumption)
if False:
x = 0.0
for rack in racks.itervalues():
@ -470,7 +472,7 @@ def power_config_to_svg(power_config, svg_file_path, worst_case_scenario=True):
penwidth = capacity * penwidth_scaler
label = "%.1f/%s" % (amperes, max_amp)
# color='//%d' % int(9.0-amperes/capacity*8)
# graph.add_edge(con.from_plug.machine.name, con.to_plug.machine.name, color="%s:%s" % (color, wsc_color), label=label, penwidth="%s:%s" % (penwidth, penwidth))
graph.add_edge(con.from_plug.machine.name, con.to_plug.machine.name, color=color, label=label, penwidth=penwidth)
@ -481,10 +483,9 @@ def power_config_to_svg(power_config, svg_file_path, worst_case_scenario=True):
sub.graph_attr['label'] = rack_id
# sub.graph_attr['rank']='same'
# assert False
#graph.layout(prog='twopi')
# graph.layout(prog='twopi')
with open('./toto.dot', 'w') as f:
f.write(graph.string())
graph.layout(prog='dot')
graph.draw(svg_file_path)

View File

@ -1,6 +1,6 @@
# encoding: utf-8
import datetime
#from Lib import SimpaDbUtil
# from Lib import SimpaDbUtil
import SimpaDbUtil
@ -20,14 +20,14 @@ class PlugTypeNotFound(Exception):
class Inventory(object):
def __init__(self, sql_reader):
"""
:param SimpaDbUtil.SqlDatabaseReader sql_reader: the inventory database
"""
super(Inventory, self).__init__()
self._sql_reader = sql_reader
def query(self, sql_query):
return self._sql_reader.query(sql_query)
@ -48,7 +48,7 @@ class Inventory(object):
def machine_name_to_machine_spec_id(self, machine_name):
try:
machine_spec_id = self._sql_reader.get_table_attr('machines', 'name', machine_name, 'machine_spec_id')
except SimpaDbUtil.TableAttrNotFound as e: # @UnusedVariable
except SimpaDbUtil.TableAttrNotFound as e: # noqa: F841 @UnusedVariable
raise MachineSpecIdNotFound(machine_name)
if machine_spec_id == '':
raise MachineSpecIdNotFound(machine_name)
@ -59,7 +59,7 @@ class Inventory(object):
def machine_spec_id_to_power_consumption(self, machine_spec_id):
try:
power_consumption = float(self._sql_reader.get_table_attr('machine_spec_to_power_consumption', 'machine_spec_id', machine_spec_id, 'power_consumption'))
except SimpaDbUtil.TableAttrNotFound as e: # @UnusedVariable
except SimpaDbUtil.TableAttrNotFound as e: # noqa: F841 @UnusedVariable
# some passive machines such as pdus are not detailed in the machine_spec_to_power_consumption because they don't consume power
power_consumption = 0.0
return power_consumption
@ -72,7 +72,7 @@ class Inventory(object):
# ('iec60309_blue_pne6h_32a_m', 'm', 32.0),
attr_value = self._sql_reader.get_table_attr('powerplug_type_desc', 'plug_type_id', plug_type, attr_name)
return attr_value
def get_plug_type(self, machine_name, plug_name):
"""
:param str machine_name: eg 'pdu4'
@ -92,7 +92,7 @@ class Inventory(object):
else:
raise PlugTypeNotFound(machine_spec_id, plug_name)
return plug_type
def read_plug_capacity(self, plug):
"""
:param PowerDiagram.Plug plug: the power plug of a 'device' we're interested in (eg pdu4.o1)
@ -105,12 +105,12 @@ class Inventory(object):
except MachineSpecIdNotFound:
# some machines are not actual machines (eg edf, ups1pdu)
pass
#except PlugTypeNotFound:
# except PlugTypeNotFound:
# some plugs are just plain connections, with no actual plug types
# pass
if plug_type is not None:
# print('plug_type : %s' % plug_type)
plug_capacity = self.get_plug_type_attr(plug_type, 'max_amps')
# if plug_capacity:
# print('plug_capacity : %f A' % plug_capacity)
@ -150,7 +150,7 @@ class Inventory(object):
dflops_per_core_per_cycle = int(self._sql_reader.get_table_attr('cpu_specs', 'cpu_model', cpu_model, 'dflops_per_core_per_cycle'))
# print(num_cores, clock_speed, dflops_per_core_per_cycle)
return clock_speed * dflops_per_core_per_cycle * num_cores
def get_num_cpus(self, computer_name):
return int(self._sql_reader.get_table_attr('computer_to_cpu', 'computer_id', computer_name, 'num_cpu'))
@ -160,20 +160,20 @@ class Inventory(object):
def get_cpu_frequency(self, computer_name):
cpu_model = self._sql_reader.get_table_attr('computer_to_cpu', 'computer_id', computer_name, 'cpu_model')
return float(self._sql_reader.get_table_attr('cpu_specs', 'cpu_model', cpu_model, 'clock_speed'))
def get_computer_dflops(self, computer_name):
# print(computer_serial_number)
num_cpus = int(self._sql_reader.get_table_attr( 'computer_to_cpu', 'computer_id', computer_name, 'num_cpu'))
num_cpus = int(self._sql_reader.get_table_attr('computer_to_cpu', 'computer_id', computer_name, 'num_cpu'))
cpu_model = self._sql_reader.get_table_attr('computer_to_cpu', 'computer_id', computer_name, 'cpu_model')
flops = num_cpus * self.get_cpu_dflops(cpu_model)
return flops
def get_computer_options_price(self, computer_name):
options_price = 0.0
if computer_name == 'simpatix58' or computer_name == 'simpatix59':
return 7675.0 / 4 * 2 # each of these computers has 2 nvidia fermi C2050 gpus
return options_price
def get_item_container(self, item_id):
"""
:param str item_id: the identifier of an inventory item (a machine (eg simpa-switch002), a group of machines (ceph), etc.)
@ -184,7 +184,7 @@ class Inventory(object):
if len(rows) > 0:
container_id = rows[0][0]
return container_id
def get_item_price(self, item_id, include_contents=False, include_maintenance=False):
"""
:param str item_id: the identifier of an inventory item (a machine (eg simpa-switch002), a group of machines (ceph), etc.)
@ -201,7 +201,7 @@ class Inventory(object):
for row in rows:
maintenance_price_ex_vat = float(row[0])
item_price += maintenance_price_ex_vat
if include_contents:
# add the price of included parts
rows = self._sql_reader.query("SELECT part_id FROM container WHERE container_id='%s'" % item_id)
@ -210,10 +210,10 @@ class Inventory(object):
item_price += self.get_item_price(part_id, include_contents, include_maintenance)
# print(u'price of %s : %.2f € HT' % (item_id, item_price))
return item_price
def get_item_ownership(self, item_id):
ownership = []
rows = self._sql_reader.query("SELECT * FROM ownership WHERE machine_id='%s'" % item_id)
for row in rows:
(machine_id, owner, owner_ratio, comment) = row # @UnusedVariable
@ -222,7 +222,7 @@ class Inventory(object):
def get_item_use(self, item_id):
ownership = []
rows = self._sql_reader.query("SELECT * FROM machine_users")
for row in rows:
(machine_id, user, user_ratio, comment) = row # @UnusedVariable