Skip to content

Commit a3df22e

Browse files
authored
[SONiCBMC] Add updates for platform API's to support leak sensor and switch host power control (#634)
* Add updates for platform API's to support leak sensor and switch host power control * Add MODULE_TYPE_SWITCH_HOST type to module_base * Update the LeakSeverity as Enum * Add an API is_bmc() from PR #647
1 parent eae91cf commit a3df22e

6 files changed

Lines changed: 549 additions & 7 deletions

File tree

sonic_platform_base/chassis_base.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,16 @@ def is_modular_chassis(self):
158158
"""
159159
return False
160160

161+
def is_bmc(self):
162+
"""
163+
Retrieves whether the sonic instance is a BMC
164+
165+
Returns:
166+
A bool value, should return False by default. BMC card instances
167+
running SONiC should return True
168+
"""
169+
return False
170+
161171
def init_midplane_switch(self):
162172
"""
163173
Initializes the midplane functionality of the modular chassis. For
@@ -247,6 +257,9 @@ def get_module(self, index):
247257
Retrieves module represented by (0-based) index <index>
248258
On a SmartSwitch index:0 will fetch DPU0 and so on
249259
260+
In case of a Switch modelled as a chassis with BMC card,
261+
On BMC : index 0 will fetch SWITCH-HOST
262+
250263
Args:
251264
index: An integer, the index (0-based) of the module to
252265
retrieve
@@ -273,6 +286,7 @@ def get_module_index(self, module_name):
273286
module_name: A string, prefixed by SUPERVISOR, LINE-CARD or FABRIC-CARD
274287
Ex. SUPERVISOR0, LINE-CARD1, FABRIC-CARD5
275288
SmartSwitch Example: DPU0, DPU1, DPU2 ... DPUX
289+
In case of a Switch modelled as a chassis with BMC card: SWITCH-HOST
276290
277291
Returns:
278292
An integer, the index of the ModuleBase object in the module_list

sonic_platform_base/liquid_cooling_base.py

Lines changed: 78 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,33 +5,107 @@
55
to interact with a liquid cooling module in SONiC
66
"""
77

8+
from enum import Enum
89
from . import device_base
910
from .sensor_base import SensorBase
1011
import sys
1112

13+
14+
class LeakSeverity(Enum):
15+
MINOR = "MINOR"
16+
CRITICAL = "CRITICAL"
17+
18+
1219
class LeakageSensorBase(SensorBase):
20+
# Keep string aliases for backwards compatibility
21+
LEAK_SEVERITY_CRITICAL = LeakSeverity.CRITICAL
22+
LEAK_SEVERITY_MINOR = LeakSeverity.MINOR
23+
1324
def __init__(self, name):
1425
self.name = name
1526
self.leaking = False
27+
self.leak_sensor_ok = True
28+
self.leak_type = None
29+
self.leak_location = None
30+
self.leak_severity = None
1631

1732
def get_name(self):
1833
"""
1934
Retrieves the name of the leakage sensor
2035
2136
Returns:
22-
tring: the name of the leakage sensor
23-
"""
37+
string: the name of the leakage sensor
38+
"""
2439
return self.name
2540

2641
def is_leak(self):
2742
"""
28-
Retrieves the leak status of the sensor
43+
Retrieves the leak status of the sensor.
44+
The platform should apply debounce logic before reporting/clearing leak.
2945
3046
Returns:
3147
bool: True if leak is detected, False if not
32-
"""
48+
"""
3349
return self.leaking
3450

51+
def is_leak_sensor_ok(self):
52+
"""
53+
Retrieves the state of leak sensor whether it is ok or faulty
54+
55+
Returns:
56+
bool: True if leak sensor is ok, False if it is faulty
57+
"""
58+
return self.leak_sensor_ok
59+
60+
def get_leak_sensor_type(self):
61+
"""
62+
Retrieves the leak sensor type
63+
64+
Returns:
65+
string: the type of the leakage sensor
66+
"""
67+
return self.leak_type
68+
69+
def get_leak_sensor_location(self):
70+
"""
71+
Retrieves the location of leak sensor
72+
73+
Returns:
74+
string: the location of the leakage sensor
75+
"""
76+
return self.leak_location
77+
78+
def get_leak_severity(self):
79+
"""
80+
Retrieves the severity of leak
81+
82+
Returns:
83+
LeakSeverity: LeakSeverity.CRITICAL or LeakSeverity.MINOR, or None if no leak
84+
"""
85+
return self.leak_severity
86+
87+
def get_leak_profile(self):
88+
"""
89+
Returns the leak sensor profile associated with this sensor.
90+
"""
91+
raise NotImplementedError
92+
93+
94+
class LeakSensorProfileBase(object):
95+
"""
96+
Platform-specific leak sensor profile, which defines APIs pre leaksensor type
97+
"""
98+
99+
def get_leak_max_minor_duration_sec(self):
100+
"""
101+
Maximum time before a minor leak is marked critical.
102+
103+
Returns:
104+
int: time in seconds
105+
"""
106+
raise NotImplementedError
107+
108+
35109
class LiquidCoolingBase(device_base.DeviceBase):
36110
"""
37111
Base class for implementing liquid cooling system

