diff --git a/releasenotes/notes/add-system-bootprogress-42ee452cfa279c63.yaml b/releasenotes/notes/add-system-bootprogress-42ee452cfa279c63.yaml new file mode 100644 index 00000000..f72a2759 --- /dev/null +++ b/releasenotes/notes/add-system-bootprogress-42ee452cfa279c63.yaml @@ -0,0 +1,10 @@ +--- +features: + - | + Adds a ``boot_progress`` mapped object to the System object. Inside of + this object, a ``last_state`` value maps to values provided by the + ``sushy.BootProgressState`` enum. + Also exposes, for information purposes, the ``last_boot_seconds_count``, + ``last_state_updated_at``, and ``oem_last_state`` values, which map to + the DMTF Redfish values ``LastBootTimeSeconds``, ``LastStateTime``, + and ``OemLastState`` fields for the ``BootProgress`` object. diff --git a/sushy/resources/system/constants.py b/sushy/resources/system/constants.py index 262de3d2..49e577ba 100644 --- a/sushy/resources/system/constants.py +++ b/sushy/resources/system/constants.py @@ -165,6 +165,44 @@ BOOT_SOURCE_ENABLED_ONCE = BootSourceOverrideEnabled.ONCE BOOT_SOURCE_ENABLED_CONTINUOUS = BootSourceOverrideEnabled.CONTINUOUS +class BootProgressStates(enum.Enum): + """Boot System Progress Indicator constants""" + # Added in ComputerSystem 1.15.0 + + NONE = 'None' + """The system is not booting.""" + + PRIMARY_PROCESSOR = 'PrimaryProcessorInitializationStarted' + """Initialization of the Primary Processor has started.""" + + BUS = 'BusInitializationStarted' + """Initalization of the buses has started.""" + + MEMORY = 'MemoryInitializationStarted' + """Initalization of memory has started.""" + + SECONDARY_PROCESSOR = 'SecondaryProcessorInitializationStarted' + """Secondary Prcessors have started initialization.""" + + PCI_RESOURCE_CONFIG = 'PCIResourceConfigStarted' + """Initalizatoin of PCI Resources has started.""" + + HARDWARE_COMPLETE = 'SystemHardwareInitializationComplete' + """Hardware Initialization is completed.""" + + SETUP = 'SetupEntered' + """System is in the Setup utility.""" + + OS_BOOT_STARTED = 'OSBootStarted' + """Boot of the Operating Sysem has started.""" + + OS_RUNNING = 'OSRunning' + """Operating System Running.""" + + OEM = 'OEM' + """OEM Defined Boot Progress State.""" + + class SystemType(enum.Enum): """System type constants""" diff --git a/sushy/resources/system/system.py b/sushy/resources/system/system.py index e06f277d..a98ad06b 100644 --- a/sushy/resources/system/system.py +++ b/sushy/resources/system/system.py @@ -19,6 +19,8 @@ import collections import logging +from dateutil import parser + from sushy import exceptions from sushy.resources import base from sushy.resources.chassis import chassis @@ -59,6 +61,23 @@ class BootField(base.CompositeField): http_boot_uri = base.Field('HttpBootUri') +class BootProgressField(base.CompositeField): + + last_boot_seconds_count = base.Field('LastBootTimeSeconds', + adapter=utils.int_or_none) + """The number of seconds the last boot took to reach OSRunning.""" + + last_state = base.MappedField('LastState', sys_cons.BootProgressStates) + """The last recorded boot progress states.""" + + last_state_updated_at = base.Field('LastStateTime', + adapter=parser.parse) + """The date-time value when the last state field was updated.""" + + oem_last_state = base.Field('OemLastState') + """The OEM last state time to describe OEM specific state information.""" + + class MemorySummaryField(base.CompositeField): health = base.Field(['Status', 'HealthRollup']) """The overall health state of memory. @@ -140,6 +159,9 @@ class System(base.ResourceBase): _actions = ActionsField('Actions', required=True) + boot_progress = BootProgressField('BootProgress') + """The last updated boot progress indicator""" + def __init__(self, connector, identity, redfish_version=None, registries=None, root=None): """A class representing a ComputerSystem diff --git a/sushy/tests/unit/json_samples/system.json b/sushy/tests/unit/json_samples/system.json index 9e4f075c..b6e19f9f 100644 --- a/sushy/tests/unit/json_samples/system.json +++ b/sushy/tests/unit/json_samples/system.json @@ -43,6 +43,12 @@ "UefiTargetBootSourceOverride": "/0x31/0x33/0x01/0x01", "HttpBootUri": "https://Contoso.lan/boot.iso" }, + "BootProgress": { + "LastBootTimeSeconds": 66, + "LastState": "OSRunning", + "LastStateTime": "2017-05-03T23:12:37-05:00", + "OemLastState": "OS foo running." + }, "TrustedModules": [ { "FirmwareVersion": "1.13b", diff --git a/sushy/tests/unit/resources/system/test_system.py b/sushy/tests/unit/resources/system/test_system.py index 8ec96fc4..0731ce03 100644 --- a/sushy/tests/unit/resources/system/test_system.py +++ b/sushy/tests/unit/resources/system/test_system.py @@ -82,6 +82,14 @@ class SystemTestCase(base.TestCase): .maintenance_window_start_time) for oem_vendor in self.sys_inst.oem_vendors: self.assertIn(oem_vendor, ('Contoso', 'Chipwise')) + self.assertEqual(sushy.BootProgressStates.OS_RUNNING, + self.sys_inst.boot_progress.last_state) + self.assertEqual(66, + self.sys_inst.boot_progress.last_boot_seconds_count) + self.assertEqual(parser.parse('2017-05-03T23:12:37-05:00'), + self.sys_inst.boot_progress.last_state_updated_at) + self.assertEqual("OS foo running.", + self.sys_inst.boot_progress.oem_last_state) def test__parse_attributes_return(self): attributes = self.sys_inst._parse_attributes(self.json_doc)