From a4ae643dd5fa601e468ad8b681118420aff1fb76 Mon Sep 17 00:00:00 2001 From: fk410167 <51665572+fk410167@users.noreply.github.com> Date: Wed, 10 Mar 2021 05:48:01 +0530 Subject: [PATCH] [PDDF] Remove references to deprecated platform plugins (#1485) #### What I did - Removed the references of deprecated plugins from PDDF utils - Removed the references of the deprecated plugins from helper utility util_base #### How I did it - Made PDDF debug utils python3 - Modified them to base only upon the 2.0 platform APIs classes - Removed the helper utilities pertaining to old plugins init --- pddf_fanutil/main.py | 242 +++++++++---------------- pddf_ledutil/main.py | 66 +++---- pddf_psuutil/main.py | 324 +++++++++++++--------------------- pddf_thermalutil/main.py | 140 ++++++--------- utilities_common/util_base.py | 60 +++---- 5 files changed, 299 insertions(+), 533 deletions(-) diff --git a/pddf_fanutil/main.py b/pddf_fanutil/main.py index 3620be42f910..48969e9d0aff 100644 --- a/pddf_fanutil/main.py +++ b/pddf_fanutil/main.py @@ -16,121 +16,40 @@ VERSION = '2.0' -SYSLOG_IDENTIFIER = "fanutil" -PLATFORM_SPECIFIC_MODULE_NAME = "fanutil" -PLATFORM_SPECIFIC_CLASS_NAME = "FanUtil" +ERROR_PERMISSIONS = 1 +ERROR_CHASSIS_LOAD = 2 +ERROR_NOT_IMPLEMENTED = 3 +ERROR_PDDF_NOT_SUPPORTED = 4 -# Global platform-specific fanutil class instance -platform_fanutil = None +# Global platform-specific chassis class instance platform_chassis = None +# Load the helper class +helper = UtilHelper() -def _wrapper_get_num_fans(): - if platform_chassis is not None: - try: - return platform_chassis.get_num_fans() - except NotImplementedError: - pass - return platform_fanutil.get_num_fans() - -def _wrapper_get_fan_name(idx): - if platform_chassis is not None: - try: - return platform_chassis.get_fan(idx-1).get_name() - except NotImplementedError: - pass - return "FAN {}".format(idx) - -def _wrapper_get_fan_presence(idx): - if platform_chassis is not None: - try: - return platform_chassis.get_fan(idx-1).get_presence() - except NotImplementedError: - pass - return platform_fanutil.get_presence(idx) - -def _wrapper_get_fan_status(idx): - if platform_chassis is not None: - try: - return platform_chassis.get_fan(idx-1).get_status() - except NotImplementedError: - pass - return platform_fanutil.get_status(idx) - -def _wrapper_get_fan_direction(idx): - if platform_chassis is not None: - try: - return platform_chassis.get_fan(idx-1).get_direction() - except NotImplementedError: - pass - return platform_fanutil.get_direction(idx) - -def _wrapper_get_fan_speed(idx): - if platform_chassis is not None: - try: - return platform_chassis.get_fan(idx-1).get_speed_rpm() - except NotImplementedError: - pass - return platform_fanutil.get_speed(idx) - -def _wrapper_get_fan_speed_rear(idx): - if platform_chassis is not None: - # This wrapper API is invalid for Pl API 2.0 as every fan - # is treated as a separate fan - return 0 - return platform_fanutil.get_speed_rear(idx) - -def _wrapper_set_fan_speed(idx, percent): - if platform_chassis is not None: - try: - return platform_chassis.get_fan(idx-1).set_speed(percent) - except NotImplementedError: - pass - return platform_fanutil.set_speed(percent) - -def _wrapper_dump_sysfs(idx): - if platform_chassis is not None: - try: - return platform_chassis.get_fan(idx).dump_sysfs() - except NotImplementedError: - pass - return platform_fanutil.dump_sysfs() +# ==================== CLI commands and groups ==================== -# This is our main entrypoint - the main 'fanutil' command +# This is our main entrypoint - the main 'pddf_fanutil' command @click.group() def cli(): """pddf_fanutil - Command line utility for providing FAN information""" - global platform_fanutil global platform_chassis if os.geteuid() != 0: click.echo("Root privileges are required for this operation") - sys.exit(1) - - # Load the helper class - helper = UtilHelper() + sys.exit(ERROR_PERMISSIONS) if not helper.check_pddf_mode(): click.echo("PDDF mode should be supported and enabled for this platform for this operation") - sys.exit(1) - - # Load new platform api class - try: - import sonic_platform.platform - platform_chassis = sonic_platform.platform.Platform().get_chassis() - except Exception as e: - click.echo("Failed to load chassis due to {}".format(str(e))) + sys.exit(ERROR_PDDF_NOT_SUPPORTED) + # Load platform-specific chassis 2.0 api class + platform_chassis = helper.load_platform_chassis() + if not platform_chassis: + sys.exit(ERROR_CHASSIS_LOAD) - # Load platform-specific fanutil class if new platform object class is not found - if platform_chassis is None: - try: - platform_fanutil = helper.load_platform_util(PLATFORM_SPECIFIC_MODULE_NAME, PLATFORM_SPECIFIC_CLASS_NAME) - except Exception as e: - click.echo("Failed to load {}: {}".format(PLATFORM_SPECIFIC_MODULE_NAME, str(e))) - sys.exit(2) # 'version' subcommand @cli.command() @@ -138,107 +57,98 @@ def version(): """Display version info""" click.echo("PDDF fanutil version {0}".format(VERSION)) + # 'numfans' subcommand @cli.command() def numfans(): """Display number of FANs installed on device""" - click.echo(_wrapper_get_num_fans()) + num_fans = platform_chassis.get_num_fans() + click.echo(num_fans) + # 'status' subcommand @cli.command() -@click.option('-i', '--index', default=-1, type=int, help="the index of FAN") +@click.option('-i', '--index', default=-1, type=int, help="Index of FAN (1-based)") def status(index): """Display FAN status""" - supported_fan = list(range(1, _wrapper_get_num_fans()+1)) - fan_ids = [] + fan_list = [] if (index < 0): - fan_ids = supported_fan + fan_list = platform_chassis.get_all_fans() + default_index = 0 else: - fan_ids = [index] + fan_list = platform_chassis.get_fan(index-1) + default_index = index-1 header = ['FAN', 'Status'] status_table = [] - for fan in fan_ids: - msg = "" - fan_name = _wrapper_get_fan_name(fan) - if fan not in supported_fan: - click.echo("Error! The {} is not available on the platform.\n" \ - "Number of supported FAN - {}.".format(fan_name, len(supported_fan))) - continue - presence = _wrapper_get_fan_presence(fan) - if presence: - oper_status = _wrapper_get_fan_status(fan) - msg = 'OK' if oper_status else "NOT OK" - else: - msg = 'NOT PRESENT' - status_table.append([fan_name, msg]) + for idx, fan in enumerate(fan_list, default_index): + fan_name = helper.try_get(fan.get_name, "Fan {}".format(idx+1)) + status = 'NOT PRESENT' + if fan.get_presence(): + oper_status = helper.try_get(fan.get_status, 'UNKNOWN') + if oper_status is True: + status = 'OK' + elif oper_status is False: + status = 'NOT OK' + else: + status = oper_status + + status_table.append([fan_name, status]) if status_table: click.echo(tabulate(status_table, header, tablefmt="simple")) + # 'direction' subcommand @cli.command() -@click.option('-i', '--index', default=-1, type=int, help="the index of FAN") +@click.option('-i', '--index', default=-1, type=int, help="Index of FAN (1-based)") def direction(index): """Display FAN airflow direction""" - supported_fan = list(range(1, _wrapper_get_num_fans() + 1)) - fan_ids = [] + fan_list = [] if (index < 0): - fan_ids = supported_fan + fan_list = platform_chassis.get_all_fans() + default_index = 0 else: - fan_ids = [index] + fan_list = platform_chassis.get_fan(index-1) + default_index = index-1 header = ['FAN', 'Direction'] - status_table = [] + dir_table = [] - for fan in fan_ids: - fan_name = _wrapper_get_fan_name(fan) - if fan not in supported_fan: - click.echo("Error! The {} is not available on the platform.\n" \ - "Number of supported FAN - {}.".format(fan_name, len(supported_fan))) - continue - direction = _wrapper_get_fan_direction(fan) - status_table.append([fan_name, direction.capitalize()]) + for idx, fan in enumerate(fan_list, default_index): + fan_name = helper.try_get(fan.get_name, "Fan {}".format(idx+1)) + direction = helper.try_get(fan.get_direction, 'N/A') + dir_table.append([fan_name, direction.capitalize()]) + + if dir_table: + click.echo(tabulate(dir_table, header, tablefmt="simple")) - if status_table: - click.echo(tabulate(status_table, header, tablefmt="simple")) # 'speed' subcommand @cli.command() -@click.option('-i', '--index', default=-1, type=int, help="the index of FAN") +@click.option('-i', '--index', default=-1, type=int, help="Index of FAN (1-based)") def getspeed(index): """Display FAN speed in RPM""" - supported_fan = list(range(1, _wrapper_get_num_fans() + 1)) - fan_ids = [] + fan_list = [] if (index < 0): - fan_ids = supported_fan + fan_list = platform_chassis.get_all_fans() + default_index = 0 else: - fan_ids = [index] + fan_list = platform_chassis.get_fan(index-1) + default_index = index-1 - if platform_chassis is not None: - header = ['FAN', 'SPEED (RPM)'] - else: - header = ['FAN', 'Front Fan RPM', 'Rear Fan RPM'] - - status_table = [] + header = ['FAN', 'SPEED (RPM)'] + speed_table = [] - for fan in fan_ids: - fan_name = _wrapper_get_fan_name(fan) - if fan not in supported_fan: - click.echo("Error! The {} is not available on the platform.\n" \ - "Number of supported FAN - {}.".format(fan_name, len(supported_fan))) - continue - front = _wrapper_get_fan_speed(fan) - rear = _wrapper_get_fan_speed_rear(fan) + for idx, fan in enumerate(fan_list, default_index): + fan_name = helper.try_get(fan.get_name, "Fan {}".format(idx+1)) + rpm = helper.try_get(fan.get_speed_rpm, 'N/A') + speed_table.append([fan_name, rpm]) - if platform_chassis is not None: - status_table.append([fan_name, front]) - else: - status_table.append([fan_name, front, rear]) + if speed_table: + click.echo(tabulate(speed_table, header, tablefmt="simple")) - if status_table: - click.echo(tabulate(status_table, header, tablefmt="simple")) # 'setspeed' subcommand @cli.command() @@ -249,30 +159,38 @@ def setspeed(speed): click.echo("speed value is required") raise click.Abort() - for fan in range(_wrapper_get_num_fans()): - status = _wrapper_set_fan_speed(fan, speed) + fan_list = platform_chassis.get_all_fans() + for idx, fan in enumerate(fan_list): + try: + status = fan.set_speed(speed) + except NotImplementedError: + click.echo("Set speed API not implemented") + sys.exit(0) + if not status: click.echo("Failed") sys.exit(1) click.echo("Successful") + @cli.group() def debug(): """pddf_fanutil debug commands""" pass + @debug.command() def dump_sysfs(): """Dump all Fan related SysFS paths""" - for fan in range(_wrapper_get_num_fans()): - status = _wrapper_dump_sysfs(fan) + fan_list = platform_chassis.get_all_fans() + for idx, fan in enumerate(fan_list): + status = fan.dump_sysfs() if status: for i in status: click.echo(i) - if __name__ == '__main__': cli() diff --git a/pddf_ledutil/main.py b/pddf_ledutil/main.py index c7bfb71314d0..63a87939c166 100644 --- a/pddf_ledutil/main.py +++ b/pddf_ledutil/main.py @@ -15,68 +15,40 @@ VERSION = '2.0' -SYSLOG_IDENTIFIER = "ledutil" -PLATFORM_SPECIFIC_MODULE_NAME = "ledutil" -PLATFORM_SPECIFIC_CLASS_NAME = "LedUtil" +ERROR_PERMISSIONS = 1 +ERROR_CHASSIS_LOAD = 2 +ERROR_NOT_IMPLEMENTED = 3 +ERROR_PDDF_NOT_SUPPORTED = 4 -# Global platform-specific ledutil class instance -platform_ledutil = None +# Global platform-specific chassis class instance platform_chassis = None - -# ==================== Wrapper APIs ==================== -def _wrapper_getstatusled(device_name): - if platform_chassis is not None: - outputs=platform_chassis.get_system_led(device_name) - else: - outputs = platform_ledutil.get_status_led(device_name) - click.echo(outputs) - -def _wrapper_setstatusled(device_name, color, color_state): - if platform_chassis is not None: - outputs=platform_chassis.set_system_led(device_name, color) - else: - outputs = platform_ledutil.set_status_led(device_name, color, color_state) - click.echo(outputs) - +# Load the helper class +helper = UtilHelper() # ==================== CLI commands and groups ==================== -# This is our main entrypoint - the main 'ledutil' command +# This is our main entrypoint - the main 'pddf_ledutil' command @click.group() def cli(): """pddf_ledutil - Command line utility for providing System LED information""" + global platform_chassis + if os.geteuid() != 0: click.echo("Root privileges are required for this operation") sys.exit(1) - # Load the helper class - helper = UtilHelper() - if not helper.check_pddf_mode(): click.echo("PDDF mode should be supported and enabled for this platform for this operation") sys.exit(1) - # Load platform-specific fanutil class - global platform_ledutil - global platform_chassis + # Load platform-specific chassis 2.0 api class + platform_chassis = helper.load_platform_chassis() + if not platform_chassis: + sys.exit(ERROR_CHASSIS_LOAD) - # Load new platform api class - try: - import sonic_platform.platform - platform_chassis = sonic_platform.platform.Platform().get_chassis() - except Exception as e: - click.echo("Failed to load chassis due to {}".format(str(e))) - - # Load platform-specific psuutil class if 2.0 implementation is not present - if platform_chassis is None: - try: - platform_ledutil = helper.load_platform_util(PLATFORM_SPECIFIC_MODULE_NAME, PLATFORM_SPECIFIC_CLASS_NAME) - except Exception as e: - click.echo("Failed to load {}: {}".format(PLATFORM_SPECIFIC_MODULE_NAME, str(e))) - sys.exit(2) # 'version' subcommand @cli.command() @@ -84,6 +56,7 @@ def version(): """Display version info""" click.echo("PDDF ledutil version {0}".format(VERSION)) + # 'getstatusled' subcommand @cli.command() @click.argument('device_name', type=click.STRING) @@ -92,20 +65,21 @@ def getstatusled(device_name): click.echo("device_name is required") raise click.Abort() - _wrapper_getstatusled(device_name) + outputs = platform_chassis.get_system_led(device_name) + click.echo(outputs) # 'setstatusled' subcommand @cli.command() @click.argument('device_name', type=click.STRING) @click.argument('color', type=click.STRING) -@click.argument('color_state', default='SOLID', type=click.STRING) -def setstatusled(device_name, color, color_state): +def setstatusled(device_name, color): if device_name is None: click.echo("device_name is required") raise click.Abort() - _wrapper_setstatusled(device_name, color, color_state) + outputs = platform_chassis.set_system_led(device_name, color) + click.echo(outputs) if __name__ == '__main__': diff --git a/pddf_psuutil/main.py b/pddf_psuutil/main.py index 4662eb3534b5..41c4b78d28ba 100644 --- a/pddf_psuutil/main.py +++ b/pddf_psuutil/main.py @@ -16,234 +16,130 @@ VERSION = '2.0' -SYSLOG_IDENTIFIER = "psuutil" -PLATFORM_SPECIFIC_MODULE_NAME = "psuutil" -PLATFORM_SPECIFIC_CLASS_NAME = "PsuUtil" +ERROR_PERMISSIONS = 1 +ERROR_CHASSIS_LOAD = 2 +ERROR_NOT_IMPLEMENTED = 3 +ERROR_PDDF_NOT_SUPPORTED = 4 -# Global platform-specific psuutil class instance -platform_psuutil = None +# Global platform-specific chassis class instance platform_chassis = None - -# Wrapper APIs so that this util is suited to both 1.0 and 2.0 platform APIs -def _wrapper_get_num_psus(): - if platform_chassis is not None: - try: - return platform_chassis.get_num_psus() - except NotImplementedError: - pass - return platform_psuutil.get_num_psus() - -def _wrapper_get_psu_name(idx): - if platform_chassis is not None: - try: - return platform_chassis.get_psu(idx-1).get_name() - except NotImplementedError: - pass - return "PSU {}".format(idx) - -def _wrapper_get_psu_presence(idx): - if platform_chassis is not None: - try: - return platform_chassis.get_psu(idx-1).get_presence() - except NotImplementedError: - pass - return platform_psuutil.get_psu_presence(idx) - -def _wrapper_get_psu_status(idx): - if platform_chassis is not None: - try: - return platform_chassis.get_psu(idx-1).get_status() - except NotImplementedError: - pass - return platform_psuutil.get_psu_status(idx) - -def _wrapper_get_psu_model(idx): - if platform_chassis is not None: - try: - return platform_chassis.get_psu(idx-1).get_model() - except NotImplementedError: - pass - return platform_psuutil.get_model(idx) - -def _wrapper_get_psu_mfr_id(idx): - if platform_chassis is not None: - try: - return platform_chassis.get_psu(idx-1).get_mfr_id() - except NotImplementedError: - pass - return platform_psuutil.get_mfr_id(idx) - -def _wrapper_get_psu_serial(idx): - if platform_chassis is not None: - try: - return platform_chassis.get_psu(idx-1).get_serial() - except NotImplementedError: - pass - return platform_psuutil.get_serial(idx) - -def _wrapper_get_psu_direction(idx): - if platform_chassis is not None: - try: - return platform_chassis.get_psu(idx-1)._fan_list[0].get_direction() - except NotImplementedError: - pass - return platform_psuutil.get_direction(idx) - -def _wrapper_get_output_voltage(idx): - if platform_chassis is not None: - try: - return platform_chassis.get_psu(idx-1).get_voltage() - except NotImplementedError: - pass - return platform_psuutil.get_output_voltage(idx) - -def _wrapper_get_output_current(idx): - if platform_chassis is not None: - try: - return platform_chassis.get_psu(idx-1).get_current() - except NotImplementedError: - pass - return platform_psuutil.get_output_current(idx) - -def _wrapper_get_output_power(idx): - if platform_chassis is not None: - try: - return platform_chassis.get_psu(idx-1).get_power() - except NotImplementedError: - pass - return platform_psuutil.get_output_power(idx) - -def _wrapper_get_fan_rpm(idx, fan_idx): - if platform_chassis is not None: - try: - return platform_chassis.get_psu(idx-1)._fan_list[fan_idx-1].get_speed_rpm() - except NotImplementedError: - pass - return platform_psuutil.get_fan_rpm(idx, fan_idx) - -def _wrapper_dump_sysfs(idx): - if platform_chassis is not None: - try: - return platform_chassis.get_psu(idx).dump_sysfs() - except NotImplementedError: - pass - return platform_psuutil.dump_sysfs() +# Load the helper class +helper = UtilHelper() # ==================== CLI commands and groups ==================== - -# This is our main entrypoint - the main 'psuutil' command +# This is our main entrypoint - the main 'pddf_psuutil' command @click.group() def cli(): - """psuutil - Command line utility for providing PSU status""" + """pddf_psuutil - Command line utility for providing PSU status for a platform using PDDF""" - global platform_psuutil global platform_chassis if os.geteuid() != 0: click.echo("Root privileges are required for this operation") - sys.exit(1) - - # Load the helper class - helper = UtilHelper() + sys.exit(ERROR_PERMISSIONS) if not helper.check_pddf_mode(): click.echo("PDDF mode should be supported and enabled for this platform for this operation") - sys.exit(1) + sys.exit(ERROR_PDDF_NOT_SUPPORTED) - # Load new platform api class - try: - import sonic_platform.platform - platform_chassis = sonic_platform.platform.Platform().get_chassis() - except Exception as e: - click.echo("Failed to load chassis due to {}".format(str(e))) + # Load platform-specific chassis 2.0 api class + platform_chassis = helper.load_platform_chassis() + if not platform_chassis: + sys.exit(ERROR_CHASSIS_LOAD) - # Load platform-specific psuutil class if 2.0 implementation is not present - if platform_chassis is None: - try: - platform_psuutil = helper.load_platform_util(PLATFORM_SPECIFIC_MODULE_NAME, PLATFORM_SPECIFIC_CLASS_NAME) - except Exception as e: - click.echo("Failed to load {}: {}".format(PLATFORM_SPECIFIC_MODULE_NAME, str(e))) - sys.exit(2) - # 'version' subcommand @cli.command() def version(): """Display version info""" click.echo("PDDF psuutil version {0}".format(VERSION)) + # 'numpsus' subcommand @cli.command() def numpsus(): """Display number of supported PSUs on device""" - click.echo(_wrapper_get_num_psus()) + num_psus = platform_chassis.get_num_psus() + click.echo(str(num_psus)) + # 'status' subcommand @cli.command() -@click.option('-i', '--index', default=-1, type=int, help="the index of PSU") +@click.option('-i', '--index', default=-1, type=int, help="Index of the PSU (1-based)") def status(index): """Display PSU status""" - supported_psu = list(range(1, _wrapper_get_num_psus() + 1)) - psu_ids = [] + psu_list = [] if (index < 0): - psu_ids = supported_psu + psu_list = platform_chassis.get_all_psus() + default_index = 0 else: - psu_ids = [index] + psu_list = platform_chassis.get_psu(index-1) + default_index = index-1 header = ['PSU', 'Status'] status_table = [] - for psu in psu_ids: - msg = "" - psu_name = _wrapper_get_psu_name(psu) - if psu not in supported_psu: - click.echo("Error! The {} is not available on the platform.\n" \ - "Number of supported PSU - {}.".format(psu_name, len(supported_psu))) - continue - presence = _wrapper_get_psu_presence(psu) - if presence: - oper_status = _wrapper_get_psu_status(psu) - msg = 'OK' if oper_status else "NOT OK" - else: - msg = 'NOT PRESENT' - status_table.append([psu_name, msg]) + for idx, psu in enumerate(psu_list, default_index): + psu_name = helper.try_get(psu.get_name, "PSU {}".format(idx+1)) + status = 'NOT PRESENT' + if psu.get_presence(): + oper_status = helper.try_get(psu.get_powergood_status, 'UNKNOWN') + if oper_status is True: + status = 'OK' + elif oper_status is False: + status = 'NOT OK' + else: + status = oper_status + + status_table.append([psu_name, status]) if status_table: - click.echo(tabulate(status_table, header, tablefmt="simple")) + click.echo(tabulate(status_table, header, tablefmt='simple')) + # 'mfrinfo' subcommand @cli.command() -@click.option('-i', '--index', default=-1, type=int, help="the index of PSU") +@click.option('-i', '--index', default=-1, type=int, help="Index of the PSU (1-based)") def mfrinfo(index): """Display PSU manufacturer info""" - supported_psu = list(range(1, _wrapper_get_num_psus() + 1)) - psu_ids = [] + psu_list = [] if (index < 0): - psu_ids = supported_psu + psu_list = platform_chassis.get_all_psus() + default_index = 0 else: - psu_ids = [index] - - for psu in psu_ids: - psu_name = _wrapper_get_psu_name(psu) - if psu not in supported_psu: - click.echo("Error! The {} is not available on the platform.\n" \ - "Number of supported PSU - {}.".format(psu_name, len(supported_psu))) - continue - status = _wrapper_get_psu_status(psu) - if not status: - click.echo("{} is Not OK\n".format(psu_name)) - continue - - model_name = _wrapper_get_psu_model(psu) - mfr_id = _wrapper_get_psu_mfr_id(psu) - serial_num = _wrapper_get_psu_serial(psu) - airflow_dir = _wrapper_get_psu_direction(psu) - - click.echo("{} is OK\nManufacture Id: {}\n" \ - "Model: {}\nSerial Number: {}\n" \ - "Fan Direction: {}\n".format(psu_name, mfr_id, model_name, serial_num, airflow_dir.capitalize())) + psu_list = platform_chassis.get_psu(index-1) + default_index = index-1 + + header = ['PSU', 'Status', 'Manufacturer ID', 'Model', 'Serial', 'Fan Airflow Direction'] + mfrinfo_table = [] + + for idx, psu in enumerate(psu_list, default_index): + psu_name = helper.try_get(psu.get_name, "PSU {}".format(idx+1)) + status = 'NOT PRESENT' + model_name = 'N/A' + mfr_id = 'N/A' + serial_num = 'N/A' + airflow_dir = 'N/A' + if psu.get_presence(): + oper_status = helper.try_get(psu.get_powergood_status, 'UNKNOWN') + if oper_status is True: + status = 'OK' + elif oper_status is False: + status = 'NOT OK' + else: + status = oper_status + + model_name = helper.try_get(psu.get_model, 'N/A') + mfr_id = helper.try_get(psu.get_mfr_id, 'N/A') + serial_num = helper.try_get(psu.get_serial, 'N/A') + airflow_dir = helper.try_get(psu._fan_list[0].get_direction, 'N/A') + + mfrinfo_table.append([psu_name, status, mfr_id, model_name, serial_num, airflow_dir]) + + if mfrinfo_table: + click.echo(tabulate(mfrinfo_table, header, tablefmt='simple')) # 'seninfo' subcommand @@ -251,44 +147,60 @@ def mfrinfo(index): @click.option('-i', '--index', default=-1, type=int, help="the index of PSU") def seninfo(index): """Display PSU sensor info""" - supported_psu = list(range(1, _wrapper_get_num_psus() + 1)) - psu_ids = [] + psu_list = [] if (index < 0): - psu_ids = supported_psu + psu_list = platform_chassis.get_all_psus() + default_index = 0 else: - psu_ids = [index] - - for psu in psu_ids: - psu_name = _wrapper_get_psu_name(psu) - if psu not in supported_psu: - click.echo("Error! The {} is not available on the platform.\n" \ - "Number of supported PSU - {}.".format(psu_name, len(supported_psu))) - continue - oper_status = _wrapper_get_psu_status(psu) - - if not oper_status: - click.echo("{} is Not OK\n".format(psu_name)) - continue - - v_out = _wrapper_get_output_voltage(psu) * 1000 - i_out = _wrapper_get_output_current(psu) * 1000 - p_out = _wrapper_get_output_power(psu) * 1000 - - fan1_rpm = _wrapper_get_fan_rpm(psu, 1) - click.echo("{} is OK\nOutput Voltage: {} mv\n" \ - "Output Current: {} ma\nOutput Power: {} mw\n" \ - "Fan1 Speed: {} rpm\n".format(psu_name, v_out, i_out, p_out, fan1_rpm)) + psu_list = platform_chassis.get_psu(index-1) + default_index = index-1 + + header = ['PSU', 'Status', 'Output Voltage (V)', 'Output Current (A)', + 'Output Power (W)', 'Temperature1 (C)', 'Fan1 Speed (RPM)'] + seninfo_table = [] + + for idx, psu in enumerate(psu_list, default_index): + psu_name = helper.try_get(psu.get_name, "PSU {}".format(idx+1)) + status = 'NOT PRESENT' + v_out = 'N/A' + i_out = 'N/A' + p_out = 'N/A' + temp1 = 'N/A' + fan1_rpm = 'N/A' + + if psu.get_presence(): + oper_status = helper.try_get(psu.get_powergood_status, 'UNKNOWN') + if oper_status is True: + status = 'OK' + elif oper_status is False: + status = 'NOT OK' + else: + status = oper_status + + v_out = helper.try_get(psu.get_voltage, 'N/A') + i_out = helper.try_get(psu.get_current, 'N/A') + p_out = helper.try_get(psu.get_power, 'N/A') + temp1 = helper.try_get(psu.get_temperature, 'N/A') + fan1_rpm = helper.try_get(psu._fan_list[0].get_speed_rpm, 'N/A') + + seninfo_table.append([psu_name, status, v_out, i_out, p_out, temp1, fan1_rpm]) + + if seninfo_table: + click.echo(tabulate(seninfo_table, header, tablefmt='simple', floatfmt='.2f')) + @cli.group() def debug(): """pddf_psuutil debug commands""" pass + @debug.command() def dump_sysfs(): """Dump all PSU related SysFS paths""" - for psu in range(_wrapper_get_num_psus()): - status = _wrapper_dump_sysfs(psu) + psu_list = platform_chassis.get_all_psus() + for psu in psu_list: + status = psu.dump_sysfs() if status: for i in status: diff --git a/pddf_thermalutil/main.py b/pddf_thermalutil/main.py index 976e5b4f2f8c..aacad45e0bda 100644 --- a/pddf_thermalutil/main.py +++ b/pddf_thermalutil/main.py @@ -16,69 +16,38 @@ VERSION = '2.0' -SYSLOG_IDENTIFIER = "thermalutil" -PLATFORM_SPECIFIC_MODULE_NAME = "thermalutil" -PLATFORM_SPECIFIC_CLASS_NAME = "ThermalUtil" +ERROR_PERMISSIONS = 1 +ERROR_CHASSIS_LOAD = 2 +ERROR_NOT_IMPLEMENTED = 3 +ERROR_PDDF_NOT_SUPPORTED = 4 -# Global platform-specific thermalutil class instance -platform_thermalutil = None +# Global platform-specific chassis class instance platform_chassis = None -# Wrapper APIs so that this util is suited to both 1.0 and 2.0 platform APIs -def _wrapper_get_num_thermals(): - if platform_chassis is not None: - try: - return platform_chassis.get_num_thermals() - except NotImplementedError: - pass - return platform_thermalutil.get_num_thermals() - -def _wrapper_get_thermal_name(idx): - if platform_chassis is not None: - try: - return platform_chassis.get_thermal(idx-1).get_name() - except NotImplementedError: - pass - return "TEMP{}".format(idx) - +# Load the helper class +helper = UtilHelper() # ==================== CLI commands and groups ==================== - # This is our main entrypoint - the main 'thermalutil' command @click.group() def cli(): """pddf_thermalutil - Command line utility for providing Temp Sensors information""" - global platform_thermalutil global platform_chassis if os.geteuid() != 0: click.echo("Root privileges are required for this operation") sys.exit(1) - # Load the helper class - helper = UtilHelper() - if not helper.check_pddf_mode(): click.echo("PDDF mode should be supported and enabled for this platform for this operation") sys.exit(1) - # Load new platform api class - try: - import sonic_platform.platform - platform_chassis = sonic_platform.platform.Platform().get_chassis() - except Exception as e: - click.echo("Failed to load chassis due to {}".format(str(e))) - - - # Load platform-specific fanutil class - if platform_chassis is None: - try: - platform_thermalutil = helper.load_platform_util(PLATFORM_SPECIFIC_MODULE_NAME, PLATFORM_SPECIFIC_CLASS_NAME) - except Exception as e: - click.echo("Failed to load {}: {}".format(PLATFORM_SPECIFIC_MODULE_NAME, str(e))) - sys.exit(2) + # Load platform-specific chassis 2.0 api class + platform_chassis = helper.load_platform_chassis() + if not platform_chassis: + sys.exit(ERROR_CHASSIS_LOAD) # 'version' subcommand @@ -87,83 +56,78 @@ def version(): """Display version info""" click.echo("PDDF thermalutil version {0}".format(VERSION)) + # 'numthermals' subcommand @cli.command() def numthermals(): """Display number of Thermal Sensors installed """ - click.echo(_wrapper_get_num_thermals()) + num_thermals = platform_chassis.get_num_thermals() + click.echo(num_thermals) + # 'gettemp' subcommand @cli.command() -@click.option('-i', '--index', default=-1, type=int, help="the index of Temp Sensor") +@click.option('-i', '--index', default=-1, type=int, help="Index of Temp Sensor (1-based)") def gettemp(index): """Display Temperature values of thermal sensors""" - supported_thermal = list(range(1, _wrapper_get_num_thermals()+ 1)) - thermal_ids = [] + thermal_list = [] if (index < 0): - thermal_ids = supported_thermal + thermal_list = platform_chassis.get_all_thermals() + default_index = 0 else: - thermal_ids = [index] + thermal_list = platform_chassis.get_thermal(index-1) + default_index = index-1 - header=[] - status_table = [] + header = [] + temp_table = [] - for thermal in thermal_ids: - thermal_name = _wrapper_get_thermal_name(thermal) - if thermal not in supported_thermal: - click.echo("Error! The {} is not available on the platform.\n" \ - "Number of supported Temp - {}.".format(thermal_name, len(supported_thermal))) - continue + for idx, thermal in enumerate(thermal_list, default_index): + thermal_name = helper.try_get(thermal.get_name, "TEMP{}".format(idx+1)) # TODO: Provide a wrapper API implementation for the below function - if platform_chassis is not None: - try: - temp = platform_chassis.get_thermal(thermal-1).get_temperature() - if temp: - value = "temp1\t %+.1f C ("%temp - high = platform_chassis.get_thermal(thermal-1).get_high_threshold() - if high: - value += "high = %+.1f C"%high - crit = platform_chassis.get_thermal(thermal-1).get_high_critical_threshold() - if high and crit: - value += ", " - if crit: - value += "crit = %+.1f C"%crit - - - label = platform_chassis.get_thermal(thermal-1).get_temp_label() - value +=")" - - except NotImplementedError: - pass - else: - label, value = platform_thermalutil.show_thermal_temp_values(thermal) + try: + temp = thermal.get_temperature() + if temp: + value = "temp1\t %+.1f C (" % temp + high = thermal.get_high_threshold() + if high: + value += "high = %+.1f C" % high + crit = thermal.get_high_critical_threshold() + if high and crit: + value += ", " + if crit: + value += "crit = %+.1f C" % crit + + label = thermal.get_temp_label() + value += ")" + + except NotImplementedError: + pass if label is None: - status_table.append([thermal_name, value]) + temp_table.append([thermal_name, value]) else: - status_table.append([thermal_name, label, value]) + temp_table.append([thermal_name, label, value]) - if status_table: + if temp_table: if label is None: header = ['Temp Sensor', 'Value'] else: header = ['Temp Sensor', 'Label', 'Value'] - click.echo(tabulate(status_table, header, tablefmt="simple")) + click.echo(tabulate(temp_table, header, tablefmt="simple")) + @cli.group() def debug(): """pddf_thermalutil debug commands""" pass + @debug.command() def dump_sysfs(): """Dump all Temp Sensor related SysFS paths""" - if platform_chassis is not None: - supported_thermal = list(range(1, _wrapper_get_num_thermals()+ 1)) - for index in supported_thermal: - status = platform_chassis.get_thermal(index-1).dump_sysfs() - else: - status = platform_thermalutil.dump_sysfs() + thermal_list = platform_chassis.get_all_thermals() + for idx, thermal in enumerate(thermal_list): + status = thermal.dump_sysfs() if status: for i in status: diff --git a/utilities_common/util_base.py b/utilities_common/util_base.py index 8dc15a4402fd..18da93de7ae1 100644 --- a/utilities_common/util_base.py +++ b/utilities_common/util_base.py @@ -1,51 +1,49 @@ -try: - import imp - import os - from sonic_py_common import device_info -except ImportError as e: - raise ImportError (str(e) + " - required module not found") +import os +import sonic_platform -# # Constants ==================================================================== -# -PDDF_FILE_PATH = '/usr/share/sonic/platform/pddf_support' +PDDF_SUPPORT_FILE = '/usr/share/sonic/platform/pddf_support' -EEPROM_MODULE_NAME = 'eeprom' -EEPROM_CLASS_NAME = 'board' +# Helper classs class UtilHelper(object): def __init__(self): pass - # Loads platform specific psuutil module from source - def load_platform_util(self, module_name, class_name): - platform_util = None + # try get information from platform API and return a default value if caught NotImplementedError + def try_get(self, callback, default=None): + """ + Handy function to invoke the callback and catch NotImplementedError + :param callback: Callback to be invoked + :param default: Default return value if exception occur + :return: Default return value if exception occur else return value of the callback + """ + try: + ret = callback() + if ret is None: + ret = default + except NotImplementedError: + ret = default - # Get path to platform and hwsku - (platform_path, hwsku_path) = device_info.get_paths_to_platform_and_hwsku_dirs() + return ret - try: - module_file = os.path.join(platform_path, "plugins", module_name + ".py") - module = imp.load_source(module_name, module_file) - except IOError as e: - raise IOError("Failed to load platform module '%s': %s" % (module_name, str(e))) + # Instantiate platform-specific Chassis class + def load_platform_chassis(self): + chassis = None + # Load 2.0 platform API chassis class try: - platform_util_class = getattr(module, class_name) - # board class of eeprom requires 4 paramerters, need special treatment here. - if module_name == EEPROM_MODULE_NAME and class_name == EEPROM_CLASS_NAME: - platform_util = platform_util_class('','','','') - else: - platform_util = platform_util_class() - except AttributeError as e: - raise AttributeError("Failed to instantiate '%s' class: %s" % (class_name, str(e))) + chassis = sonic_platform.platform.Platform().get_chassis() + except Exception as e: + raise Exception("Failed to load chassis due to {}".format(repr(e))) - return platform_util + return chassis + # Check for PDDF mode enabled def check_pddf_mode(self): - if os.path.exists(PDDF_FILE_PATH): + if os.path.exists(PDDF_SUPPORT_FILE): return True else: return False