sonic_platform_base/module_base.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ class ModuleBase(device_base.DeviceBase):
3636
MODULE_TYPE_FABRIC = "FABRIC-CARD"
3737
MODULE_TYPE_DPU = "DPU"
3838

39+
# Module Type for Switch on a device having BMC(which controls switch power state)
40+
MODULE_TYPE_SWITCH_HOST = "SWITCH-HOST"
41+
3942
# Possible card status for modular chassis
4043
# Module state is Empty if no module is inserted in the slot
4144
MODULE_STATUS_EMPTY = "Empty"
@@ -173,6 +176,8 @@ def get_name(self):
173176
Retrieves the name of the module prefixed by SUPERVISOR, LINE-CARD,
174177
FABRIC-CARD, DPU0, DPUX
175178
179+
It can return name 'SWITCH-HOST' for module type MODULE_TYPE_SWITCH_HOST
180+
176181
Returns:
177182
A string, the module name prefixed by one of MODULE_TYPE_SUPERVISOR,
178183
MODULE_TYPE_LINE or MODULE_TYPE_FABRIC or MODULE_TYPE_DPU and followed
@@ -209,8 +214,8 @@ def get_type(self):
209214
210215
Returns:
211216
A string, the module-type from one of the predefined types:
212-
MODULE_TYPE_SUPERVISOR, MODULE_TYPE_LINE or MODULE_TYPE_FABRIC
213-
or MODULE_TYPE_DPU
217+
MODULE_TYPE_SUPERVISOR, MODULE_TYPE_LINE, MODULE_TYPE_FABRIC,
218+
MODULE_TYPE_DPU, or MODULE_TYPE_SWITCH_HOST
214219
"""
215220
raise NotImplementedError
216221

@@ -260,6 +265,15 @@ def set_admin_state(self, up):
260265
"""
261266
raise NotImplementedError
262267

268+
def do_power_cycle(self):
269+
"""
270+
Request to do a powercycle of the module.
271+
272+
Returns:
273+
bool: True if the request has been issued successfully, False if not
274+
"""
275+
raise NotImplementedError
276+
263277
def get_maximum_consumed_power(self):
264278
"""
265279
Retrives the maximum power drawn by this module

tests/chassis_base_test.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,34 @@ def test_get_bmc(self):
6565
mock_bmc = "mock_bmc_instance"
6666
chassis._bmc = mock_bmc
6767
assert(chassis.get_bmc() == mock_bmc)
68+
69+
def test_is_bmc(self):
70+
chassis = ChassisBase()
71+
assert chassis.is_bmc() is False
72+
73+
class BmcChassis(ChassisBase):
74+
def is_bmc(self):
75+
return True
76+
77+
bmc = BmcChassis()
78+
assert bmc.is_bmc() is True
79+
80+
def test_switch_host_module_at_index_zero(self):
81+
'''
82+
On a BMC chassis, only the Switch-Host is modelled as a module.
83+
get_all_modules() returns [switch_host] and index 0 fetches it.
84+
get_module_index() maps the Switch-Host name back to index 0.
85+
'''
86+
from sonic_platform_base.module_base import ModuleBase
87+
88+
class SwitchHostModule(ModuleBase):
89+
def get_name(self):
90+
return ModuleBase.MODULE_TYPE_SWITCH_HOST
91+
92+
switch_host = SwitchHostModule()
93+
chassis = ChassisBase()
94+
chassis._module_list = [switch_host]
95+
96+
assert chassis.get_num_modules() == 1
97+
assert chassis.get_all_modules() == [switch_host]
98+
assert chassis.get_module(0) is switch_host

0 commit comments

Comments
 (0)