Skip to content

Commit

Permalink
Add new platform management API. Currently with support for chassis, …
Browse files Browse the repository at this point in the history
…PSUs, fans and watchdog (sonic-net#13)
  • Loading branch information
jleveque authored Dec 4, 2018
1 parent 0d1622a commit d4bf78c
Show file tree
Hide file tree
Showing 9 changed files with 633 additions and 0 deletions.
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
packages=[
'sonic_eeprom',
'sonic_led',
'sonic_platform_base',
'sonic_psu',
'sonic_sfp',
],
Expand Down
Empty file added sonic_platform_base/__init__.py
Empty file.
223 changes: 223 additions & 0 deletions sonic_platform_base/chassis_base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
#
# chassis_base.py
#
# Base class for implementing a platform-specific class with which
# to interact with a chassis device in SONiC.
#

import sys
from . import device_base


class ChassisBase(device_base.DeviceBase):
"""
Base class for interfacing with a platform chassis
"""

# Possible reboot causes
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 = "insufficient_fan"
REBOOT_CAUSE_WATCHDOG = "watchdog"
REBOOT_CAUSE_HARDWARE_OTHER = "hardware_other"
REBOOT_CAUSE_NON_HARDWARE = "non_hardware"

# List of ModuleBase-derived objects representing all modules
# available on the chassis (for use with modular chassis)
_module_list = []

# List of FanBase-derived objects representing all fans
# available on the chassis
_fan_list = []

# List of PsuBase-derived objects representing all power supply units
# available on the chassis
_psu_list = []

# Object derived from WatchdogBase for interacting with hardware watchdog
_watchdog = 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'
"""
raise NotImplementedError

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

def get_component_versions(self):
"""
Retrieves platform-specific hardware/firmware versions for chassis
componenets such as BIOS, CPLD, FPGA, etc.
Returns:
A string containing platform-specific component versions
"""
raise NotImplementedError

##############################################
# Module methods
##############################################

def get_num_modules(self):
"""
Retrieves the number of modules available on this chassis
Returns:
An integer, the number of modules available on this chassis
"""
return len(self._module_list)

def get_all_modules(self):
"""
Retrieves all modules available on this chassis
Returns:
A list of objects derived from ModuleBase representing all
modules available on this chassis
"""
return self._module_list

def get_module(self, index):
"""
Retrieves module represented by (0-based) index <index>
Args:
index: An integer, the index (0-based) of the module to
retrieve
Returns:
An object dervied from ModuleBase representing the specified
module
"""
module = None

try:
module = self._module_list[index]
except IndexError:
sys.stderr.write("Module index {} out of range (0-{})\n".format(
index, len(self._module_list)-1))

return module

##############################################
# Fan methods
##############################################

def get_num_fans(self):
"""
Retrieves the number of fans available on this chassis
Returns:
An integer, the number of fan modules available on this chassis
"""
return len(self._fan_list)

def get_all_fans(self):
"""
Retrieves all fan modules available on this chassis
Returns:
A list of objects derived from FanBase representing all fan
modules available on this chassis
"""
return self._fan_list

def get_fan(self, index):
"""
Retrieves fan module represented by (0-based) index <index>
Args:
index: An integer, the index (0-based) of the fan module to
retrieve
Returns:
An object dervied from FanBase representing the specified fan
module
"""
fan = None

try:
fan = self._fan_list[index]
except IndexError:
sys.stderr.write("Fan index {} out of range (0-{})\n".format(
index, len(self._fan_list)-1))

return fan

##############################################
# PSU methods
##############################################

def get_num_psus(self):
"""
Retrieves the number of power supply units available on this chassis
Returns:
An integer, the number of power supply units available on this
chassis
"""
return len(self._psu_list)

def get_all_psus(self):
"""
Retrieves all power supply units available on this chassis
Returns:
A list of objects derived from PsuBase representing all power
supply units available on this chassis
"""
return self._psu_list

def get_psu(self, index):
"""
Retrieves power supply unit represented by (0-based) index <index>
Args:
index: An integer, the index (0-based) of the power supply unit to
retrieve
Returns:
An object dervied from PsuBase representing the specified power
supply unit
"""
psu = None

try:
psu = self._psu_list[index]
except IndexError:
sys.stderr.write("PSU index {} out of range (0-{})\n".format(
index, len(self._psu_list)-1))

return psu

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

def get_watchdog(self):
"""
Retreives hardware watchdog device on this chassis
Returns:
An object derived from WatchdogBase representing the hardware
watchdog device
"""
return _watchdog
66 changes: 66 additions & 0 deletions sonic_platform_base/device_base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#
# device_base.py
#
# Abstract base class for interfacing with a generic type of platform
# peripheral device in SONiC
#

class DeviceBase(object):
"""
Abstract base class for interfacing with a generic type of platform
peripheral device
"""

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

def get_model(self):
"""
Retrieves the model number (or part number) of the device
Returns:
string: Model/part number of device
"""
raise NotImplementedError

def get_serial(self):
"""
Retrieves the serial number of the device
Returns:
string: Serial number of device
"""
raise NotImplementedError

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

def get_change_event(self, timeout=0):
"""
Returns a dictionary containing all devices which have experienced a
change
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;
- Dict where key is device ID and value is device event,
status='1' represents device inserted,
status='0' represents device removed. Ex. {'0': '1', '1': '0'}
"""
raise NotImplementedError
89 changes: 89 additions & 0 deletions sonic_platform_base/fan_base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#
# fan_base.py
#
# Abstract base class for implementing a platform-specific class with which
# to interact with a fan module in SONiC
#

from . import device_base


class FanBase(device_base.DeviceBase):
"""
Abstract base class for interfacing with a fan module
"""

# Possible fan directions (relative to port-side of device)
FAN_DIRECTION_INTAKE = "intake"
FAN_DIRECTION_EXHAUST = "exhaust"

# Possible fan status LED colors
STATUS_LED_COLOR_GREEN = "green"
STATUS_LED_COLOR_RED = "red"
STATUS_LED_COLOR_OFF = "off"

def get_direction(self):
"""
Retrieves the direction of fan
Returns:
A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST
depending on fan direction
"""
raise NotImplementedError

def get_speed(self):
"""
Retrieves the speed of fan as a percentage of full speed
Returns:
An integer, the percentage of full fan speed, in the range 0 (off)
to 100 (full speed)
"""
raise NotImplementedError

def get_target_speed(self):
"""
Retrieves the target (expected) speed of the fan
Returns:
An integer, the percentage of full fan speed, in the range 0 (off)
to 100 (full speed)
"""
raise NotImplementedError

def get_speed_tolerance(self):
"""
Retrieves the speed tolerance of the fan
Returns:
An integer, the percentage of variance from target speed which is
considered tolerable
"""
raise NotImplementedError

def set_speed(self, speed):
"""
Sets the fan speed
Args:
speed: An integer, the percentage of full fan speed to set fan to,
in the range 0 (off) to 100 (full speed)
Returns:
A boolean, True if speed is set successfully, False if not
"""
raise NotImplementedError

def set_status_led(self, color):
"""
Sets the state of the fan module status LED
Args:
color: A string representing the color with which to set the
fan module status LED
Returns:
bool: True if status LED state is set successfully, False if not
"""
raise NotImplementedError
Loading

0 comments on commit d4bf78c

Please sign in to comment.