#!/usr/bin/env python ############################################################################# # Celestica # # Module contains an implementation of SONiC Platform Base API and # provides the Chassis information which are available in the platform # ############################################################################# import sys import re import os import subprocess import json try: from sonic_platform_base.chassis_base import ChassisBase from sonic_platform.fan import Fan from sonic_platform.psu import Psu from sonic_platform.component import Component from sonic_platform.thermal import Thermal from sonic_platform.sfp import Sfp from sonic_platform.eeprom import Tlv except ImportError as e: raise ImportError(str(e) + "- required module not found") NUM_FAN_TRAY = 5 NUM_FAN = 2 NUM_PSU = 2 NUM_THERMAL = 5 NUM_SFP = 32 NUM_COMPONENT = 5 RESET_REGISTER = "0x103" HOST_REBOOT_CAUSE_PATH = "/host/reboot-cause/" PMON_REBOOT_CAUSE_PATH = "/usr/share/sonic/platform/api_files/reboot-cause/" REBOOT_CAUSE_FILE = "reboot-cause.txt" PREV_REBOOT_CAUSE_FILE = "previous-reboot-cause.txt" HOST_CHK_CMD = "docker > /dev/null 2>&1" class Chassis(ChassisBase): """Platform-specific Chassis class""" def __init__(self): ChassisBase.__init__(self) self.config_data = {} for fant_index in range(0, NUM_FAN_TRAY): for fan_index in range(0, NUM_FAN): fan = Fan(fant_index, fan_index) self._fan_list.append(fan) for index in range(0, NUM_PSU): psu = Psu(index) self._psu_list.append(psu) for index in range(0, NUM_THERMAL): thermal = Thermal(index) self._thermal_list.append(thermal) # sfp index start from 1 self._sfp_list.append(None) for index in range(1, NUM_SFP+1): sfp = Sfp(index) self._sfp_list.append(sfp) for index in range(0, NUM_COMPONENT): component = Component(index) self._component_list.append(component) self._eeprom = Tlv() def __is_host(self): return os.system(HOST_CHK_CMD) == 0 def __read_txt_file(self, file_path): try: with open(file_path, 'r') as fd: data = fd.read() return data.strip() except IOError: pass return None def get_base_mac(self): """ Retrieves the base MAC address for the chassis Returns: A string containing the MAC address in the format 'XX:XX:XX:XX:XX:XX' """ return self._eeprom.get_mac() def get_serial_number(self): """ Retrieves the hardware serial number for the chassis Returns: A string containing the hardware serial number for this chassis. """ return self._eeprom.get_serial() def get_system_eeprom_info(self): """ Retrieves the full content of system EEPROM information for the chassis Returns: A dictionary where keys are the type code defined in OCP ONIE TlvInfo EEPROM format and values are their corresponding values. """ return self._eeprom.get_eeprom() def get_reboot_cause(self): """ Retrieves the cause of the previous reboot Returns: A tuple (string, string) where the first element is a string containing the cause of the previous reboot. This string must be one of the predefined strings in this class. If the first string is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used to pass a description of the reboot cause. """ description = 'None' reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER reboot_cause_path = (HOST_REBOOT_CAUSE_PATH + REBOOT_CAUSE_FILE) if self.__is_host( ) else PMON_REBOOT_CAUSE_PATH + REBOOT_CAUSE_FILE prev_reboot_cause_path = (HOST_REBOOT_CAUSE_PATH + PREV_REBOOT_CAUSE_FILE) if self.__is_host( ) else PMON_REBOOT_CAUSE_PATH + PREV_REBOOT_CAUSE_FILE hw_reboot_cause = self._component_list[0].get_register_value(RESET_REGISTER) sw_reboot_cause = self.__read_txt_file( reboot_cause_path) or "Unknown" prev_sw_reboot_cause = self.__read_txt_file( prev_reboot_cause_path) or "Unknown" if sw_reboot_cause == "Unknown" and (prev_sw_reboot_cause == "Unknown" or prev_sw_reboot_cause == self.REBOOT_CAUSE_POWER_LOSS) and hw_reboot_cause == "0x11": reboot_cause = self.REBOOT_CAUSE_POWER_LOSS elif sw_reboot_cause != "Unknown" and hw_reboot_cause == "0x11": reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE description = sw_reboot_cause elif prev_reboot_cause_path != "Unknown" and hw_reboot_cause == "0x11": reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE description = prev_sw_reboot_cause elif hw_reboot_cause == "0x22": reboot_cause = self.REBOOT_CAUSE_WATCHDOG, else: reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER description = 'Unknown reason' return (reboot_cause, description) def get_watchdog(self): """ Retreives hardware watchdog device on this chassis Returns: An object derived from WatchdogBase representing the hardware watchdog device """ if self._watchdog is None: from sonic_platform.watchdog import Watchdog self._watchdog = Watchdog() return self._watchdog