bfe5835650
* [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>
143 lines
4.7 KiB
Python
143 lines
4.7 KiB
Python
try:
|
|
import os
|
|
import sys
|
|
import datetime
|
|
import re
|
|
|
|
sys.path.append(os.path.dirname(__file__))
|
|
|
|
if sys.version_info.major == 3:
|
|
from io import StringIO
|
|
else:
|
|
from cStringIO import StringIO
|
|
|
|
from sonic_platform_base.sonic_eeprom import eeprom_base
|
|
from sonic_platform_base.sonic_eeprom import eeprom_tlvinfo
|
|
from platform_utils import file_create
|
|
|
|
from platform_thrift_client import thrift_try
|
|
except ImportError as e:
|
|
raise ImportError (str(e) + "- required module not found")
|
|
|
|
|
|
_platform_eeprom_map = {
|
|
"prod_name" : ("Product Name", "0x21", 12),
|
|
"odm_pcba_part_num" : ("Part Number", "0x22", 13),
|
|
"prod_ser_num" : ("Serial Number", "0x23", 12),
|
|
"ext_mac_addr" : ("Extended MAC Address Base", "0x24", 12),
|
|
"sys_mfg_date" : ("System Manufacturing Date", "0x25", 4),
|
|
"prod_ver" : ("Product Version", "0x26", 1),
|
|
"ext_mac_addr_size" : ("Extende MAC Address Size", "0x2A", 2),
|
|
"sys_mfger" : ("Manufacturer", "0x2B", 8)
|
|
}
|
|
|
|
_product_dict = {
|
|
"Montara" : "Wedge100BF-32X-O-AC-F-BF",
|
|
"Lower MAV" : "Wedge100BF-65X-O-AC-F-BF",
|
|
"Upper MAV" : "Wedge100BF-65X-O-AC-F-BF"
|
|
}
|
|
|
|
_EEPROM_SYMLINK = "/var/run/platform/eeprom/syseeprom"
|
|
_EEPROM_STATUS = "/var/run/platform/eeprom/status"
|
|
|
|
class Eeprom(eeprom_tlvinfo.TlvInfoDecoder):
|
|
def __init__(self):
|
|
file_create(_EEPROM_SYMLINK, '646')
|
|
file_create(_EEPROM_STATUS, '646')
|
|
with open(_EEPROM_STATUS, 'w') as f:
|
|
f.write("initializing..")
|
|
|
|
self.eeprom_path = _EEPROM_SYMLINK
|
|
super(Eeprom, self).__init__(self.eeprom_path, 0, _EEPROM_STATUS, True)
|
|
|
|
def sys_eeprom_get(client):
|
|
return client.pltfm_mgr.pltfm_mgr_sys_eeprom_get()
|
|
try:
|
|
platform_eeprom = thrift_try(sys_eeprom_get)
|
|
except Exception:
|
|
raise RuntimeError("eeprom.py: Initialization failed")
|
|
|
|
self.__eeprom_init(platform_eeprom)
|
|
|
|
def __eeprom_init(self, platform_eeprom):
|
|
with open(_EEPROM_STATUS, 'w') as f:
|
|
f.write("ok")
|
|
|
|
eeprom_params = ""
|
|
for attr, val in platform_eeprom.__dict__.items():
|
|
if val is None:
|
|
continue
|
|
|
|
elem = _platform_eeprom_map.get(attr)
|
|
if elem is None:
|
|
continue
|
|
|
|
if isinstance(val, str):
|
|
value = val.replace('\0', '')
|
|
else:
|
|
value = str(val)
|
|
|
|
if attr == "sys_mfg_date":
|
|
value = datetime.datetime.strptime(value, '%m-%d-%y').strftime('%m/%d/%Y 00:00:00')
|
|
|
|
product = _product_dict.get(value)
|
|
if product is not None:
|
|
value = product
|
|
if len(eeprom_params) > 0:
|
|
eeprom_params += ","
|
|
eeprom_params += "{0:s}={1:s}".format(elem[1], value)
|
|
|
|
orig_stdout = sys.stdout
|
|
sys.stdout = StringIO()
|
|
try:
|
|
eeprom_data = eeprom_tlvinfo.TlvInfoDecoder.set_eeprom(self, "", [eeprom_params])
|
|
finally:
|
|
decode_output = sys.stdout.getvalue()
|
|
sys.stdout = orig_stdout
|
|
|
|
eeprom_base.EepromDecoder.write_eeprom(self, eeprom_data)
|
|
self.__eeprom_tlv_dict = self.__parse_output(decode_output)
|
|
|
|
def __parse_output(self, decode_output):
|
|
EEPROM_DECODE_HEADLINES = 6
|
|
lines = decode_output.replace('\0', '').split('\n')
|
|
lines = lines[EEPROM_DECODE_HEADLINES:]
|
|
res = dict()
|
|
|
|
for line in lines:
|
|
try:
|
|
# match whitespace-separated tag hex, length and value (value is mathced with its whitespaces)
|
|
match = re.search('(0x[0-9a-fA-F]{2})([\s]+[\S]+[\s]+)([\S]+[\s]*[\S]*)', line)
|
|
if match is not None:
|
|
code = match.group(1)
|
|
value = match.group(3).rstrip('\0')
|
|
res[code] = value
|
|
except Exception:
|
|
pass
|
|
return res
|
|
|
|
def __tlv_get(self, code):
|
|
return self.__eeprom_tlv_dict.get("0x{:X}".format(code), 'N/A')
|
|
|
|
def system_eeprom_info(self):
|
|
return self.__eeprom_tlv_dict
|
|
|
|
def serial_number_str(self):
|
|
return self.__tlv_get(self._TLV_CODE_SERIAL_NUMBER)
|
|
|
|
def serial_str(self):
|
|
return self.serial_number_str()
|
|
|
|
def base_mac_addr(self):
|
|
return self.__tlv_get(self._TLV_CODE_MAC_BASE)
|
|
|
|
def part_number_str(self):
|
|
return self.__tlv_get(self._TLV_CODE_PART_NUMBER)
|
|
|
|
def modelstr(self):
|
|
return self.__tlv_get(self._TLV_CODE_PRODUCT_NAME)
|
|
|
|
def revision_str(self):
|
|
return self.__tlv_get(self._TLV_CODE_LABEL_REVISION)
|
|
|