#!/usr/bin/env python3 r""" State Manager module: - Defines Valid states of the system """ import os import re import sys from robot.libraries.BuiltIn import BuiltIn robot_pgm_dir_path = os.path.dirname(__file__) + os.sep repo_data_dir_path = re.sub("/lib", "/data", robot_pgm_dir_path) sys.path.append(repo_data_dir_path) import gen_robot_keyword as keyword # NOQA import variables as var # NOQA BuiltIn().import_resource("state_manager.robot") BuiltIn().import_resource("rest_client.robot") platform_arch_type = os.environ.get( "PLATFORM_ARCH_TYPE", "" ) or BuiltIn().get_variable_value("${PLATFORM_ARCH_TYPE}", default="power") # We will build eventually the mapping for warm, cold reset as well. VALID_STATES = { "reboot": { # (Power Policy, BMC state, Chassis State, Host State) ("LEAVE_OFF", "Ready", "Off", "Off"), ("ALWAYS_POWER_ON", "Ready", "On", "Running"), ("ALWAYS_POWER_ON", "Ready", "On", "Off"), ("RESTORE_LAST_STATE", "Ready", "On", "Running"), ("RESTORE_LAST_STATE", "Ready", "On", "Off"), ("ALWAYS_POWER_OFF", "Ready", "On", "Running"), ("ALWAYS_POWER_OFF", "Ready", "Off", "Off"), }, } VALID_BOOT_STATES = { "Off": { # Valid states when Host is Off. # (BMC , Chassis , Host , BootProgress, OperatingSystemState) ( "xyz.openbmc_project.State.BMC.BMCState.Ready", "xyz.openbmc_project.State.Chassis.PowerState.Off", "xyz.openbmc_project.State.Host.HostState.Off", "xyz.openbmc_project.State.Boot.Progress.ProgressStages.Unspecified", "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus.Inactive", ), }, "Reboot": { # Valid states when BMC reset to standby. # (BMC , Chassis , Host , BootProgress, OperatingSystemState) ( "xyz.openbmc_project.State.BMC.BMCState.Ready", "xyz.openbmc_project.State.Chassis.PowerState.Off", "xyz.openbmc_project.State.Host.HostState.Off", "xyz.openbmc_project.State.Boot.Progress.ProgressStages.Unspecified", "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus.Inactive", ), }, "Running": { # Valid states when Host is powering on. # (BMC , Chassis , Host , BootProgress, OperatingSystemState) ( "xyz.openbmc_project.State.BMC.BMCState.Ready", "xyz.openbmc_project.State.Chassis.PowerState.On", "xyz.openbmc_project.State.Host.HostState.Running", "xyz.openbmc_project.State.Boot.Progress.ProgressStages.MotherboardInit", "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus.Inactive", ), }, "Booted": { # Valid state when Host is booted. # (BMC , Chassis , Host , BootProgress, OperatingSystemState) ( "xyz.openbmc_project.State.BMC.BMCState.Ready", "xyz.openbmc_project.State.Chassis.PowerState.On", "xyz.openbmc_project.State.Host.HostState.Running", "xyz.openbmc_project.State.Boot.Progress.ProgressStages.OSStart", "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus.BootComplete", ), }, "ResetReload": { # Valid state BMC reset reload when host is booted. # (BMC , Chassis , Host , BootProgress, OperatingSystemState) ( "xyz.openbmc_project.State.BMC.BMCState.Ready", "xyz.openbmc_project.State.Chassis.PowerState.On", "xyz.openbmc_project.State.Host.HostState.Running", "xyz.openbmc_project.State.Boot.Progress.ProgressStages.OSStart", "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus.BootComplete", ), }, } REDFISH_VALID_BOOT_STATES = { "Off": { # Valid states when Host is Off. # (BMC , Chassis , Host , BootProgress) ( "Enabled", "Off", "Disabled", "None", ), }, "Reboot": { # Valid states when BMC reset to standby. # (BMC , Chassis , Host , BootProgress) ( "Enabled", "Off", "Disabled", "None", ), }, "Running": { # Valid states when Host is powering on. # (BMC , Chassis , Host , BootProgress) ( "Enabled", "On", "Enabled", "OSRunning", ), }, "Booted": { # Valid state when Host is booted. # (BMC , Chassis , Host , BootProgress) ( "Enabled", "On", "Enabled", "OSRunning", ), }, "ResetReload": { # Valid state BMC reset reload when host is booted. # (BMC , Chassis , Host , BootProgress) ( "Enabled", "On", "Enabled", "OSRunning", ), }, } if platform_arch_type == "x86": VALID_BOOT_STATES_X86 = {} for state_name, state_set in VALID_BOOT_STATES.items(): VALID_BOOT_STATES_X86[state_name] = set() for state_tuple in state_set: state_tuple_new = tuple( x for x in state_tuple if not ( x.startswith("xyz.openbmc_project.State.Boot.Progress") or x.startswith( "xyz.openbmc_project.State.OperatingSystem" ) ) ) VALID_BOOT_STATES_X86[state_name].add(state_tuple_new) VALID_BOOT_STATES = VALID_BOOT_STATES_X86 class state_map: def get_boot_state(self): r""" Return the system state as a tuple of bmc, chassis, host state, BootProgress and OperatingSystemState. """ status, state = keyword.run_key( "Read Properties " + var.SYSTEM_STATE_URI + "enumerate" ) bmc_state = state[var.SYSTEM_STATE_URI + "bmc0"]["CurrentBMCState"] chassis_state = state[var.SYSTEM_STATE_URI + "chassis0"][ "CurrentPowerState" ] host_state = state[var.SYSTEM_STATE_URI + "host0"]["CurrentHostState"] if platform_arch_type == "x86": return (str(bmc_state), str(chassis_state), str(host_state)) else: boot_state = state[var.SYSTEM_STATE_URI + "host0"]["BootProgress"] os_state = state[var.SYSTEM_STATE_URI + "host0"][ "OperatingSystemState" ] return ( str(bmc_state), str(chassis_state), str(host_state), str(boot_state), str(os_state), ) def valid_boot_state(self, boot_type, state_set): r""" Validate a given set of states is valid. Description of argument(s): boot_type Boot type (e.g. off/running/host booted etc.) state_set State set (e.g.bmc,chassis,host, BootProgress,OperatingSystemState) """ if state_set in set(VALID_BOOT_STATES[boot_type]): return True else: return False def redfish_valid_boot_state(self, boot_type, state_dict): r""" Validate a given set of states is valid. Description of argument(s): boot_type Boot type (e.g. off/running/host booted etc.) state_dict State dictionary. """ if set(state_dict.values()) in set( REDFISH_VALID_BOOT_STATES[boot_type] ): return True else: return False