[mellanox]: Align platform API: change CPLD version representation (#4221)

This commit is contained in:
Nazarii Hnydyn 2020-03-23 18:04:11 +02:00 committed by GitHub
parent 440f86ee07
commit 4d22cd405f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 93 additions and 57 deletions

View File

@ -154,7 +154,7 @@ class Chassis(ChassisBase):
# Initialize component list # Initialize component list
from sonic_platform.component import ComponentBIOS, ComponentCPLD from sonic_platform.component import ComponentBIOS, ComponentCPLD
self._component_list.append(ComponentBIOS()) self._component_list.append(ComponentBIOS())
self._component_list.append(ComponentCPLD()) self._component_list.extend(ComponentCPLD.get_component_list())
def get_name(self): def get_name(self):

View File

@ -18,13 +18,13 @@ try:
except ImportError as e: except ImportError as e:
raise ImportError(str(e) + "- required module not found") raise ImportError(str(e) + "- required module not found")
#components definitions ZERO = '0'
COMPONENT_BIOS = "BIOS" NEWLINE = '\n'
COMPONENT_CPLD = "CPLD"
class Component(ComponentBase): class Component(ComponentBase):
def __init__(self): def __init__(self):
self.name = None self.name = None
self.description = None
self.image_ext_name = None self.image_ext_name = None
@ -38,20 +38,35 @@ class Component(ComponentBase):
return self.name return self.name
def _read_generic_file(self, filename, len): def get_description(self):
"""
Retrieves the description of the component
Returns:
A string containing the description of the component
"""
return self.description
@staticmethod
def _read_generic_file(filename, len, ignore_errors=False):
""" """
Read a generic file, returns the contents of the file Read a generic file, returns the contents of the file
""" """
result = '' result = None
try: try:
with io.open(filename, 'r') as fileobj: with io.open(filename, 'r') as fileobj:
result = fileobj.read(len) result = fileobj.read(len)
return result
except IOError as e: except IOError as e:
raise RuntimeError("Failed to read file {} due to {}".format(filename, repr(e))) if not ignore_errors:
raise RuntimeError("Failed to read file {} due to {}".format(filename, repr(e)))
return result
def _get_command_result(self, cmdline): @staticmethod
def _get_command_result(cmdline):
try: try:
proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT) proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT)
stdout = proc.communicate()[0] stdout = proc.communicate()[0]
@ -83,38 +98,33 @@ class Component(ComponentBase):
class ComponentBIOS(Component): class ComponentBIOS(Component):
COMPONENT_NAME = 'BIOS'
COMPONENT_DESCRIPTION = 'BIOS - Basic Input/Output System'
COMPONENT_FIRMWARE_EXTENSION = '.rom'
# To update BIOS requires the ONIE with version 5.2.0016 or upper # To update BIOS requires the ONIE with version 5.2.0016 or upper
ONIE_VERSION_PARSE_PATTERN = '[0-9]{4}\.[0-9]{2}-([0-9]+)\.([0-9]+)\.([0-9]+)' ONIE_VERSION_PARSE_PATTERN = '[0-9]{4}\.[0-9]{2}-([0-9]+)\.([0-9]+)\.([0-9]+)'
ONIE_VERSION_MAJOR_OFFSET = 1 ONIE_VERSION_MAJOR_OFFSET = 1
ONIE_VERSION_MINOR_OFFSET = 2 ONIE_VERSION_MINOR_OFFSET = 2
ONIE_VERSION_RELEASE_OFFSET = 3 ONIE_VERSION_RELEASE_OFFSET = 3
ONIE_REQUIRED_MAJOR = "5" ONIE_REQUIRED_MAJOR = '5'
ONIE_REQUIRED_MINOR = "2" ONIE_REQUIRED_MINOR = '2'
ONIE_REQUIRED_RELEASE = "0016" ONIE_REQUIRED_RELEASE = '0016'
BIOS_VERSION_PARSE_PATTERN = 'OEM[\s]*Strings\n[\s]*String[\s]*1:[\s]*([0-9a-zA-Z_\.]*)' BIOS_VERSION_PARSE_PATTERN = 'OEM[\s]*Strings\n[\s]*String[\s]*1:[\s]*([0-9a-zA-Z_\.]*)'
BIOS_PENDING_UPDATE_PATTERN = '([0-9A-Za-z_]*.rom)[\s]*\|[\s]*bios_update' BIOS_PENDING_UPDATE_PATTERN = '([0-9A-Za-z_]*.rom)[\s]*\|[\s]*bios_update'
ONIE_FW_UPDATE_CMD_ADD = "/usr/bin/onie-fw-update.sh add {}" ONIE_FW_UPDATE_CMD_ADD = '/usr/bin/onie-fw-update.sh add {}'
ONIE_FW_UPDATE_CMD_REMOVE = "/usr/bin/onie-fw-update.sh remove {}" ONIE_FW_UPDATE_CMD_REMOVE = '/usr/bin/onie-fw-update.sh remove {}'
ONIE_FW_UPDATE_CMD_UPDATE = "/usr/bin/onie-fw-update.sh update" ONIE_FW_UPDATE_CMD_UPDATE = '/usr/bin/onie-fw-update.sh update'
ONIE_FW_UPDATE_CMD_SHOW = "/usr/bin/onie-fw-update.sh show-pending" ONIE_FW_UPDATE_CMD_SHOW = '/usr/bin/onie-fw-update.sh show-pending'
BIOS_QUERY_VERSION_COMMAND = 'dmidecode -t 11' BIOS_QUERY_VERSION_COMMAND = 'dmidecode -t 11'
def __init__(self): def __init__(self):
self.name = COMPONENT_BIOS self.name = self.COMPONENT_NAME
self.image_ext_name = ".rom" self.description = self.COMPONENT_DESCRIPTION
self.image_ext_name = self.COMPONENT_FIRMWARE_EXTENSION
def get_description(self):
"""
Retrieves the description of the component
Returns:
A string containing the description of the component
"""
return "BIOS - Basic Input/Output System"
def get_firmware_version(self): def get_firmware_version(self):
@ -210,33 +220,39 @@ class ComponentBIOS(Component):
print("ERROR: Installing BIOS failed due to {}".format(repr(e))) print("ERROR: Installing BIOS failed due to {}".format(repr(e)))
return False return False
print("INFO: Reboot is required to finish BIOS installation.") print("INFO: Reboot is required to finish BIOS installation")
return True return True
class ComponentCPLD(Component): class ComponentCPLD(Component):
CPLD_VERSION_FILE_PATTERN = '/var/run/hw-management/system/cpld[0-9]_version' COMPONENT_NAME = 'CPLD{}'
CPLD_VERSION_MAX_LENGTH = 4 COMPONENT_DESCRIPTION = 'CPLD - Complex Programmable Logic Device'
COMPONENT_FIRMWARE_EXTENSION = '.vme'
CPLD_UPDATE_COMMAND = "cpldupdate --dev {} {}" CPLD_NUMBER_FILE = '/var/run/hw-management/config/cpld_num'
CPLD_INSTALL_SUCCESS_FLAG = "PASS!" CPLD_PART_NUMBER_FILE = '/var/run/hw-management/system/cpld{}_pn'
CPLD_VERSION_FILE = '/var/run/hw-management/system/cpld{}_version'
CPLD_VERSION_MINOR_FILE = '/var/run/hw-management/system/cpld{}_version_minor'
MST_DEVICE_PATTERN = "/dev/mst/mt[0-9]*_pciconf0" CPLD_NUMBER_MAX_LENGTH = 1
CPLD_PART_NUMBER_MAX_LENGTH = 6
CPLD_VERSION_MAX_LENGTH = 2
CPLD_VERSION_MINOR_MAX_LENGTH = 2
def __init__(self): CPLD_PART_NUMBER_DEFAULT = ZERO
self.name = COMPONENT_CPLD CPLD_VERSION_MINOR_DEFAULT = ZERO
self.image_ext_name = ".vme"
CPLD_UPDATE_COMMAND = 'cpldupdate --dev {} {}'
CPLD_INSTALL_SUCCESS_FLAG = 'PASS!'
def get_description(self): MST_DEVICE_PATTERN = '/dev/mst/mt[0-9]*_pci_cr0'
"""
Retrieves the description of the component
Returns: def __init__(self, idx):
A string containing the description of the component self.idx = idx
""" self.name = self.COMPONENT_NAME.format(self.idx)
return "CPLD - includes all CPLDs in the switch" self.description = self.COMPONENT_DESCRIPTION
self.image_ext_name = self.COMPONENT_FIRMWARE_EXTENSION
def get_firmware_version(self): def get_firmware_version(self):
@ -246,19 +262,26 @@ class ComponentCPLD(Component):
Returns: Returns:
A string containing the firmware version of the component A string containing the firmware version of the component
""" """
cpld_version_file_list = glob(self.CPLD_VERSION_FILE_PATTERN)
cpld_version = ''
if cpld_version_file_list:
cpld_version_file_list.sort()
for version_file in cpld_version_file_list:
version = self._read_generic_file(version_file, self.CPLD_VERSION_MAX_LENGTH)
if cpld_version:
cpld_version += '.'
cpld_version += version.rstrip('\n')
else:
raise RuntimeError("Failed to get CPLD version files by matching {}".format(self.CPLD_VERSION_FILE_PATTERN))
return cpld_version part_number_file = self.CPLD_PART_NUMBER_FILE.format(self.idx)
version_file = self.CPLD_VERSION_FILE.format(self.idx)
version_minor_file = self.CPLD_VERSION_MINOR_FILE.format(self.idx)
part_number = self._read_generic_file(part_number_file, self.CPLD_PART_NUMBER_MAX_LENGTH, True)
version = self._read_generic_file(version_file, self.CPLD_VERSION_MAX_LENGTH)
version_minor = self._read_generic_file(version_minor_file, self.CPLD_VERSION_MINOR_MAX_LENGTH, True)
if part_number is None:
part_number = self.CPLD_PART_NUMBER_DEFAULT
if version_minor is None:
version_minor = self.CPLD_VERSION_MINOR_DEFAULT
part_number = part_number.rstrip(NEWLINE).zfill(self.CPLD_PART_NUMBER_MAX_LENGTH)
version = version.rstrip(NEWLINE).zfill(self.CPLD_VERSION_MAX_LENGTH)
version_minor = version_minor.rstrip(NEWLINE).zfill(self.CPLD_VERSION_MINOR_MAX_LENGTH)
return "CPLD{}_REV{}{}".format(part_number, version, version_minor)
def _get_mst_device(self): def _get_mst_device(self):
@ -331,8 +354,21 @@ class ComponentCPLD(Component):
raise RuntimeError("Failed to execute command {} due to {}".format(cmdline, repr(e))) raise RuntimeError("Failed to execute command {} due to {}".format(cmdline, repr(e)))
if success_flag: if success_flag:
print("INFO: Success. Refresh or power cycle is required to finish CPLD installation.") print("INFO: Refresh or power cycle is required to finish CPLD installation")
else: else:
print("ERROR: Failed to install CPLD") print("ERROR: Failed to install CPLD")
return success_flag return success_flag
@classmethod
def get_component_list(cls):
component_list = [ ]
cpld_number = cls._read_generic_file(cls.CPLD_NUMBER_FILE, cls.CPLD_NUMBER_MAX_LENGTH)
cpld_number = cpld_number.rstrip(NEWLINE)
for cpld_idx in xrange(1, int(cpld_number) + 1):
component_list.append(cls(cpld_idx))
return component_list