576f0982d2
*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
149 lines
4.5 KiB
Python
149 lines
4.5 KiB
Python
#!/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_CPLD = "CPLD"
|
|
|
|
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
|
|
|
|
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:
|
|
with io.open(filename, 'r') as fileobj:
|
|
result = fileobj.read(len)
|
|
return result
|
|
except IOError as e:
|
|
raise RuntimeError("Failed to read file {} due to {}".format(filename, repr(e)))
|
|
|
|
|
|
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 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
|
|
|
|
|
|
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):
|
|
"""
|
|
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(self.BIOS_VERSION_PARSE_PATTERN, bios_ver_str)
|
|
result = m.group(1)
|
|
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
|
|
|
|
|
|
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
|
|
"""
|
|
return "CPLD - includes all CPLDs in the switch"
|
|
|
|
|
|
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 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')
|
|
else:
|
|
raise RuntimeError("Failed to get CPLD version files by matching {}".format(CPLD_VERSION_FILE_PATTERN))
|
|
|
|
return cpld_version
|
|
|