diff --git a/sonic_platform_base/chassis_base.py b/sonic_platform_base/chassis_base.py index 6cd4403c6..05a633596 100644 --- a/sonic_platform_base/chassis_base.py +++ b/sonic_platform_base/chassis_base.py @@ -151,6 +151,7 @@ def is_modular_chassis(self): A bool value, should return False by default or for fixed-platforms. Should return True for supervisor-cards, line-cards etc running as part of modular-chassis. + For SmartSwitch this should return False. """ return False @@ -218,32 +219,37 @@ def get_component(self, index): def get_num_modules(self): """ Retrieves the number of modules available on this chassis + On a SmarSwitch chassis this will be the number of DPUs. Returns: - An integer, the number of modules available on this chassis + An integer, the number of modules available on this chassis. + On a SmartSwitch this will be the number of DPUs """ return len(self._module_list) def get_all_modules(self): """ - Retrieves all modules available on this chassis + Retrieves all modules available on this chassis. On a SmartSwitch + chassis this will return all the DPUs. Returns: A list of objects derived from ModuleBase representing all - modules available on this chassis + modules available on this chassis. On a SmartSwitch this + will be a list of DPU objects. """ return self._module_list def get_module(self, index): """ Retrieves module represented by (0-based) index + On a SmartSwitch index:0 will fetch DPU0 and so on Args: index: An integer, the index (0-based) of the module to retrieve Returns: - An object dervied from ModuleBase representing the specified + An object derived from ModuleBase representing the specified module """ module = None @@ -263,12 +269,37 @@ def get_module_index(self, module_name): Args: module_name: A string, prefixed by SUPERVISOR, LINE-CARD or FABRIC-CARD Ex. SUPERVISOR0, LINE-CARD1, FABRIC-CARD5 + SmartSwitch Example: DPU0, DPU1, DPU2 ... DPUX Returns: An integer, the index of the ModuleBase object in the module_list """ raise NotImplementedError + ############################################## + # SmartSwitch methods + ############################################## + + def get_dpu_id(self, name): + """ + Retrieves the DPU ID for the given dpu-module name. + Returns None for non-smartswitch chassis. + + Returns: + An integer, indicating the DPU ID Ex: name:DPU0 return value 0, + name:DPU1 return value 1, name:DPUX return value X + """ + raise NotImplementedError + + def is_smartswitch(self): + """ + Retrieves whether the sonic instance is part of smartswitch + + Returns: + Returns:True for SmartSwitch and False for other platforms + """ + return False + ############################################## # Fan methods ############################################## diff --git a/sonic_platform_base/module_base.py b/sonic_platform_base/module_base.py index ccd507b44..0067f116f 100644 --- a/sonic_platform_base/module_base.py +++ b/sonic_platform_base/module_base.py @@ -21,6 +21,7 @@ class ModuleBase(device_base.DeviceBase): MODULE_TYPE_SUPERVISOR = "SUPERVISOR" MODULE_TYPE_LINE = "LINE-CARD" MODULE_TYPE_FABRIC = "FABRIC-CARD" + MODULE_TYPE_DPU = "DPU" # Possible card status for modular chassis # Module state is Empty if no module is inserted in the slot @@ -104,15 +105,17 @@ def get_system_eeprom_info(self): def get_name(self): """ Retrieves the name of the module prefixed by SUPERVISOR, LINE-CARD, - FABRIC-CARD + FABRIC-CARD, DPU0, DPUX Returns: A string, the module name prefixed by one of MODULE_TYPE_SUPERVISOR, - MODULE_TYPE_LINE or MODULE_TYPE_FABRIC and followed by a 0-based index + MODULE_TYPE_LINE or MODULE_TYPE_FABRIC or MODULE_TYPE_DPU and followed + by a 0-based index. Ex. A Chassis having 1 supervisor, 4 line-cards and 6 fabric-cards can provide names SUPERVISOR0, LINE-CARD0 to LINE-CARD3, - FABRIC-CARD0 to FABRIC-CARD5 + FABRIC-CARD0 to FABRIC-CARD5. + A SmartSwitch having 4 DPUs names DPU0 to DPU3 """ raise NotImplementedError @@ -141,6 +144,7 @@ def get_type(self): Returns: A string, the module-type from one of the predefined types: MODULE_TYPE_SUPERVISOR, MODULE_TYPE_LINE or MODULE_TYPE_FABRIC + or MODULE_TYPE_DPU """ raise NotImplementedError @@ -175,7 +179,7 @@ def set_admin_state(self, up): The down state will power down the module and the status should show MODULE_STATUS_OFFLINE. The up state will take the module to MODULE_STATUS_FAULT or - MODULE_STAUS_ONLINE states. + MODULE_STATUS_ONLINE states. Args: up: A boolean, True to set the admin-state to UP. False to set the @@ -196,6 +200,64 @@ def get_maximum_consumed_power(self): """ raise NotImplementedError + ############################################## + # SmartSwitch methods + ############################################## + + def get_dpu_id(self): + """ + Retrieves the DPU ID. Returns None for non-smartswitch chassis. + + Returns: + An integer, indicating the DPU ID. DPU0 returns 0, DPUX returns X + DPU ID can be greater than or equal to 0. + """ + raise NotImplementedError + + def get_reboot_cause(self): + """ + Retrieves the cause of the previous reboot of the DPU module + + 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. + + """ + raise NotImplementedError + + def get_state_info(self): + """ + Retrieves the dpu state object having the detailed dpu state progression. + Fetched from ChassisStateDB. + + Returns: + An object instance of the DPU_STATE (see DB schema) + Returns None on switch module + + Sample Output: + { + 'dpu_control_plane': { + 'state': 'UP', + 'time': '20240626 21:13:25', + 'reason': 'All containers are up and running, host-ethlink-status: Uplink1/1 is UP' + }, + 'dpu_data_plane': { + 'state': 'UP', + 'time': '20240626 21:13:25', + 'reason': 'DPU container named polaris is running, pciemgrd running : OK' + }, + 'dpu_midplane_link': { + 'state': 'UP', + 'time': '20240626 21:13:25', + 'reason': 'INTERNAL-MGMT : admin state - UP, oper_state - UP, status - OK' + } + } + """ + raise NotImplementedError + ############################################## # Component methods ############################################## @@ -227,7 +289,7 @@ def get_component(self, index): index: An integer, the index (0-based) of the component to retrieve Returns: - An object dervied from ComponentBase representing the specified component + An object derived from ComponentBase representing the specified component """ component = None @@ -542,6 +604,9 @@ def get_midplane_ip(self): When called from the line-card, the module will represent the Supervisor and return its midplane IP-address. + When called from the SmartSwitch returns the midplane IP-address of + the DPU module. + Returns: A string, the IP-address of the module reachable over the midplane diff --git a/tests/chassis_base_test.py b/tests/chassis_base_test.py index e550ce5f8..c7dbc512e 100644 --- a/tests/chassis_base_test.py +++ b/tests/chassis_base_test.py @@ -22,6 +22,7 @@ def test_chassis_base(self): not_implemented_methods = [ [chassis.get_uid_led], [chassis.set_uid_led, "COLOR"], + [chassis.get_dpu_id, "DPU0"], ] for method in not_implemented_methods: @@ -35,6 +36,10 @@ def test_chassis_base(self): assert exception_raised + def test_smartswitch(self): + chassis = ChassisBase() + assert(chassis.is_smartswitch() == False) + def test_sensors(self): chassis = ChassisBase() assert(chassis.get_num_voltage_sensors() == 0) diff --git a/tests/module_base_test.py b/tests/module_base_test.py index 20d0ef05a..b4b9519e3 100644 --- a/tests/module_base_test.py +++ b/tests/module_base_test.py @@ -2,6 +2,25 @@ class TestModuleBase: + def test_module_base(self): + module = ModuleBase() + not_implemented_methods = [ + [module.get_dpu_id], + [module.get_reboot_cause], + [module.get_state_info], + ] + + for method in not_implemented_methods: + exception_raised = False + try: + func = method[0] + args = method[1:] + func(*args) + except NotImplementedError: + exception_raised = True + + assert exception_raised + def test_sensors(self): module = ModuleBase() assert(module.get_num_voltage_sensors() == 0)