sonic-buildimage/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/component.py

319 lines
11 KiB
Python
Raw Normal View History

[BFN] Implementation API for platform component (#10180) * [BFN] Implementation API for platform component SONiC has a concept of "platform components" this may include - CPLD, FPGA, BIOS, BMC, etc. These changes are needed to read the version of the BIOS and BMC component. What I did Create components.py module Add funcion for reading componet version to thrift interface How I did it The previous implementaion didn't have platform components API, so fwutil return an empty list. After implementation of the platform component API, we have actual list of platform components and firmware versions How to verify it Run manually 'fwutil show status' or run unit tests Previous command output Chassis Module Component Version Description ------------------------ -------- ----------- --------- ------------- New command output Chassis Module Component Version Description ------------------------ -------- ----------- --------- ------------- Chassis1 N/A BIOS 1.2.3 Chassis BIOS BMC 5.1 Chassis BMC Signed-off-by: Taras Keryk <tarasx.keryk@intel.com> * [BFN] Implementation API for platform component SONiC has a concept of "platform components" this may include - CPLD, FPGA, BIOS, BMC, etc. These changes are needed to read the version of the BIOS and BMC component. What I did Create components.py module Add funcion for reading componet version to thrift interface How I did it The previous implementaion didn't have platform components API, so fwutil return an empty list. After implementation of the platform component API, we have actual list of platform components and firmware versions How to verify it Run manually 'fwutil show status' or run unit tests Previous command output Chassis Module Component Version Description ------------------------ -------- ----------- --------- ------------- New command output Chassis Module Component Version Description ------------------------ -------- ----------- --------- ------------- Chassis1 N/A BIOS 1.2.3 Chassis BIOS BMC 5.1 Chassis BMC Signed-off-by: Taras Keryk <tarasx.keryk@intel.com> * [BFN] Implementation API for platform component get chassis name from json * [BFN] Implementation API for platform component Updated platform and platrom_components json * [BFN] Implementation API for platform component Fixed spaces in component.py * [BFN] Implementation API for platform component Fixed exception in component.py * Update chassis.py * [BFN] Implementation API for platform component Fixed spaces in component.py, chassis.py * [BFN] Implementation API for platform component: Fixed spaces in component.py, chassis.py * Fixed exception in get_bios_version
2022-03-10 04:55:06 -06:00
try:
[BFN] Fix exception when fwutil run without sudo (#10335) * [BFN] Fix for run fwutil without sudo SONiC has a concept of "platform components" this may include - CPLD, FPGA, BIOS, BMC, etc. These changes are needed to read the version of the BIOS and BMC component. What I did The previous implementaion of component.py expect fwutil run with sudo. When fwutil run without sudo, there are an exception: ``` Traceback (most recent call last): File "/usr/local/bin/fwutil", line 5, in <module> from fwutil.main import cli File "/usr/local/lib/python3.9/dist-packages/fwutil/__init__.py", line 3, in <module> from . import main File "/usr/local/lib/python3.9/dist-packages/fwutil/main.py", line 40, in <module> pdp = PlatformDataProvider() File "/usr/local/lib/python3.9/dist-packages/fwutil/lib.py", line 159, in __init__ self.__platform = Platform() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/platform.py", line 21, in __init__ self._chassis = Chassis() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/chassis.py", line 48, in __init__ self.__initialize_components() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/chassis.py", line 136, in __initialize_components component = Components(index) File "/usr/local/lib/python3.9/dist-packages/sonic_platform/component.py", line 184, in __init__ self.version = get_bios_version() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/component.py", line 19, in get_bios_version return subprocess.check_output(['dmidecode', '-s', 'bios-version']).strip().decode() File "/usr/lib/python3.9/subprocess.py", line 424, in check_output return run(*popenargs, stdout=PIPE, timeout=timeout, check=True, File "/usr/lib/python3.9/subprocess.py", line 505, in run with Popen(*popenargs, **kwargs) as process: File "/usr/lib/python3.9/subprocess.py", line 951, in __init__ self._execute_child(args, executable, preexec_fn, close_fds, File "/usr/lib/python3.9/subprocess.py", line 1823, in _execute_child raise child_exception_type(errno_num, err_msg, err_filename) FileNotFoundError: [Errno 2] No such file or directory: 'dmidecode' ``` How I did it Modification of dmidecode command How to verify it Run manually 'fwutil' (without sudo) Previous command output had exception New command output: Root privileges are required Signed-off-by: Taras Keryk <tarasx.keryk@intel.com> * Why I did it The previous implementaion of component.py expect fwutil run with sudo. When fwutil run without sudo, there are an exception: Traceback (most recent call last): File "/usr/local/bin/fwutil", line 5, in <module> from fwutil.main import cli File "/usr/local/lib/python3.9/dist-packages/fwutil/__init__.py", line 3, in <module> from . import main File "/usr/local/lib/python3.9/dist-packages/fwutil/main.py", line 40, in <module> pdp = PlatformDataProvider() File "/usr/local/lib/python3.9/dist-packages/fwutil/lib.py", line 159, in __init__ self.__platform = Platform() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/platform.py", line 21, in __init__ self._chassis = Chassis() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/chassis.py", line 48, in __init__ self.__initialize_components() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/chassis.py", line 136, in __initialize_components component = Components(index) File "/usr/local/lib/python3.9/dist-packages/sonic_platform/component.py", line 184, in __init__ self.version = get_bios_version() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/component.py", line 19, in get_bios_version return subprocess.check_output(['dmidecode', '-s', 'bios-version']).strip().decode() File "/usr/lib/python3.9/subprocess.py", line 424, in check_output return run(*popenargs, stdout=PIPE, timeout=timeout, check=True, File "/usr/lib/python3.9/subprocess.py", line 505, in run with Popen(*popenargs, **kwargs) as process: File "/usr/lib/python3.9/subprocess.py", line 951, in __init__ self._execute_child(args, executable, preexec_fn, close_fds, File "/usr/lib/python3.9/subprocess.py", line 1823, in _execute_child raise child_exception_type(errno_num, err_msg, err_filename) FileNotFoundError: [Errno 2] No such file or directory: 'dmidecode' How I did it Modification of dmidecode command How to verify it Run manually 'fwutil' (without sudo) Previous command output had exception New command output: Root privileges are required Signed-off-by: Taras Keryk tarasx.keryk@intel.com Signed-off-by: Taras Keryk <tarasx.keryk@intel.com> * rewrite a call of dmidecode, when run without sudo Signed-off-by: Taras Keryk <tarasx.keryk@intel.com> * Why I did it The previous implementaion of component.py expect fwutil run with sudo. When fwutil run without sudo, there are an exception: Traceback (most recent call last): File "/usr/local/bin/fwutil", line 5, in <module> from fwutil.main import cli File "/usr/local/lib/python3.9/dist-packages/fwutil/__init__.py", line 3, in <module> from . import main File "/usr/local/lib/python3.9/dist-packages/fwutil/main.py", line 40, in <module> pdp = PlatformDataProvider() File "/usr/local/lib/python3.9/dist-packages/fwutil/lib.py", line 159, in __init__ self.__platform = Platform() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/platform.py", line 21, in __init__ self._chassis = Chassis() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/chassis.py", line 48, in __init__ self.__initialize_components() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/chassis.py", line 136, in __initialize_components component = Components(index) File "/usr/local/lib/python3.9/dist-packages/sonic_platform/component.py", line 184, in __init__ self.version = get_bios_version() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/component.py", line 19, in get_bios_version return subprocess.check_output(['dmidecode', '-s', 'bios-version']).strip().decode() File "/usr/lib/python3.9/subprocess.py", line 424, in check_output return run(*popenargs, stdout=PIPE, timeout=timeout, check=True, File "/usr/lib/python3.9/subprocess.py", line 505, in run with Popen(*popenargs, **kwargs) as process: File "/usr/lib/python3.9/subprocess.py", line 951, in __init__ self._execute_child(args, executable, preexec_fn, close_fds, File "/usr/lib/python3.9/subprocess.py", line 1823, in _execute_child raise child_exception_type(errno_num, err_msg, err_filename) FileNotFoundError: [Errno 2] No such file or directory: 'dmidecode' The previous implementaion of eeprom.py expect fwutil run with sudo. When fwutil run without sudo, there are an exception: Traceback (most recent call last): File "/usr/lib/python3.9/logging/config.py", line 564, in configure handler = self.configure_handler(handlers[name]) File "/usr/lib/python3.9/logging/config.py", line 745, in configure_handler result = factory(**kwargs) File "/usr/lib/python3.9/logging/handlers.py", line 153, in init BaseRotatingHandler.init(self, filename, mode, encoding=encoding, File "/usr/lib/python3.9/logging/handlers.py", line 58, in init logging.FileHandler.init(self, filename, mode=mode, File "/usr/lib/python3.9/logging/init.py", line 1142, in init StreamHandler.init(self, self._open()) File "/usr/lib/python3.9/logging/init.py", line 1171, in _open return open(self.baseFilename, self.mode, encoding=self.encoding, PermissionError: [Errno 13] Permission denied: '/var/log/platform.log' The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/usr/local/bin/fwutil", line 5, in from fwutil.main import cli File "/usr/local/lib/python3.9/dist-packages/fwutil/init.py", line 3, in from . import main File "/usr/local/lib/python3.9/dist-packages/fwutil/main.py", line 41, in pdp = PlatformDataProvider() File "/usr/local/lib/python3.9/dist-packages/fwutil/lib.py", line 162, in init self.chassis_component_map = self.__get_chassis_component_map() File "/usr/local/lib/python3.9/dist-packages/fwutil/lib.py", line 168, in __get_chassis_component_map chassis_name = self.__chassis.get_name() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/chassis.py", line 146, in get_name return self._eeprom.modelstr() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/chassis.py", line 54, in _eeprom self.__eeprom = Eeprom() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/eeprom.py", line 50, in init logging.config.dictConfig(config_dict) File "/usr/lib/python3.9/logging/config.py", line 809, in dictConfig dictConfigClass(config).configure() File "/usr/lib/python3.9/logging/config.py", line 571, in configure raise ValueError('Unable to configure handler ' ValueError: Unable to configure handler 'file' How I did it Modification call of dmidecode command. Added modification of log files access attributes before file open operations. How to verify it Run manually 'fwutil' (without sudo) New command output have no exception. Signed-off-by: Taras Keryk <tarasx.keryk@intel.com> * Added file_check for checking access to log files for eeprom.py Signed-off-by: Taras Keryk <tarasx.keryk@intel.com> * Removed unused import * Added logfile_create to eeprom.py and chassis.py Signed-off-by: Taras Keryk <tarasx.keryk@intel.com> * Created platform_utils.py Signed-off-by: Taras Keryk <tarasx.keryk@intel.com> * Added interpreter string to platform_utils.py Signed-off-by: Taras Keryk <tarasx.keryk@intel.com>
2022-04-05 13:33:51 -05:00
import os
[BFN] Implementation API for platform component (#10180) * [BFN] Implementation API for platform component SONiC has a concept of "platform components" this may include - CPLD, FPGA, BIOS, BMC, etc. These changes are needed to read the version of the BIOS and BMC component. What I did Create components.py module Add funcion for reading componet version to thrift interface How I did it The previous implementaion didn't have platform components API, so fwutil return an empty list. After implementation of the platform component API, we have actual list of platform components and firmware versions How to verify it Run manually 'fwutil show status' or run unit tests Previous command output Chassis Module Component Version Description ------------------------ -------- ----------- --------- ------------- New command output Chassis Module Component Version Description ------------------------ -------- ----------- --------- ------------- Chassis1 N/A BIOS 1.2.3 Chassis BIOS BMC 5.1 Chassis BMC Signed-off-by: Taras Keryk <tarasx.keryk@intel.com> * [BFN] Implementation API for platform component SONiC has a concept of "platform components" this may include - CPLD, FPGA, BIOS, BMC, etc. These changes are needed to read the version of the BIOS and BMC component. What I did Create components.py module Add funcion for reading componet version to thrift interface How I did it The previous implementaion didn't have platform components API, so fwutil return an empty list. After implementation of the platform component API, we have actual list of platform components and firmware versions How to verify it Run manually 'fwutil show status' or run unit tests Previous command output Chassis Module Component Version Description ------------------------ -------- ----------- --------- ------------- New command output Chassis Module Component Version Description ------------------------ -------- ----------- --------- ------------- Chassis1 N/A BIOS 1.2.3 Chassis BIOS BMC 5.1 Chassis BMC Signed-off-by: Taras Keryk <tarasx.keryk@intel.com> * [BFN] Implementation API for platform component get chassis name from json * [BFN] Implementation API for platform component Updated platform and platrom_components json * [BFN] Implementation API for platform component Fixed spaces in component.py * [BFN] Implementation API for platform component Fixed exception in component.py * Update chassis.py * [BFN] Implementation API for platform component Fixed spaces in component.py, chassis.py * [BFN] Implementation API for platform component: Fixed spaces in component.py, chassis.py * Fixed exception in get_bios_version
2022-03-10 04:55:06 -06:00
import subprocess
from sonic_platform_base.component_base import ComponentBase
from platform_thrift_client import thrift_try
import json
from collections import OrderedDict
from sonic_py_common import device_info
except ImportError as e:
raise ImportError(str(e) + "- required module not found")
def get_bios_version():
"""
Retrieves the firmware version of the BIOS
Returns:
A string containing the firmware version of the BIOS
"""
try:
[BFN] Fix exception when fwutil run without sudo (#10335) * [BFN] Fix for run fwutil without sudo SONiC has a concept of "platform components" this may include - CPLD, FPGA, BIOS, BMC, etc. These changes are needed to read the version of the BIOS and BMC component. What I did The previous implementaion of component.py expect fwutil run with sudo. When fwutil run without sudo, there are an exception: ``` Traceback (most recent call last): File "/usr/local/bin/fwutil", line 5, in <module> from fwutil.main import cli File "/usr/local/lib/python3.9/dist-packages/fwutil/__init__.py", line 3, in <module> from . import main File "/usr/local/lib/python3.9/dist-packages/fwutil/main.py", line 40, in <module> pdp = PlatformDataProvider() File "/usr/local/lib/python3.9/dist-packages/fwutil/lib.py", line 159, in __init__ self.__platform = Platform() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/platform.py", line 21, in __init__ self._chassis = Chassis() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/chassis.py", line 48, in __init__ self.__initialize_components() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/chassis.py", line 136, in __initialize_components component = Components(index) File "/usr/local/lib/python3.9/dist-packages/sonic_platform/component.py", line 184, in __init__ self.version = get_bios_version() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/component.py", line 19, in get_bios_version return subprocess.check_output(['dmidecode', '-s', 'bios-version']).strip().decode() File "/usr/lib/python3.9/subprocess.py", line 424, in check_output return run(*popenargs, stdout=PIPE, timeout=timeout, check=True, File "/usr/lib/python3.9/subprocess.py", line 505, in run with Popen(*popenargs, **kwargs) as process: File "/usr/lib/python3.9/subprocess.py", line 951, in __init__ self._execute_child(args, executable, preexec_fn, close_fds, File "/usr/lib/python3.9/subprocess.py", line 1823, in _execute_child raise child_exception_type(errno_num, err_msg, err_filename) FileNotFoundError: [Errno 2] No such file or directory: 'dmidecode' ``` How I did it Modification of dmidecode command How to verify it Run manually 'fwutil' (without sudo) Previous command output had exception New command output: Root privileges are required Signed-off-by: Taras Keryk <tarasx.keryk@intel.com> * Why I did it The previous implementaion of component.py expect fwutil run with sudo. When fwutil run without sudo, there are an exception: Traceback (most recent call last): File "/usr/local/bin/fwutil", line 5, in <module> from fwutil.main import cli File "/usr/local/lib/python3.9/dist-packages/fwutil/__init__.py", line 3, in <module> from . import main File "/usr/local/lib/python3.9/dist-packages/fwutil/main.py", line 40, in <module> pdp = PlatformDataProvider() File "/usr/local/lib/python3.9/dist-packages/fwutil/lib.py", line 159, in __init__ self.__platform = Platform() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/platform.py", line 21, in __init__ self._chassis = Chassis() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/chassis.py", line 48, in __init__ self.__initialize_components() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/chassis.py", line 136, in __initialize_components component = Components(index) File "/usr/local/lib/python3.9/dist-packages/sonic_platform/component.py", line 184, in __init__ self.version = get_bios_version() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/component.py", line 19, in get_bios_version return subprocess.check_output(['dmidecode', '-s', 'bios-version']).strip().decode() File "/usr/lib/python3.9/subprocess.py", line 424, in check_output return run(*popenargs, stdout=PIPE, timeout=timeout, check=True, File "/usr/lib/python3.9/subprocess.py", line 505, in run with Popen(*popenargs, **kwargs) as process: File "/usr/lib/python3.9/subprocess.py", line 951, in __init__ self._execute_child(args, executable, preexec_fn, close_fds, File "/usr/lib/python3.9/subprocess.py", line 1823, in _execute_child raise child_exception_type(errno_num, err_msg, err_filename) FileNotFoundError: [Errno 2] No such file or directory: 'dmidecode' How I did it Modification of dmidecode command How to verify it Run manually 'fwutil' (without sudo) Previous command output had exception New command output: Root privileges are required Signed-off-by: Taras Keryk tarasx.keryk@intel.com Signed-off-by: Taras Keryk <tarasx.keryk@intel.com> * rewrite a call of dmidecode, when run without sudo Signed-off-by: Taras Keryk <tarasx.keryk@intel.com> * Why I did it The previous implementaion of component.py expect fwutil run with sudo. When fwutil run without sudo, there are an exception: Traceback (most recent call last): File "/usr/local/bin/fwutil", line 5, in <module> from fwutil.main import cli File "/usr/local/lib/python3.9/dist-packages/fwutil/__init__.py", line 3, in <module> from . import main File "/usr/local/lib/python3.9/dist-packages/fwutil/main.py", line 40, in <module> pdp = PlatformDataProvider() File "/usr/local/lib/python3.9/dist-packages/fwutil/lib.py", line 159, in __init__ self.__platform = Platform() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/platform.py", line 21, in __init__ self._chassis = Chassis() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/chassis.py", line 48, in __init__ self.__initialize_components() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/chassis.py", line 136, in __initialize_components component = Components(index) File "/usr/local/lib/python3.9/dist-packages/sonic_platform/component.py", line 184, in __init__ self.version = get_bios_version() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/component.py", line 19, in get_bios_version return subprocess.check_output(['dmidecode', '-s', 'bios-version']).strip().decode() File "/usr/lib/python3.9/subprocess.py", line 424, in check_output return run(*popenargs, stdout=PIPE, timeout=timeout, check=True, File "/usr/lib/python3.9/subprocess.py", line 505, in run with Popen(*popenargs, **kwargs) as process: File "/usr/lib/python3.9/subprocess.py", line 951, in __init__ self._execute_child(args, executable, preexec_fn, close_fds, File "/usr/lib/python3.9/subprocess.py", line 1823, in _execute_child raise child_exception_type(errno_num, err_msg, err_filename) FileNotFoundError: [Errno 2] No such file or directory: 'dmidecode' The previous implementaion of eeprom.py expect fwutil run with sudo. When fwutil run without sudo, there are an exception: Traceback (most recent call last): File "/usr/lib/python3.9/logging/config.py", line 564, in configure handler = self.configure_handler(handlers[name]) File "/usr/lib/python3.9/logging/config.py", line 745, in configure_handler result = factory(**kwargs) File "/usr/lib/python3.9/logging/handlers.py", line 153, in init BaseRotatingHandler.init(self, filename, mode, encoding=encoding, File "/usr/lib/python3.9/logging/handlers.py", line 58, in init logging.FileHandler.init(self, filename, mode=mode, File "/usr/lib/python3.9/logging/init.py", line 1142, in init StreamHandler.init(self, self._open()) File "/usr/lib/python3.9/logging/init.py", line 1171, in _open return open(self.baseFilename, self.mode, encoding=self.encoding, PermissionError: [Errno 13] Permission denied: '/var/log/platform.log' The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/usr/local/bin/fwutil", line 5, in from fwutil.main import cli File "/usr/local/lib/python3.9/dist-packages/fwutil/init.py", line 3, in from . import main File "/usr/local/lib/python3.9/dist-packages/fwutil/main.py", line 41, in pdp = PlatformDataProvider() File "/usr/local/lib/python3.9/dist-packages/fwutil/lib.py", line 162, in init self.chassis_component_map = self.__get_chassis_component_map() File "/usr/local/lib/python3.9/dist-packages/fwutil/lib.py", line 168, in __get_chassis_component_map chassis_name = self.__chassis.get_name() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/chassis.py", line 146, in get_name return self._eeprom.modelstr() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/chassis.py", line 54, in _eeprom self.__eeprom = Eeprom() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/eeprom.py", line 50, in init logging.config.dictConfig(config_dict) File "/usr/lib/python3.9/logging/config.py", line 809, in dictConfig dictConfigClass(config).configure() File "/usr/lib/python3.9/logging/config.py", line 571, in configure raise ValueError('Unable to configure handler ' ValueError: Unable to configure handler 'file' How I did it Modification call of dmidecode command. Added modification of log files access attributes before file open operations. How to verify it Run manually 'fwutil' (without sudo) New command output have no exception. Signed-off-by: Taras Keryk <tarasx.keryk@intel.com> * Added file_check for checking access to log files for eeprom.py Signed-off-by: Taras Keryk <tarasx.keryk@intel.com> * Removed unused import * Added logfile_create to eeprom.py and chassis.py Signed-off-by: Taras Keryk <tarasx.keryk@intel.com> * Created platform_utils.py Signed-off-by: Taras Keryk <tarasx.keryk@intel.com> * Added interpreter string to platform_utils.py Signed-off-by: Taras Keryk <tarasx.keryk@intel.com>
2022-04-05 13:33:51 -05:00
cmd = ['dmidecode', '-s', 'bios-version']
if os.geteuid() != 0:
cmd.insert(0, 'sudo')
return subprocess.check_output(cmd).strip().decode()
[BFN] Implementation API for platform component (#10180) * [BFN] Implementation API for platform component SONiC has a concept of "platform components" this may include - CPLD, FPGA, BIOS, BMC, etc. These changes are needed to read the version of the BIOS and BMC component. What I did Create components.py module Add funcion for reading componet version to thrift interface How I did it The previous implementaion didn't have platform components API, so fwutil return an empty list. After implementation of the platform component API, we have actual list of platform components and firmware versions How to verify it Run manually 'fwutil show status' or run unit tests Previous command output Chassis Module Component Version Description ------------------------ -------- ----------- --------- ------------- New command output Chassis Module Component Version Description ------------------------ -------- ----------- --------- ------------- Chassis1 N/A BIOS 1.2.3 Chassis BIOS BMC 5.1 Chassis BMC Signed-off-by: Taras Keryk <tarasx.keryk@intel.com> * [BFN] Implementation API for platform component SONiC has a concept of "platform components" this may include - CPLD, FPGA, BIOS, BMC, etc. These changes are needed to read the version of the BIOS and BMC component. What I did Create components.py module Add funcion for reading componet version to thrift interface How I did it The previous implementaion didn't have platform components API, so fwutil return an empty list. After implementation of the platform component API, we have actual list of platform components and firmware versions How to verify it Run manually 'fwutil show status' or run unit tests Previous command output Chassis Module Component Version Description ------------------------ -------- ----------- --------- ------------- New command output Chassis Module Component Version Description ------------------------ -------- ----------- --------- ------------- Chassis1 N/A BIOS 1.2.3 Chassis BIOS BMC 5.1 Chassis BMC Signed-off-by: Taras Keryk <tarasx.keryk@intel.com> * [BFN] Implementation API for platform component get chassis name from json * [BFN] Implementation API for platform component Updated platform and platrom_components json * [BFN] Implementation API for platform component Fixed spaces in component.py * [BFN] Implementation API for platform component Fixed exception in component.py * Update chassis.py * [BFN] Implementation API for platform component Fixed spaces in component.py, chassis.py * [BFN] Implementation API for platform component: Fixed spaces in component.py, chassis.py * Fixed exception in get_bios_version
2022-03-10 04:55:06 -06:00
except subprocess.CalledProcessError as e:
[BFN] Fix exception when fwutil run without sudo (#10335) * [BFN] Fix for run fwutil without sudo SONiC has a concept of "platform components" this may include - CPLD, FPGA, BIOS, BMC, etc. These changes are needed to read the version of the BIOS and BMC component. What I did The previous implementaion of component.py expect fwutil run with sudo. When fwutil run without sudo, there are an exception: ``` Traceback (most recent call last): File "/usr/local/bin/fwutil", line 5, in <module> from fwutil.main import cli File "/usr/local/lib/python3.9/dist-packages/fwutil/__init__.py", line 3, in <module> from . import main File "/usr/local/lib/python3.9/dist-packages/fwutil/main.py", line 40, in <module> pdp = PlatformDataProvider() File "/usr/local/lib/python3.9/dist-packages/fwutil/lib.py", line 159, in __init__ self.__platform = Platform() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/platform.py", line 21, in __init__ self._chassis = Chassis() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/chassis.py", line 48, in __init__ self.__initialize_components() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/chassis.py", line 136, in __initialize_components component = Components(index) File "/usr/local/lib/python3.9/dist-packages/sonic_platform/component.py", line 184, in __init__ self.version = get_bios_version() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/component.py", line 19, in get_bios_version return subprocess.check_output(['dmidecode', '-s', 'bios-version']).strip().decode() File "/usr/lib/python3.9/subprocess.py", line 424, in check_output return run(*popenargs, stdout=PIPE, timeout=timeout, check=True, File "/usr/lib/python3.9/subprocess.py", line 505, in run with Popen(*popenargs, **kwargs) as process: File "/usr/lib/python3.9/subprocess.py", line 951, in __init__ self._execute_child(args, executable, preexec_fn, close_fds, File "/usr/lib/python3.9/subprocess.py", line 1823, in _execute_child raise child_exception_type(errno_num, err_msg, err_filename) FileNotFoundError: [Errno 2] No such file or directory: 'dmidecode' ``` How I did it Modification of dmidecode command How to verify it Run manually 'fwutil' (without sudo) Previous command output had exception New command output: Root privileges are required Signed-off-by: Taras Keryk <tarasx.keryk@intel.com> * Why I did it The previous implementaion of component.py expect fwutil run with sudo. When fwutil run without sudo, there are an exception: Traceback (most recent call last): File "/usr/local/bin/fwutil", line 5, in <module> from fwutil.main import cli File "/usr/local/lib/python3.9/dist-packages/fwutil/__init__.py", line 3, in <module> from . import main File "/usr/local/lib/python3.9/dist-packages/fwutil/main.py", line 40, in <module> pdp = PlatformDataProvider() File "/usr/local/lib/python3.9/dist-packages/fwutil/lib.py", line 159, in __init__ self.__platform = Platform() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/platform.py", line 21, in __init__ self._chassis = Chassis() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/chassis.py", line 48, in __init__ self.__initialize_components() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/chassis.py", line 136, in __initialize_components component = Components(index) File "/usr/local/lib/python3.9/dist-packages/sonic_platform/component.py", line 184, in __init__ self.version = get_bios_version() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/component.py", line 19, in get_bios_version return subprocess.check_output(['dmidecode', '-s', 'bios-version']).strip().decode() File "/usr/lib/python3.9/subprocess.py", line 424, in check_output return run(*popenargs, stdout=PIPE, timeout=timeout, check=True, File "/usr/lib/python3.9/subprocess.py", line 505, in run with Popen(*popenargs, **kwargs) as process: File "/usr/lib/python3.9/subprocess.py", line 951, in __init__ self._execute_child(args, executable, preexec_fn, close_fds, File "/usr/lib/python3.9/subprocess.py", line 1823, in _execute_child raise child_exception_type(errno_num, err_msg, err_filename) FileNotFoundError: [Errno 2] No such file or directory: 'dmidecode' How I did it Modification of dmidecode command How to verify it Run manually 'fwutil' (without sudo) Previous command output had exception New command output: Root privileges are required Signed-off-by: Taras Keryk tarasx.keryk@intel.com Signed-off-by: Taras Keryk <tarasx.keryk@intel.com> * rewrite a call of dmidecode, when run without sudo Signed-off-by: Taras Keryk <tarasx.keryk@intel.com> * Why I did it The previous implementaion of component.py expect fwutil run with sudo. When fwutil run without sudo, there are an exception: Traceback (most recent call last): File "/usr/local/bin/fwutil", line 5, in <module> from fwutil.main import cli File "/usr/local/lib/python3.9/dist-packages/fwutil/__init__.py", line 3, in <module> from . import main File "/usr/local/lib/python3.9/dist-packages/fwutil/main.py", line 40, in <module> pdp = PlatformDataProvider() File "/usr/local/lib/python3.9/dist-packages/fwutil/lib.py", line 159, in __init__ self.__platform = Platform() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/platform.py", line 21, in __init__ self._chassis = Chassis() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/chassis.py", line 48, in __init__ self.__initialize_components() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/chassis.py", line 136, in __initialize_components component = Components(index) File "/usr/local/lib/python3.9/dist-packages/sonic_platform/component.py", line 184, in __init__ self.version = get_bios_version() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/component.py", line 19, in get_bios_version return subprocess.check_output(['dmidecode', '-s', 'bios-version']).strip().decode() File "/usr/lib/python3.9/subprocess.py", line 424, in check_output return run(*popenargs, stdout=PIPE, timeout=timeout, check=True, File "/usr/lib/python3.9/subprocess.py", line 505, in run with Popen(*popenargs, **kwargs) as process: File "/usr/lib/python3.9/subprocess.py", line 951, in __init__ self._execute_child(args, executable, preexec_fn, close_fds, File "/usr/lib/python3.9/subprocess.py", line 1823, in _execute_child raise child_exception_type(errno_num, err_msg, err_filename) FileNotFoundError: [Errno 2] No such file or directory: 'dmidecode' The previous implementaion of eeprom.py expect fwutil run with sudo. When fwutil run without sudo, there are an exception: Traceback (most recent call last): File "/usr/lib/python3.9/logging/config.py", line 564, in configure handler = self.configure_handler(handlers[name]) File "/usr/lib/python3.9/logging/config.py", line 745, in configure_handler result = factory(**kwargs) File "/usr/lib/python3.9/logging/handlers.py", line 153, in init BaseRotatingHandler.init(self, filename, mode, encoding=encoding, File "/usr/lib/python3.9/logging/handlers.py", line 58, in init logging.FileHandler.init(self, filename, mode=mode, File "/usr/lib/python3.9/logging/init.py", line 1142, in init StreamHandler.init(self, self._open()) File "/usr/lib/python3.9/logging/init.py", line 1171, in _open return open(self.baseFilename, self.mode, encoding=self.encoding, PermissionError: [Errno 13] Permission denied: '/var/log/platform.log' The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/usr/local/bin/fwutil", line 5, in from fwutil.main import cli File "/usr/local/lib/python3.9/dist-packages/fwutil/init.py", line 3, in from . import main File "/usr/local/lib/python3.9/dist-packages/fwutil/main.py", line 41, in pdp = PlatformDataProvider() File "/usr/local/lib/python3.9/dist-packages/fwutil/lib.py", line 162, in init self.chassis_component_map = self.__get_chassis_component_map() File "/usr/local/lib/python3.9/dist-packages/fwutil/lib.py", line 168, in __get_chassis_component_map chassis_name = self.__chassis.get_name() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/chassis.py", line 146, in get_name return self._eeprom.modelstr() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/chassis.py", line 54, in _eeprom self.__eeprom = Eeprom() File "/usr/local/lib/python3.9/dist-packages/sonic_platform/eeprom.py", line 50, in init logging.config.dictConfig(config_dict) File "/usr/lib/python3.9/logging/config.py", line 809, in dictConfig dictConfigClass(config).configure() File "/usr/lib/python3.9/logging/config.py", line 571, in configure raise ValueError('Unable to configure handler ' ValueError: Unable to configure handler 'file' How I did it Modification call of dmidecode command. Added modification of log files access attributes before file open operations. How to verify it Run manually 'fwutil' (without sudo) New command output have no exception. Signed-off-by: Taras Keryk <tarasx.keryk@intel.com> * Added file_check for checking access to log files for eeprom.py Signed-off-by: Taras Keryk <tarasx.keryk@intel.com> * Removed unused import * Added logfile_create to eeprom.py and chassis.py Signed-off-by: Taras Keryk <tarasx.keryk@intel.com> * Created platform_utils.py Signed-off-by: Taras Keryk <tarasx.keryk@intel.com> * Added interpreter string to platform_utils.py Signed-off-by: Taras Keryk <tarasx.keryk@intel.com>
2022-04-05 13:33:51 -05:00
raise RuntimeError("Failed to get BIOS version")
[BFN] Implementation API for platform component (#10180) * [BFN] Implementation API for platform component SONiC has a concept of "platform components" this may include - CPLD, FPGA, BIOS, BMC, etc. These changes are needed to read the version of the BIOS and BMC component. What I did Create components.py module Add funcion for reading componet version to thrift interface How I did it The previous implementaion didn't have platform components API, so fwutil return an empty list. After implementation of the platform component API, we have actual list of platform components and firmware versions How to verify it Run manually 'fwutil show status' or run unit tests Previous command output Chassis Module Component Version Description ------------------------ -------- ----------- --------- ------------- New command output Chassis Module Component Version Description ------------------------ -------- ----------- --------- ------------- Chassis1 N/A BIOS 1.2.3 Chassis BIOS BMC 5.1 Chassis BMC Signed-off-by: Taras Keryk <tarasx.keryk@intel.com> * [BFN] Implementation API for platform component SONiC has a concept of "platform components" this may include - CPLD, FPGA, BIOS, BMC, etc. These changes are needed to read the version of the BIOS and BMC component. What I did Create components.py module Add funcion for reading componet version to thrift interface How I did it The previous implementaion didn't have platform components API, so fwutil return an empty list. After implementation of the platform component API, we have actual list of platform components and firmware versions How to verify it Run manually 'fwutil show status' or run unit tests Previous command output Chassis Module Component Version Description ------------------------ -------- ----------- --------- ------------- New command output Chassis Module Component Version Description ------------------------ -------- ----------- --------- ------------- Chassis1 N/A BIOS 1.2.3 Chassis BIOS BMC 5.1 Chassis BMC Signed-off-by: Taras Keryk <tarasx.keryk@intel.com> * [BFN] Implementation API for platform component get chassis name from json * [BFN] Implementation API for platform component Updated platform and platrom_components json * [BFN] Implementation API for platform component Fixed spaces in component.py * [BFN] Implementation API for platform component Fixed exception in component.py * Update chassis.py * [BFN] Implementation API for platform component Fixed spaces in component.py, chassis.py * [BFN] Implementation API for platform component: Fixed spaces in component.py, chassis.py * Fixed exception in get_bios_version
2022-03-10 04:55:06 -06:00
def get_bmc_version():
"""
Retrieves the firmware version of the BMC
Returns:
A string containing the firmware version of the BMC
"""
ver = "N/A"
def bmc_get(client):
return client.pltfm_mgr.pltfm_mgr_chss_mgmt_bmc_ver_get()
try:
ver = thrift_try(bmc_get)
except Exception:
pass
return ver
class BFPlatformComponentsParser(object):
"""
BFPlatformComponentsParser
"""
CHASSIS_KEY = "chassis"
MODULE_KEY = "module"
COMPONENT_KEY = "component"
FIRMWARE_KEY = "firmware"
def __init__(self, platform_components_path):
self.__chassis_component_map = OrderedDict()
self.__component_list = []
self.__bf_model = ""
self.__parse_platform_components(platform_components_path)
def __is_str(self, obj):
return isinstance(obj, str)
def __is_dict(self, obj):
return isinstance(obj, dict)
def __parser_fail(self, msg):
raise RuntimeError("Failed to parse \"{}\": {}".format(PLATFORM_COMPONENTS_FILE, msg))
def __parser_platform_fail(self, msg):
self.__parser_fail("invalid platform schema: {}".format(msg))
def __parser_chassis_fail(self, msg):
self.__parser_fail("invalid chassis schema: {}".format(msg))
def __parser_component_fail(self, msg):
self.__parser_fail("invalid component schema: {}".format(msg))
def __parse_component_section(self, section, component, is_module_component=False):
if not self.__is_dict(component):
self.__parser_component_fail("dictionary is expected: key={}".format(self.COMPONENT_KEY))
if not component:
return
missing_key = None
for key1, value1 in component.items():
if not self.__is_dict(value1):
self.__parser_component_fail("dictionary is expected: key={}".format(key1))
self.__chassis_component_map[section][key1] = OrderedDict()
if value1:
if len(value1) < 1 or len(value1) > 3:
self.__parser_component_fail("unexpected number of records: key={}".format(key1))
if self.FIRMWARE_KEY not in value1:
missing_key = self.FIRMWARE_KEY
break
for key2, value2 in value1.items():
if not self.__is_str(value2):
self.__parser_component_fail("string is expected: key={}".format(key2))
self.__chassis_component_map[section][key1] = value1
if missing_key is not None:
self.__parser_component_fail("\"{}\" key hasn't been found".format(missing_key))
def __parse_chassis_section(self, chassis):
self.__chassis_component_map = OrderedDict()
if not self.__is_dict(chassis):
self.__parser_chassis_fail("dictionary is expected: key={}".format(self.CHASSIS_KEY))
if not chassis:
self.__parser_chassis_fail("dictionary is empty: key={}".format(self.CHASSIS_KEY))
if len(chassis) != 1:
self.__parser_chassis_fail("unexpected number of records: key={}".format(self.CHASSIS_KEY))
for key, value in chassis.items():
if not self.__is_dict(value):
self.__parser_chassis_fail("dictionary is expected: key={}".format(key))
if not value:
self.__parser_chassis_fail("dictionary is empty: key={}".format(key))
if self.COMPONENT_KEY not in value:
self.__parser_chassis_fail("\"{}\" key hasn't been found".format(self.COMPONENT_KEY))
if len(value) != 1:
self.__parser_chassis_fail("unexpected number of records: key={}".format(key))
self.__chassis_component_map[key] = OrderedDict()
self.__parse_component_section(key, value[self.COMPONENT_KEY])
def get_components_list(self):
self.__component_list = []
for key, value in self.__chassis_component_map[self.__bf_model].items():
self.__component_list.append(key)
return self.__component_list
def get_chassis_component_map(self):
return self.__chassis_component_map
def __parse_platform_components(self, platform_components_path):
with open(platform_components_path) as platform_components:
data = json.load(platform_components)
kkey, val = list(data[self.CHASSIS_KEY].items())[0]
self.__bf_model = kkey
if not self.__is_dict(data):
self.__parser_platform_fail("dictionary is expected: key=root")
if not data:
self.__parser_platform_fail("dictionary is empty: key=root")
if self.CHASSIS_KEY not in data:
self.__parser_platform_fail("\"{}\" key hasn't been found".format(self.CHASSIS_KEY))
if len(data) != 1:
self.__parser_platform_fail("unexpected number of records: key=root")
self.__parse_chassis_section(data[self.CHASSIS_KEY])
chassis_component_map = property(fget=get_chassis_component_map)
class Components(ComponentBase):
"""BFN Montara Platform-specific Component class"""
bf_platform = device_info.get_path_to_platform_dir()
bf_platform_json = "{}/platform_components.json".format(bf_platform.strip())
bpcp = BFPlatformComponentsParser(bf_platform_json)
def __init__(self, component_index=0):
try:
self.index = component_index
self.name = "N/A"
self.version = "N/A"
self.description = "N/A"
self.name = self.bpcp.get_components_list()[self.index]
except IndexError as e:
print("Error: No components found in plaform_components.json")
if (self.name == "BMC"):
self.version = get_bmc_version()
self.description = "Chassis BMC"
elif (self.name == "BIOS"):
self.version = get_bios_version()
self.description = "Chassis BIOS"
def get_name(self):
"""
Retrieves the name of the component
Returns:
A string containing the name of the component
"""
if not self.name:
return "N/A"
return self.name
def get_description(self):
"""
Retrieves the description of the component
Returns:
A string containing the description of the component
"""
return self.description
def get_firmware_version(self):
"""
Retrieves the firmware version of the component
Returns:
A string containing the firmware version of the component
"""
return self.version
def install_firmware(self, image_path):
"""
Installs firmware to the component
Args:
image_path: A string, path to firmware image
Returns:
A boolean, True if install was successful, False if not
"""
return False
def get_presence(self):
"""
Retrieves the presence of the component
Returns:
bool: True if component is present, False if not
"""
return True
def get_model(self):
"""
Retrieves the model number (or part number) of the component
Returns:
string: Model/part number of component
"""
return 'N/A'
def get_serial(self):
"""
Retrieves the serial number of the component
Returns:
string: Serial number of component
"""
return 'N/A'
def get_status(self):
"""
Retrieves the operational status of the component
Returns:
A boolean value, True if component is operating properly, False if not
"""
return True
def get_position_in_parent(self):
"""
Retrieves 1-based relative physical position in parent device.
If the agent cannot determine the parent-relative position
for some reason, or if the associated value of
entPhysicalContainedIn is'0', then the value '-1' is returned
Returns:
integer: The 1-based relative physical position in parent device
or -1 if cannot determine the position
"""
return -1
def is_replaceable(self):
"""
Indicate whether this component is replaceable.
Returns:
bool: True if it is replaceable.
"""
return False
def get_available_firmware_version(self, image_path):
return 'None'
def get_firmware_update_notification(self, image_path):
"""
Retrieves a notification on what should be done in order to complete
the component firmware update
Args:
image_path: A string, path to firmware image
Returns:
A string containing the component firmware update notification if required.
By default 'None' value will be used, which indicates that no actions are required
"""
return 'None'
def update_firmware(self, image_path):
"""
Updates firmware of the component
This API performs firmware update: it assumes firmware installation and loading in a single call.
In case platform component requires some extra steps (apart from calling Low Level Utility)
to load the installed firmware (e.g, reboot, power cycle, etc.) - this will be done automatically by API
Args:
image_path: A string, path to firmware image
Raises:
RuntimeError: update failed
"""
return False
def auto_update_firmware(self, image_path, boot_action):
"""
Default handling of attempted automatic update for a component
Will skip the installation if the boot_action is 'warm' or 'fast' and will call update_firmware()
if boot_action is fast.
"""
return 1