Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Platform APIs for SmartSwitch #454

Merged
merged 16 commits into from
Aug 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 35 additions & 4 deletions sonic_platform_base/chassis_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
rameshraghupathy marked this conversation as resolved.
Show resolved Hide resolved
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 <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
Expand All @@ -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

##############################################
rameshraghupathy marked this conversation as resolved.
Show resolved Hide resolved
# 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
##############################################
Expand Down
75 changes: 70 additions & 5 deletions sonic_platform_base/module_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand All @@ -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
rameshraghupathy marked this conversation as resolved.
Show resolved Hide resolved
DPU ID can be greater than or equal to 0.
"""
raise NotImplementedError

def get_reboot_cause(self):
rameshraghupathy marked this conversation as resolved.
Show resolved Hide resolved
"""
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):
rameshraghupathy marked this conversation as resolved.
Show resolved Hide resolved
rameshraghupathy marked this conversation as resolved.
Show resolved Hide resolved
"""
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'
rameshraghupathy marked this conversation as resolved.
Show resolved Hide resolved
}
}
"""
raise NotImplementedError

##############################################
# Component methods
##############################################
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand Down
5 changes: 5 additions & 0 deletions tests/chassis_base_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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)
Expand Down
19 changes: 19 additions & 0 deletions tests/module_base_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Loading