Ejemplo n.º 1
0
class Chassis(ChassisBase):
    """Platform-specific Chassis class"""
    def __init__(self):
        super(Chassis, self).__init__()

        for fantray_index in range(0, NUM_FAN_TRAY):
            for fan_index in range(0, NUM_FAN):
                fan = Fan(fantray_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)

        self.PORT_START = SFP_PORT_START
        self.QSFP_PORT_START = QSFP_PORT_START
        self.PORT_END = QSFP_PORT_END
        for index in range(0, NUM_SFP):
            if index in range(self.QSFP_PORT_START, self.QSPORT_END + 1):
                sfp_module = Sfp(index, 'QSFP')
            else:
                sfp_module = Sfp(index, 'SFP')
            self._sfp_list.append(sfp_module)
        self._component_name_list = COMPONENT_NAME_LIST
        self._watchdog = Watchdog()
        self._eeprom = Tlv()
        logger.log_info("Chassis loaded successfully")

    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(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_firmware_version(self, component_name):
        """
        Retrieves platform-specific hardware/firmware versions for chassis
        componenets such as BIOS, CPLD, FPGA, etc.
        Args:
            type: A string, component name

        Returns:
            A string containing platform-specific component versions
        """
        self.component = Component(component_name)
        if component_name not in self._component_name_list:
            return None
        return self.component.get_firmware_version()

    def install_component_firmware(self, component_name, image_path):
        """
        Install firmware to module
        Args:
            type: A string, component name.
            image_path: A string, path to firmware image.

        Returns:
            A boolean, True if install successfully, False if not
        """
        self.component = Component(component_name)
        if component_name not in self._component_name_list:
            return False
        return self.component.upgrade_firmware(image_path)

    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
        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":
            reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE
            description = sw_reboot_cause
        else:
            reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER
            description = 'Unknown reason'

        return (reboot_cause, description)
Ejemplo n.º 2
0
class Chassis(ChassisBase):
    """Platform-specific Chassis class"""
    def __init__(self):
        self.config_data = {}
        ChassisBase.__init__(self)
        self._eeprom = Tlv()
        self._api_helper = APIHelper()

        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)

    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.
        """

        status, raw_cause = self._api_helper.ipmi_raw(IPMI_OEM_NETFN,
                                                      IPMI_GET_REBOOT_CAUSE)
        hx_cause = raw_cause.split()[0] if status else 00
        reboot_cause = {
            "00": self.REBOOT_CAUSE_HARDWARE_OTHER,
            "11": self.REBOOT_CAUSE_POWER_LOSS,
            "22": self.REBOOT_CAUSE_NON_HARDWARE,
            "33": self.REBOOT_CAUSE_HARDWARE_OTHER,
            "44": self.REBOOT_CAUSE_NON_HARDWARE,
            "55": self.REBOOT_CAUSE_NON_HARDWARE,
            "66": self.REBOOT_CAUSE_WATCHDOG,
            "77": self.REBOOT_CAUSE_NON_HARDWARE
        }.get(hx_cause, self.REBOOT_CAUSE_HARDWARE_OTHER)

        description = {
            "00": "Unknown reason",
            "11": "The last reset is Power on reset",
            "22": "The last reset is soft-set CPU warm reset",
            "33": "The last reset is soft-set CPU cold reset",
            "44": "The last reset is CPU warm reset",
            "55": "The last reset is CPU cold reset",
            "66": "The last reset is watchdog reset",
            "77": "The last reset is power cycle reset"
        }.get(hx_cause, "Unknown reason")

        return (reboot_cause, description)
Ejemplo n.º 3
0
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._reboot_cause_path = HOST_REBOOT_CAUSE_PATH if self.__is_host(
        ) else PMON_REBOOT_CAUSE_PATH

        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
        hw_reboot_cause = self._component_list[0].get_register_value(
            RESET_REGISTER)
        sw_reboot_cause = self.__read_txt_file(
            self._reboot_cause_path) or "Unknown"

        if hw_reboot_cause == "0x55":
            reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE
            description = sw_reboot_cause
        elif hw_reboot_cause == "0x11":
            reboot_cause = self.REBOOT_CAUSE_POWER_LOSS
        elif hw_reboot_cause == "0x33":
            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
Ejemplo n.º 4
0
class Chassis(ChassisBase):
    """Platform-specific Chassis class"""

    CHASSIS_CONFIG = 'chassis.json'
    THERMAL_CONFIG = 'thermal.json'
    SFP_CONFIG = 'sfp.json'
    PSU_CONFIG = 'psu.json'
    FAN_CONFIG = 'fan.json'
    COMPONENT_CONFIG = 'component.json'

    def __init__(self):
        ChassisBase.__init__(self)
        self._api_common = Common()
        config_path = self._api_common.get_config_path(self.CHASSIS_CONFIG)
        self._config = self._api_common.load_json_file(config_path)

        self.sfp_module_initialized = False
        self.__initialize_eeprom()

        if not self._api_common.is_host():
            self.__initialize_fan()
            self.__initialize_psu()
            self.__initialize_thermals()
        else:
            self.__initialize_components()

    def __initialize_fan(self):
        from sonic_platform.fan import Fan
        from sonic_platform.fan_drawer import FanDrawer

        fan_config_path = self._api_common.get_config_path(self.FAN_CONFIG)
        self._fan_config = self._api_common.load_json_file(fan_config_path)

        if self._fan_config:
            fan_index = 0
            for drawer_index in range(0, self._fan_config['drawer_num']):
                drawer_fan_list = []
                for index in range(0, self._fan_config['fan_num_per_drawer']):
                    fan = Fan(fan_index, conf=self._fan_config)
                    fan_index += 1
                    self._fan_list.append(fan)
                    drawer_fan_list.append(fan)
                fan_drawer = FanDrawer(drawer_index, drawer_fan_list)
                self._fan_drawer_list.append(fan_drawer)

    def __initialize_sfp(self):
        from sonic_platform.sfp import Sfp

        sfp_config_path = self._api_common.get_config_path(self.SFP_CONFIG)
        sfp_config = self._api_common.load_json_file(sfp_config_path)

        sfp_index = 0
        for index in range(0, sfp_config['port_num']):
            sfp = Sfp(sfp_index, conf=sfp_config)
            self._sfp_list.append(sfp)
            sfp_index += 1
        self.sfp_module_initialized = True

    def __initialize_psu(self):
        from sonic_platform.psu import Psu

        psu_config_path = self._api_common.get_config_path(self.PSU_CONFIG)
        psu_config = self._api_common.load_json_file(psu_config_path)

        if psu_config:
            psu_index = 0
            for index in range(0, psu_config['psu_num']):
                psu = Psu(psu_index,
                          conf=psu_config,
                          fan_conf=self._fan_config)
                psu_index += 1
                self._psu_list.append(psu)

    def __initialize_thermals(self):
        from sonic_platform.thermal import Thermal

        thermal_config_path = self._api_common.get_config_path(
            self.THERMAL_CONFIG)
        thermal_config = self._api_common.load_json_file(thermal_config_path)

        thermal_index = 0
        for index in range(0, thermal_config['thermal_num']):
            thermal = Thermal(thermal_index, conf=thermal_config)
            thermal_index += 1
            self._thermal_list.append(thermal)

    def __initialize_eeprom(self):
        from sonic_platform.eeprom import Tlv
        self._eeprom = Tlv(self._config)

    def __initialize_components(self):
        from component import Component

        component_config_path = self._api_common.get_config_path(
            self.COMPONENT_CONFIG)
        component_config = self._api_common.load_json_file(
            component_config_path)

        for index in range(0, component_config['component_num']):
            component = Component(index, conf=component_config)
            self._component_list.append(component)

    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.

        Avaliable reboot cause:
            REBOOT_CAUSE_POWER_LOSS = "Power Loss"
            REBOOT_CAUSE_THERMAL_OVERLOAD_CPU = "Thermal Overload: CPU"
            REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC = "Thermal Overload: ASIC"
            REBOOT_CAUSE_THERMAL_OVERLOAD_OTHER = "Thermal Overload: Other"
            REBOOT_CAUSE_INSUFFICIENT_FAN_SPEED = "Insufficient Fan Speed"
            REBOOT_CAUSE_WATCHDOG = "Watchdog"
            REBOOT_CAUSE_HARDWARE_OTHER = "Hardware - Other"
            REBOOT_CAUSE_NON_HARDWARE = "Non-Hardware"

        """
        reboot_cause = self._api_common.get_output(
            0, self._config['get_reboot_cause'],
            self.REBOOT_CAUSE_HARDWARE_OTHER)
        description = self._api_common.get_output(
            0, self._config['get_reboot_description'], 'Unknown')

        return (reboot_cause, description)

    # ##############################################################
    # ######################## SFP methods #########################
    # ##############################################################

    def get_num_sfps(self):
        """
        Retrieves the number of sfps available on this chassis
        Returns:
            An integer, the number of sfps available on this chassis
        """
        if not self.sfp_module_initialized:
            self.__initialize_sfp()

        return len(self._sfp_list)

    def get_all_sfps(self):
        """
        Retrieves all sfps available on this chassis
        Returns:
            A list of objects derived from SfpBase representing all sfps
            available on this chassis
        """
        if not self.sfp_module_initialized:
            self.__initialize_sfp()

        return self._sfp_list

    def get_sfp(self, index):
        """
        Retrieves sfp represented by (1-based) index <index>
        Args:
            index: An integer, the index (1-based) of the sfp to retrieve.
            The index should be the sequence of a physical port in a chassis,
            starting from 1.
            For example, 1 for Ethernet0, 2 for Ethernet4 and so on.
        Returns:
            An object dervied from SfpBase representing the specified sfp
        """
        sfp = None
        if not self.sfp_module_initialized:
            self.__initialize_sfp()

        try:
            # The index will start from 1
            sfp = self._sfp_list[index - 1]
        except IndexError:
            sys.stderr.write("SFP index {} out of range (1-{})\n".format(
                index, len(self._sfp_list)))
        return sfp

    ##############################################################
    ###################### Event methods #########################
    ##############################################################

    def get_change_event(self, timeout=0):
        """
        Returns a nested dictionary containing all devices which have
        experienced a change at chassis level
        Args:
            timeout: Timeout in milliseconds (optional). If timeout == 0,
                this method will block until a change is detected.
        Returns:
            (bool, dict):
                - True if call successful, False if not;
                - A nested dictionary where key is a device type,
                  value is a dictionary with key:value pairs in the format of
                  {'device_id':'device_event'},
                  where device_id is the device ID for this device and
                        device_event,
                             status='1' represents device inserted,
                             status='0' represents device removed.
                  Ex. {'fan':{'0':'0', '2':'1'}, 'sfp':{'11':'0'}}
                      indicates that fan 0 has been removed, fan 2
                      has been inserted and sfp 11 has been removed.
                  Specifically for SFP event, besides SFP plug in and plug out,
                  there are some other error event could be raised from SFP, when
                  these error happened, SFP eeprom will not be avalaible, XCVRD shall
                  stop to read eeprom before SFP recovered from error status.
                      status='2' I2C bus stuck,
                      status='3' Bad eeprom,
                      status='4' Unsupported cable,
                      status='5' High Temperature,
                      status='6' Bad cable.
        """

        if not self.sfp_module_initialized:
            self.__initialize_sfp()

        return self._api_common.get_event(timeout,
                                          self._config['get_change_event'],
                                          self._sfp_list)

    # ##############################################################
    # ###################### Other methods ########################
    # ##############################################################

    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:
            wdt = self._api_common.get_output(0, self._config['get_watchdog'],
                                              None)
            self._watchdog = wdt()

        return self._watchdog

    # ##############################################################
    # ###################### Device methods ########################
    # ##############################################################

    def get_name(self):
        """
        Retrieves the name of the device
            Returns:
            string: The name of the device
        """
        return self._api_common.hwsku

    def get_presence(self):
        """
        Retrieves the presence of the PSU
        Returns:
            bool: True if PSU is present, False if not
        """
        return True

    def get_model(self):
        """
        Retrieves the model number (or part number) of the device
        Returns:
            string: Model/part number of device
        """
        return self._eeprom.get_pn()

    def get_serial(self):
        """
        Retrieves the serial number of the device
        Returns:
            string: Serial number of device
        """
        return self._eeprom.get_serial()

    def get_status(self):
        """
        Retrieves the operational status of the device
        Returns:
            A boolean value, True if device is operating properly, False if not
        """
        return True