From 501df9305adb136ca0f6ebd085e9804590eddf54 Mon Sep 17 00:00:00 2001 From: Stephen Sun Date: Mon, 30 Sep 2019 11:35:27 +0300 Subject: [PATCH 1/8] [sonic_platform]Support component API (get_firmware_version). Currently get_firmware_version implementated by using chassis.get_firmware_version and chassis._component_name_list which are not supported in the latest sonic_platform_common, causing chassis broken. Update this part so that it aligns to the latest sonic_platform_common Support component API --- .../sonic_platform/chassis.py | 121 +---------- .../sonic_platform/component.py | 188 ++++++++++++++++++ .../sonic_platform/platform.py | 2 +- 3 files changed, 194 insertions(+), 117 deletions(-) create mode 100644 platform/mellanox/mlnx-platform-api/sonic_platform/component.py diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index 814c7aca817..af67882d186 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -10,6 +10,7 @@ try: from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform_base.component_base import ComponentBase from sonic_daemon_base.daemon_base import Logger from os import listdir from os.path import isfile, join @@ -37,22 +38,6 @@ REBOOT_CAUSE_FILE_LENGTH = 1 -#version retrieving related definitions -CPLD_VERSION_ROOT = HWMGMT_SYSTEM_ROOT - -CPLD1_VERSION_FILE = 'cpld1_version' -CPLD2_VERSION_FILE = 'cpld2_version' -CPLD_VERSION_MAX_LENGTH = 4 - -FW_QUERY_VERSION_COMMAND = 'mlxfwmanager --query' -BIOS_QUERY_VERSION_COMMAND = 'dmidecode -t 11' - -#components definitions -COMPONENT_BIOS = "BIOS" -COMPONENT_FIRMWARE = "ASIC-FIRMWARE" -COMPONENT_CPLD1 = "CPLD1" -COMPONENT_CPLD2 = "CPLD2" - # Global logger class instance SYSLOG_IDENTIFIER = "mlnx-chassis-api" logger = Logger(SYSLOG_IDENTIFIER) @@ -140,10 +125,10 @@ def initialize_eeprom(self): def initialize_components_list(self): # Initialize component list - self._component_name_list.append(COMPONENT_BIOS) - self._component_name_list.append(COMPONENT_FIRMWARE) - self._component_name_list.append(COMPONENT_CPLD1) - self._component_name_list.append(COMPONENT_CPLD2) + from sonic_platform.component import ComponentBIOS, ComponentCPLD, ComponentASIC_FW + self._component_list.append(ComponentBIOS()) + self._component_list.append(ComponentCPLD()) + self._component_list.append(ComponentASIC_FW()) ############################################## # SFP methods @@ -348,102 +333,6 @@ def get_reboot_cause(self): return self.REBOOT_CAUSE_NON_HARDWARE, '' - def _get_cpld_version(self, version_file): - cpld_version = self._read_generic_file(join(CPLD_VERSION_ROOT, version_file), CPLD_VERSION_MAX_LENGTH) - return cpld_version.rstrip('\n') - - def _get_command_result(self, cmdline): - try: - proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT) - stdout = proc.communicate()[0] - proc.wait() - result = stdout.rstrip('\n') - - except OSError, e: - result = '' - - return result - - def _get_firmware_version(self): - """ - firmware version is retrieved via command 'mlxfwmanager --query' - which should return result in the following convention - admin@mtbc-sonic-01-2410:~$ sudo mlxfwmanager --query - Querying Mellanox devices firmware ... - - Device #1: - ---------- - - Device Type: Spectrum - Part Number: MSN2410-CxxxO_Ax_Bx - Description: Spectrum based 25GbE/100GbE 1U Open Ethernet switch with ONIE; 48 SFP28 ports; 8 QSFP28 ports; x86 dual core; RoHS6 - PSID: MT_2860111033 - PCI Device Name: /dev/mst/mt52100_pci_cr0 - Base MAC: 98039bf3f500 - Versions: Current Available - FW ***13.2000.1140***N/A - - Status: No matching image found - - By using regular expression '(Versions:.*\n[\s]+FW[\s]+)([\S]+)', - we can extrace the version which is marked with *** in the above context - """ - fw_ver_str = self._get_command_result(FW_QUERY_VERSION_COMMAND) - try: - m = re.search('(Versions:.*\n[\s]+FW[\s]+)([\S]+)', fw_ver_str) - result = m.group(2) - except : - result = '' - - return result - - def _get_bios_version(self): - """ - BIOS version is retrieved via command 'dmidecode -t 11' - which should return result in the following convention - # dmidecode 3.0 - Getting SMBIOS data from sysfs. - SMBIOS 2.7 present. - - Handle 0x0022, DMI type 11, 5 bytes - OEM Strings - String 1:*0ABZS017_02.02.002* - String 2: To Be Filled By O.E.M. - - By using regular expression 'OEM[\s]*Strings\n[\s]*String[\s]*1:[\s]*([0-9a-zA-Z_\.]*)' - we can extrace the version string which is marked with * in the above context - """ - bios_ver_str = self._get_command_result(BIOS_QUERY_VERSION_COMMAND) - try: - m = re.search('OEM[\s]*Strings\n[\s]*String[\s]*1:[\s]*([0-9a-zA-Z_\.]*)', bios_ver_str) - result = m.group(1) - except: - result = '' - - return result - - def get_firmware_version(self, component_name): - """ - Retrieves platform-specific hardware/firmware versions for chassis - componenets such as BIOS, CPLD, FPGA, etc. - Args: - component_name: A string, the component name. - - Returns: - A string containing platform-specific component versions - """ - if component_name in self._component_name_list : - if component_name == COMPONENT_BIOS: - return self._get_bios_version() - elif component_name == COMPONENT_CPLD1: - return self._get_cpld_version(CPLD1_VERSION_FILE) - elif component_name == COMPONENT_CPLD2: - return self._get_cpld_version(CPLD2_VERSION_FILE) - elif component_name == COMPONENT_FIRMWARE: - return self._get_firmware_version() - - return None - def _show_capabilities(self): """ This function is for debug purpose diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py new file mode 100644 index 00000000000..765074edb53 --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py @@ -0,0 +1,188 @@ +#!/usr/bin/env python + +############################################################################# +# Mellanox +# +# implementation of new platform api +############################################################################# + +try: + from sonic_platform_base.component_base import ComponentBase + from glob import glob + import subprocess + import io + import re +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +#components definitions +COMPONENT_BIOS = "BIOS" +COMPONENT_FIRMWARE = "ASIC-FIRMWARE" +COMPONENT_CPLD = "CPLD" + +FW_QUERY_VERSION_COMMAND = 'mlxfwmanager --query' +BIOS_QUERY_VERSION_COMMAND = 'dmidecode -t 11' +CPLD_VERSION_FILE_PATTERN = '/var/run/hw-management/system/cpld?_version' +CPLD_VERSION_MAX_LENGTH = 4 + +class Component(ComponentBase): + def get_name(self): + """ + Retrieves the name of the component + + Returns: + A string containing the name of the component + """ + return self.name + + def _read_generic_file(self, filename, len): + """ + Read a generic file, returns the contents of the file + """ + result = '' + try: + fileobj = io.open(filename) + result = fileobj.read(len) + fileobj.close() + return result + except Exception as e: + logger.log_info("Fail to read file {} due to {}".format(filename, repr(e))) + return '0' + + def _get_command_result(self, cmdline): + try: + proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT) + stdout = proc.communicate()[0] + proc.wait() + result = stdout.rstrip('\n') + + except OSError, e: + result = '' + + return result + +class ComponentBIOS(Component): + def __init__(self): + self.name = COMPONENT_BIOS + + def get_description(self): + """ + Retrieves the description of the component + + Returns: + A string containing the description of the component + """ + raise NotImplementedError + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + + BIOS version is retrieved via command 'dmidecode -t 11' + which should return result in the following convention + # dmidecode 3.0 + Getting SMBIOS data from sysfs. + SMBIOS 2.7 present. + + Handle 0x0022, DMI type 11, 5 bytes + OEM Strings + String 1:*0ABZS017_02.02.002* + String 2: To Be Filled By O.E.M. + + By using regular expression 'OEM[\s]*Strings\n[\s]*String[\s]*1:[\s]*([0-9a-zA-Z_\.]*)' + we can extrace the version string which is marked with * in the above context + """ + bios_ver_str = self._get_command_result(BIOS_QUERY_VERSION_COMMAND) + try: + m = re.search('OEM[\s]*Strings\n[\s]*String[\s]*1:[\s]*([0-9a-zA-Z_\.]*)', bios_ver_str) + result = m.group(1) + except: + result = '' + + return result + +class ComponentCPLD(Component): + def __init__(self): + self.name = COMPONENT_CPLD + + def get_description(self): + """ + Retrieves the description of the component + + Returns: + A string containing the description of the component + """ + raise NotImplementedError + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + """ + cpld_version_file_list = glob(CPLD_VERSION_FILE_PATTERN) + cpld_version = '' + if cpld_version_file_list is not None and not cpld_version_file_list == []: + cpld_version_file_list.sort() + for version_file in cpld_version_file_list: + version = self._read_generic_file(version_file, CPLD_VERSION_MAX_LENGTH) + if not cpld_version == '': + cpld_version += '.' + cpld_version += version.rstrip('\n') + + return cpld_version + +class ComponentASIC_FW(Component): + def __init__(self): + self.name = COMPONENT_FIRMWARE + + def get_description(self): + """ + Retrieves the description of the component + + Returns: + A string containing the description of the component + """ + raise NotImplementedError + + def get_firmware_version(self): + """ + Retrieves the firmware version of the component + + Returns: + A string containing the firmware version of the component + + firmware version is retrieved via command 'mlxfwmanager --query' + which should return result in the following convention + admin@mtbc-sonic-01-2410:~$ sudo mlxfwmanager --query + Querying Mellanox devices firmware ... + + Device #1: + ---------- + + Device Type: Spectrum + Part Number: MSN2410-CxxxO_Ax_Bx + Description: Spectrum based 25GbE/100GbE 1U Open Ethernet switch with ONIE; 48 SFP28 ports; 8 QSFP28 ports; x86 dual core; RoHS6 + PSID: MT_2860111033 + PCI Device Name: /dev/mst/mt52100_pci_cr0 + Base MAC: 98039bf3f500 + Versions: Current Available + FW ***13.2000.1140***N/A + + Status: No matching image found + + By using regular expression '(Versions:.*\n[\s]+FW[\s]+)([\S]+)', + we can extrace the version which is marked with *** in the above context + """ + fw_ver_str = self._get_command_result(FW_QUERY_VERSION_COMMAND) + try: + m = re.search('(Versions:.*\n[\s]+FW[\s]+)([\S]+)', fw_ver_str) + result = m.group(2) + except : + result = '' + + return result diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py b/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py index fc555bc479a..661a094ea29 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py @@ -18,12 +18,12 @@ def __init__(self): PlatformBase.__init__(self) if self._is_host(): self._chassis = Chassis() + self._chassis.initialize_components_list() else: self._chassis = Chassis() self._chassis.initialize_psu() self._chassis.initialize_fan() self._chassis.initialize_eeprom() - self._chassis.initialize_components_list() def _is_host(self): """ From 3dcb48811ca453da59914d74033e59e632612b6c Mon Sep 17 00:00:00 2001 From: Stephen Sun Date: Mon, 30 Sep 2019 12:57:05 +0300 Subject: [PATCH 2/8] [sonic_platform]follow the PEP8 standard --- .../sonic_platform/chassis.py | 23 +++++++++++++++++++ .../sonic_platform/component.py | 11 +++++++++ 2 files changed, 34 insertions(+) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index af67882d186..d923f1a65a3 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -63,10 +63,12 @@ def __init__(self): self.reboot_cause_initialized = False logger.log_info("Chassis loaded successfully") + def __del__(self): if self.sfp_event_initialized: self.sfp_event.deinitialize() + def initialize_psu(self): from sonic_platform.psu import Psu # Initialize PSU list @@ -75,6 +77,7 @@ def initialize_psu(self): psu = Psu(index, self.sku_name) self._psu_list.append(psu) + def initialize_fan(self): from sonic_platform.fan import Fan from sonic_platform.fan import FAN_PATH @@ -92,6 +95,7 @@ def initialize_fan(self): fan = Fan(index, index) self._fan_list.append(fan) + def initialize_sfp(self): from sonic_platform.sfp import SFP @@ -113,16 +117,19 @@ def initialize_sfp(self): self.sfp_module_initialized = True + def initialize_thermals(self): from sonic_platform.thermal import initialize_thermals # Initialize thermals initialize_thermals(self.sku_name, self._thermal_list, self._psu_list) + def initialize_eeprom(self): from eeprom import Eeprom # Initialize EEPROM self._eeprom = Eeprom() + def initialize_components_list(self): # Initialize component list from sonic_platform.component import ComponentBIOS, ComponentCPLD, ComponentASIC_FW @@ -130,6 +137,7 @@ def initialize_components_list(self): self._component_list.append(ComponentCPLD()) self._component_list.append(ComponentASIC_FW()) + ############################################## # SFP methods ############################################## @@ -144,6 +152,7 @@ def get_num_sfps(self): self.initialize_sfp() return len(self._sfp_list) + def get_all_sfps(self): """ Retrieves all sfps available on this chassis @@ -156,6 +165,7 @@ def get_all_sfps(self): self.initialize_sfp() return self._sfp_list + def get_sfp(self, index): """ Retrieves sfp represented by (0-based) index @@ -182,6 +192,7 @@ def get_sfp(self, index): return sfp + def _extract_num_of_fans_and_fan_drawers(self): num_of_fan = 0 num_of_drawer = 0 @@ -198,15 +209,18 @@ def _extract_num_of_fans_and_fan_drawers(self): return num_of_fan, num_of_drawer + def _get_sku_name(self): p = subprocess.Popen(GET_HWSKU_CMD, shell=True, stdout=subprocess.PIPE) out, err = p.communicate() return out.rstrip('\n') + def _get_port_position_tuple_by_sku_name(self): position_tuple = port_position_tuple_list[hwsku_dict_port[self.sku_name]] return position_tuple + def get_watchdog(self): """ Retrieves hardware watchdog device on this chassis @@ -231,6 +245,7 @@ def get_watchdog(self): return self._watchdog + def get_base_mac(self): """ Retrieves the base MAC address for the chassis @@ -241,6 +256,7 @@ def get_base_mac(self): """ return self._eeprom.get_base_mac() + def get_serial_number(self): """ Retrieves the hardware serial number for the chassis @@ -250,6 +266,7 @@ def get_serial_number(self): """ return self._eeprom.get_serial_number() + def get_system_eeprom_info(self): """ Retrieves the full content of system EEPROM information for the chassis @@ -261,6 +278,7 @@ def get_system_eeprom_info(self): """ return self._eeprom.get_system_eeprom_info() + def _read_generic_file(self, filename, len): """ Read a generic file, returns the contents of the file @@ -275,6 +293,7 @@ def _read_generic_file(self, filename, len): logger.log_info("Fail to read file {} due to {}".format(filename, repr(e))) return '0' + def _verify_reboot_cause(self, filename): ''' Open and read the reboot cause file in @@ -283,6 +302,7 @@ def _verify_reboot_cause(self, filename): ''' return bool(int(self._read_generic_file(join(REBOOT_CAUSE_ROOT, filename), REBOOT_CAUSE_FILE_LENGTH).rstrip('\n'))) + def initialize_reboot_cause(self): self.reboot_major_cause_dict = { 'reset_main_pwr_fail' : self.REBOOT_CAUSE_POWER_LOSS, @@ -308,6 +328,7 @@ def initialize_reboot_cause(self): } self.reboot_cause_initialized = True + def get_reboot_cause(self): """ Retrieves the cause of the previous reboot @@ -333,6 +354,7 @@ def get_reboot_cause(self): return self.REBOOT_CAUSE_NON_HARDWARE, '' + def _show_capabilities(self): """ This function is for debug purpose @@ -354,6 +376,7 @@ def _show_capabilities(self): except: print "fail to retrieve capabilities for module index {}".format(s.index) + def get_change_event(self, timeout=0): """ Returns a nested dictionary containing all devices which have diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py index 765074edb53..5057a95801a 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py @@ -35,6 +35,7 @@ def get_name(self): """ return self.name + def _read_generic_file(self, filename, len): """ Read a generic file, returns the contents of the file @@ -49,6 +50,7 @@ def _read_generic_file(self, filename, len): logger.log_info("Fail to read file {} due to {}".format(filename, repr(e))) return '0' + def _get_command_result(self, cmdline): try: proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT) @@ -61,10 +63,12 @@ def _get_command_result(self, cmdline): return result + class ComponentBIOS(Component): def __init__(self): self.name = COMPONENT_BIOS + def get_description(self): """ Retrieves the description of the component @@ -74,6 +78,7 @@ def get_description(self): """ raise NotImplementedError + def get_firmware_version(self): """ Retrieves the firmware version of the component @@ -104,10 +109,12 @@ def get_firmware_version(self): return result + class ComponentCPLD(Component): def __init__(self): self.name = COMPONENT_CPLD + def get_description(self): """ Retrieves the description of the component @@ -117,6 +124,7 @@ def get_description(self): """ raise NotImplementedError + def get_firmware_version(self): """ Retrieves the firmware version of the component @@ -136,10 +144,12 @@ def get_firmware_version(self): return cpld_version + class ComponentASIC_FW(Component): def __init__(self): self.name = COMPONENT_FIRMWARE + def get_description(self): """ Retrieves the description of the component @@ -149,6 +159,7 @@ def get_description(self): """ raise NotImplementedError + def get_firmware_version(self): """ Retrieves the firmware version of the component From 92ddc777e9f3c4883e361f65a713e8ff045f2ebb Mon Sep 17 00:00:00 2001 From: Stephen Date: Tue, 1 Oct 2019 12:08:00 +0000 Subject: [PATCH 3/8] [sonic_platform]Address comments 1. rename initialize_components 2. replace cpld?_version with cpld[0-9]_version in order to be more accurate --- platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py | 2 +- platform/mellanox/mlnx-platform-api/sonic_platform/component.py | 2 +- platform/mellanox/mlnx-platform-api/sonic_platform/platform.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index d923f1a65a3..ee95a25383d 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -130,7 +130,7 @@ def initialize_eeprom(self): self._eeprom = Eeprom() - def initialize_components_list(self): + def initialize_components(self): # Initialize component list from sonic_platform.component import ComponentBIOS, ComponentCPLD, ComponentASIC_FW self._component_list.append(ComponentBIOS()) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py index 5057a95801a..06bff036b89 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py @@ -22,7 +22,7 @@ FW_QUERY_VERSION_COMMAND = 'mlxfwmanager --query' BIOS_QUERY_VERSION_COMMAND = 'dmidecode -t 11' -CPLD_VERSION_FILE_PATTERN = '/var/run/hw-management/system/cpld?_version' +CPLD_VERSION_FILE_PATTERN = '/var/run/hw-management/system/cpld[0-9]_version' CPLD_VERSION_MAX_LENGTH = 4 class Component(ComponentBase): diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py b/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py index 661a094ea29..25461986f37 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py @@ -18,7 +18,7 @@ def __init__(self): PlatformBase.__init__(self) if self._is_host(): self._chassis = Chassis() - self._chassis.initialize_components_list() + self._chassis.initialize_components() else: self._chassis = Chassis() self._chassis.initialize_psu() From 013b3a355a0e0d92bfe15b88a1a19e21b650d0c5 Mon Sep 17 00:00:00 2001 From: Stephen Date: Tue, 1 Oct 2019 12:25:35 +0000 Subject: [PATCH 4/8] [sonic_platform]Remove ASIC_FW from components list --- .../sonic_platform/chassis.py | 3 +- .../sonic_platform/component.py | 55 ------------------- 2 files changed, 1 insertion(+), 57 deletions(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index ee95a25383d..0016dc8ff3d 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -132,10 +132,9 @@ def initialize_eeprom(self): def initialize_components(self): # Initialize component list - from sonic_platform.component import ComponentBIOS, ComponentCPLD, ComponentASIC_FW + from sonic_platform.component import ComponentBIOS, ComponentCPLD self._component_list.append(ComponentBIOS()) self._component_list.append(ComponentCPLD()) - self._component_list.append(ComponentASIC_FW()) ############################################## diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py index 06bff036b89..8dd84ef74b3 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py @@ -17,10 +17,8 @@ #components definitions COMPONENT_BIOS = "BIOS" -COMPONENT_FIRMWARE = "ASIC-FIRMWARE" COMPONENT_CPLD = "CPLD" -FW_QUERY_VERSION_COMMAND = 'mlxfwmanager --query' BIOS_QUERY_VERSION_COMMAND = 'dmidecode -t 11' CPLD_VERSION_FILE_PATTERN = '/var/run/hw-management/system/cpld[0-9]_version' CPLD_VERSION_MAX_LENGTH = 4 @@ -144,56 +142,3 @@ def get_firmware_version(self): return cpld_version - -class ComponentASIC_FW(Component): - def __init__(self): - self.name = COMPONENT_FIRMWARE - - - def get_description(self): - """ - Retrieves the description of the component - - Returns: - A string containing the description of the component - """ - raise NotImplementedError - - - def get_firmware_version(self): - """ - Retrieves the firmware version of the component - - Returns: - A string containing the firmware version of the component - - firmware version is retrieved via command 'mlxfwmanager --query' - which should return result in the following convention - admin@mtbc-sonic-01-2410:~$ sudo mlxfwmanager --query - Querying Mellanox devices firmware ... - - Device #1: - ---------- - - Device Type: Spectrum - Part Number: MSN2410-CxxxO_Ax_Bx - Description: Spectrum based 25GbE/100GbE 1U Open Ethernet switch with ONIE; 48 SFP28 ports; 8 QSFP28 ports; x86 dual core; RoHS6 - PSID: MT_2860111033 - PCI Device Name: /dev/mst/mt52100_pci_cr0 - Base MAC: 98039bf3f500 - Versions: Current Available - FW ***13.2000.1140***N/A - - Status: No matching image found - - By using regular expression '(Versions:.*\n[\s]+FW[\s]+)([\S]+)', - we can extrace the version which is marked with *** in the above context - """ - fw_ver_str = self._get_command_result(FW_QUERY_VERSION_COMMAND) - try: - m = re.search('(Versions:.*\n[\s]+FW[\s]+)([\S]+)', fw_ver_str) - result = m.group(2) - except : - result = '' - - return result From 151f895f8a18e757ff553c769ee1c1f2901d6217 Mon Sep 17 00:00:00 2001 From: Stephen Date: Tue, 1 Oct 2019 12:31:59 +0000 Subject: [PATCH 5/8] [sonic_platform]Add description of components --- .../mellanox/mlnx-platform-api/sonic_platform/component.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py index 8dd84ef74b3..154cac02b40 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py @@ -74,7 +74,7 @@ def get_description(self): Returns: A string containing the description of the component """ - raise NotImplementedError + return "BIOS - Basic Input/Output System" def get_firmware_version(self): @@ -120,7 +120,7 @@ def get_description(self): Returns: A string containing the description of the component """ - raise NotImplementedError + return "CPLD - includes all CPLDs in the switch" def get_firmware_version(self): From ea23de225e7a0809ed06fb6e85ff7c3ea3791523 Mon Sep 17 00:00:00 2001 From: Stephen Date: Tue, 1 Oct 2019 15:01:01 +0000 Subject: [PATCH 6/8] [sonic_platform] Raise an exception if CPLD version files not found. --- platform/mellanox/mlnx-platform-api/sonic_platform/component.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py index 154cac02b40..4c6a554ab00 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py @@ -139,6 +139,8 @@ def get_firmware_version(self): if not cpld_version == '': cpld_version += '.' cpld_version += version.rstrip('\n') + else: + raise RuntimeError("Failed to get CPLD version files by matching {}".format(CPLD_VERSION_FILE_PATTERN)) return cpld_version From cf723d2af6deb03eb6aee77eede10ed4bfcb504f Mon Sep 17 00:00:00 2001 From: Stephen Date: Wed, 2 Oct 2019 01:44:56 +0000 Subject: [PATCH 7/8] [sonic_platform]Address comments 1. implement file reading by with statment 2. adjust statement which testing whether list is empty --- .../mellanox/mlnx-platform-api/sonic_platform/component.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py index 4c6a554ab00..b313fe87bc5 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py @@ -40,9 +40,8 @@ def _read_generic_file(self, filename, len): """ result = '' try: - fileobj = io.open(filename) - result = fileobj.read(len) - fileobj.close() + with io.open(filename, 'r') as fileobj: + result = fileobj.read(len) return result except Exception as e: logger.log_info("Fail to read file {} due to {}".format(filename, repr(e))) @@ -132,7 +131,7 @@ def get_firmware_version(self): """ cpld_version_file_list = glob(CPLD_VERSION_FILE_PATTERN) cpld_version = '' - if cpld_version_file_list is not None and not cpld_version_file_list == []: + if cpld_version_file_list is not None and cpld_version_file_list: cpld_version_file_list.sort() for version_file in cpld_version_file_list: version = self._read_generic_file(version_file, CPLD_VERSION_MAX_LENGTH) From 47b3e6e2efc3651fb26d7d445dd4b5ea25b22952 Mon Sep 17 00:00:00 2001 From: Stephen Date: Thu, 3 Oct 2019 04:04:57 +0000 Subject: [PATCH 8/8] [sonic_platform]Raise exception if any error occurs --- .../sonic_platform/component.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py index b313fe87bc5..fd593f7bbe4 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py @@ -43,9 +43,8 @@ def _read_generic_file(self, filename, len): with io.open(filename, 'r') as fileobj: result = fileobj.read(len) return result - except Exception as e: - logger.log_info("Fail to read file {} due to {}".format(filename, repr(e))) - return '0' + except IOError as e: + raise RuntimeError("Failed to read file {} due to {}".format(filename, repr(e))) def _get_command_result(self, cmdline): @@ -55,13 +54,16 @@ def _get_command_result(self, cmdline): proc.wait() result = stdout.rstrip('\n') - except OSError, e: - result = '' + except OSError as e: + raise RuntimeError("Failed to execute command {} due to {}".format(cmdline, repr(e))) return result class ComponentBIOS(Component): + BIOS_VERSION_PARSE_PATTERN = 'OEM[\s]*Strings\n[\s]*String[\s]*1:[\s]*([0-9a-zA-Z_\.]*)' + + def __init__(self): self.name = COMPONENT_BIOS @@ -99,10 +101,11 @@ def get_firmware_version(self): """ bios_ver_str = self._get_command_result(BIOS_QUERY_VERSION_COMMAND) try: - m = re.search('OEM[\s]*Strings\n[\s]*String[\s]*1:[\s]*([0-9a-zA-Z_\.]*)', bios_ver_str) + m = re.search(self.BIOS_VERSION_PARSE_PATTERN, bios_ver_str) result = m.group(1) - except: - result = '' + except AttributeError as e: + raise RuntimeError("Failed to parse BIOS version by {} from {} due to {}".format( + self.BIOS_VERSION_PARSE_PATTERN, bios_ver_str, repr(e))) return result