1e7e9171eSGeorge Keishing#!/usr/bin/env python3 270369fdcSMichael Walsh 370369fdcSMichael Walshr""" 470369fdcSMichael WalshThis module contains functions having to do with machine state: get_state, 570369fdcSMichael Walshcheck_state, wait_state, etc. 670369fdcSMichael Walsh 770369fdcSMichael WalshThe 'State' is a composite of many pieces of data. Therefore, the functions 870369fdcSMichael Walshin this module define state as an ordered dictionary. Here is an example of 970369fdcSMichael Walshsome test output showing machine state: 1070369fdcSMichael Walsh 11341c21ebSMichael Walshdefault_state: 1265b12540SMichael Walsh default_state[chassis]: On 1301975fa8SMichael Walsh default_state[boot_progress]: OSStart 145674922eSMichael Walsh default_state[operating_system]: BootComplete 1565b12540SMichael Walsh default_state[host]: Running 16341c21ebSMichael Walsh default_state[os_ping]: 1 17341c21ebSMichael Walsh default_state[os_login]: 1 18341c21ebSMichael Walsh default_state[os_run_cmd]: 1 1970369fdcSMichael Walsh 2070369fdcSMichael WalshDifferent users may very well have different needs when inquiring about 218fae6eaeSMichael Walshstate. Support for new pieces of state information may be added to this 228fae6eaeSMichael Walshmodule as needed. 2370369fdcSMichael Walsh 2470369fdcSMichael WalshBy using the wait_state function, a caller can start a boot and then wait for 2570369fdcSMichael Walsha precisely defined state to indicate that the boot has succeeded. If 2670369fdcSMichael Walshthe boot fails, they can see exactly why by looking at the current state as 2770369fdcSMichael Walshcompared with the expected state. 2870369fdcSMichael Walsh""" 2970369fdcSMichael Walsh 30*139f1da6SBrian Maimport importlib.util 3120f38712SPatrick Williamsimport os 3220f38712SPatrick Williamsimport re 3320f38712SPatrick Williamsimport sys 34e635ddc0SGeorge Keishing 3520f38712SPatrick Williamsimport bmc_ssh_utils as bsu 3620f38712SPatrick Williamsimport gen_cmd as gc 3720f38712SPatrick Williamsimport gen_print as gp 3820f38712SPatrick Williamsimport gen_robot_utils as gru 3920f38712SPatrick Williamsimport gen_valid as gv 4070369fdcSMichael Walshfrom robot.libraries.BuiltIn import BuiltIn 41341c21ebSMichael Walshfrom robot.utils import DotDict 4270369fdcSMichael Walsh 435a5868aaSMichael Walsh# NOTE: Avoid importing utils.robot because utils.robot imports state.py 445a5868aaSMichael Walsh# (indirectly) which will cause failures. 455a5868aaSMichael Walshgru.my_import_resource("rest_client.robot") 4670369fdcSMichael Walsh 4720f38712SPatrick Williamsbase_path = ( 48*139f1da6SBrian Ma os.path.dirname( 49*139f1da6SBrian Ma os.path.dirname(importlib.util.find_spec("gen_robot_print").origin) 50*139f1da6SBrian Ma ) 5120f38712SPatrick Williams + os.sep 5220f38712SPatrick Williams) 535674922eSMichael Walshsys.path.append(base_path + "data/") 545674922eSMichael Walsh 55940d6914SMichael Walsh# Previously, I had this coded: 56940d6914SMichael Walsh# import variables as var 57940d6914SMichael Walsh# However, we ran into a problem where a robot program did this... 58940d6914SMichael Walsh# Variables ../../lib/ras/variables.py 59940d6914SMichael Walsh# Prior to doing this... 60940d6914SMichael Walsh# Library ../lib/state.py 61940d6914SMichael Walsh 62940d6914SMichael Walsh# This caused the wrong variables.py file to be selected. Attempts to fix this 63940d6914SMichael Walsh# have failed so far. For the moment, we will hard-code the value we need from 64940d6914SMichael Walsh# the file. 65940d6914SMichael Walsh 66940d6914SMichael WalshSYSTEM_STATE_URI = "/xyz/openbmc_project/state/" 675674922eSMichael Walsh 688fae6eaeSMichael Walsh# The BMC code has recently been changed as far as what states are defined and 698fae6eaeSMichael Walsh# what the state values can be. This module now has a means of processing both 708fae6eaeSMichael Walsh# the old style state (i.e. OBMC_STATES_VERSION = 0) and the new style (i.e. 7116cbb7f7SMichael Walsh# OBMC_STATES_VERSION = 1). 72341c21ebSMichael Walsh# The caller can set environment variable OBMC_STATES_VERSION to dictate 73341c21ebSMichael Walsh# whether we're processing old or new style states. If OBMC_STATES_VERSION is 748fae6eaeSMichael Walsh# not set it will default to 1. 75341c21ebSMichael Walsh 76619aa332SMichael Walsh# As of the present moment, OBMC_STATES_VERSION of 0 is for cold that is so old 77619aa332SMichael Walsh# that it is no longer worthwhile to maintain. The OBMC_STATES_VERSION 0 code 78619aa332SMichael Walsh# is being removed but the OBMC_STATES_VERSION value will stay for now in the 79619aa332SMichael Walsh# event that it is needed in the future. 80619aa332SMichael Walsh 8120f38712SPatrick WilliamsOBMC_STATES_VERSION = int(os.environ.get("OBMC_STATES_VERSION", 1)) 82341c21ebSMichael Walsh 8320f38712SPatrick Williamsredfish_support_trans_state = int( 8420f38712SPatrick Williams os.environ.get("REDFISH_SUPPORT_TRANS_STATE", 0) 8520f38712SPatrick Williams) or int( 8620f38712SPatrick Williams BuiltIn().get_variable_value("${REDFISH_SUPPORT_TRANS_STATE}", default=0) 8720f38712SPatrick Williams) 88da40c1d2SMichael Shepos 8920f38712SPatrick Williamsplatform_arch_type = os.environ.get( 9020f38712SPatrick Williams "PLATFORM_ARCH_TYPE", "" 9120f38712SPatrick Williams) or BuiltIn().get_variable_value("${PLATFORM_ARCH_TYPE}", default="power") 921e2fbee9SGeorge Keishing 93bdd1dceaSMichael Shepos# valid_os_req_states and default_os_req_states are used by the os_get_state 94bdd1dceaSMichael Shepos# function. 95bdd1dceaSMichael Shepos# valid_os_req_states is a list of state information supported by the 96bdd1dceaSMichael Shepos# get_os_state function. 9720f38712SPatrick Williamsvalid_os_req_states = ["os_ping", "os_login", "os_run_cmd"] 98bdd1dceaSMichael Shepos 99bdd1dceaSMichael Shepos# When a user calls get_os_state w/o specifying req_states, 100bdd1dceaSMichael Shepos# default_os_req_states is used as its value. 10120f38712SPatrick Williamsdefault_os_req_states = ["os_ping", "os_login", "os_run_cmd"] 102bdd1dceaSMichael Shepos 103bdd1dceaSMichael Shepos# Presently, some BMCs appear to not keep time very well. This environment 104bdd1dceaSMichael Shepos# variable directs the get_state function to use either the BMC's epoch time 105bdd1dceaSMichael Shepos# or the local epoch time. 10620f38712SPatrick WilliamsUSE_BMC_EPOCH_TIME = int(os.environ.get("USE_BMC_EPOCH_TIME", 0)) 107bdd1dceaSMichael Shepos 108bdd1dceaSMichael Shepos# Useful state constant definition(s). 109bdd1dceaSMichael Sheposif not redfish_support_trans_state: 1108fae6eaeSMichael Walsh # When a user calls get_state w/o specifying req_states, default_req_states 1118fae6eaeSMichael Walsh # is used as its value. 11220f38712SPatrick Williams default_req_states = [ 11320f38712SPatrick Williams "rest", 11420f38712SPatrick Williams "chassis", 11520f38712SPatrick Williams "bmc", 11620f38712SPatrick Williams "boot_progress", 11720f38712SPatrick Williams "operating_system", 11820f38712SPatrick Williams "host", 11920f38712SPatrick Williams "os_ping", 12020f38712SPatrick Williams "os_login", 12120f38712SPatrick Williams "os_run_cmd", 12220f38712SPatrick Williams ] 1238fae6eaeSMichael Walsh 124619aa332SMichael Walsh # valid_req_states is a list of sub states supported by the get_state function. 125619aa332SMichael Walsh # valid_req_states, default_req_states and master_os_up_match are used by the 1268fae6eaeSMichael Walsh # get_state function. 127da40c1d2SMichael Shepos 12820f38712SPatrick Williams valid_req_states = [ 12920f38712SPatrick Williams "ping", 13020f38712SPatrick Williams "packet_loss", 13120f38712SPatrick Williams "uptime", 13220f38712SPatrick Williams "epoch_seconds", 13320f38712SPatrick Williams "elapsed_boot_time", 13420f38712SPatrick Williams "rest", 13520f38712SPatrick Williams "chassis", 13620f38712SPatrick Williams "requested_chassis", 13720f38712SPatrick Williams "bmc", 13820f38712SPatrick Williams "requested_bmc", 13920f38712SPatrick Williams "boot_progress", 14020f38712SPatrick Williams "operating_system", 14120f38712SPatrick Williams "host", 14220f38712SPatrick Williams "requested_host", 14320f38712SPatrick Williams "attempts_left", 14420f38712SPatrick Williams "os_ping", 14520f38712SPatrick Williams "os_login", 14620f38712SPatrick Williams "os_run_cmd", 14720f38712SPatrick Williams ] 1488fae6eaeSMichael Walsh 149619aa332SMichael Walsh # default_state is an initial value which may be of use to callers. 15020f38712SPatrick Williams default_state = DotDict( 15120f38712SPatrick Williams [ 15220f38712SPatrick Williams ("rest", "1"), 15320f38712SPatrick Williams ("chassis", "On"), 15420f38712SPatrick Williams ("bmc", "Ready"), 15520f38712SPatrick Williams ("boot_progress", "OSStart"), 15620f38712SPatrick Williams ("operating_system", "BootComplete"), 15720f38712SPatrick Williams ("host", "Running"), 15820f38712SPatrick Williams ("os_ping", "1"), 15920f38712SPatrick Williams ("os_login", "1"), 16020f38712SPatrick Williams ("os_run_cmd", "1"), 16120f38712SPatrick Williams ] 16220f38712SPatrick Williams ) 163619aa332SMichael Walsh 1647dc885b6SMichael Walsh # A match state for checking that the system is at "standby". 16520f38712SPatrick Williams standby_match_state = DotDict( 16620f38712SPatrick Williams [ 16720f38712SPatrick Williams ("rest", "^1$"), 16820f38712SPatrick Williams ("chassis", "^Off$"), 16920f38712SPatrick Williams ("bmc", "^Ready$"), 17020f38712SPatrick Williams ("boot_progress", "^Off|Unspecified$"), 17120f38712SPatrick Williams ("operating_system", "^Inactive$"), 17220f38712SPatrick Williams ("host", "^Off$"), 17320f38712SPatrick Williams ] 17420f38712SPatrick Williams ) 1757dc885b6SMichael Walsh 1767dc885b6SMichael Walsh # A match state for checking that the system is at "os running". 17720f38712SPatrick Williams os_running_match_state = DotDict( 17820f38712SPatrick Williams [ 17920f38712SPatrick Williams ("chassis", "^On$"), 18020f38712SPatrick Williams ("bmc", "^Ready$"), 18120f38712SPatrick Williams ("boot_progress", "FW Progress, Starting OS|OSStart"), 18220f38712SPatrick Williams ("operating_system", "BootComplete"), 18320f38712SPatrick Williams ("host", "^Running$"), 18420f38712SPatrick Williams ("os_ping", "^1$"), 18520f38712SPatrick Williams ("os_login", "^1$"), 18620f38712SPatrick Williams ("os_run_cmd", "^1$"), 18720f38712SPatrick Williams ] 18820f38712SPatrick Williams ) 1897dc885b6SMichael Walsh 190619aa332SMichael Walsh # A master dictionary to determine whether the os may be up. 19120f38712SPatrick Williams master_os_up_match = DotDict( 19220f38712SPatrick Williams [ 19320f38712SPatrick Williams ("chassis", "^On$"), 19420f38712SPatrick Williams ("bmc", "^Ready$"), 19520f38712SPatrick Williams ("boot_progress", "FW Progress, Starting OS|OSStart"), 19620f38712SPatrick Williams ("operating_system", "BootComplete"), 19720f38712SPatrick Williams ("host", "^Running|Quiesced$"), 19820f38712SPatrick Williams ] 19920f38712SPatrick Williams ) 200619aa332SMichael Walsh 20120f38712SPatrick Williams invalid_state_match = DotDict( 20220f38712SPatrick Williams [ 20320f38712SPatrick Williams ("rest", "^$"), 20420f38712SPatrick Williams ("chassis", "^$"), 20520f38712SPatrick Williams ("bmc", "^$"), 20620f38712SPatrick Williams ("boot_progress", "^$"), 20720f38712SPatrick Williams ("operating_system", "^$"), 20820f38712SPatrick Williams ("host", "^$"), 20920f38712SPatrick Williams ] 21020f38712SPatrick Williams ) 211da40c1d2SMichael Sheposelse: 212bdd1dceaSMichael Shepos # When a user calls get_state w/o specifying req_states, default_req_states 213bdd1dceaSMichael Shepos # is used as its value. 21420f38712SPatrick Williams default_req_states = [ 21520f38712SPatrick Williams "redfish", 21620f38712SPatrick Williams "chassis", 21720f38712SPatrick Williams "bmc", 21820f38712SPatrick Williams "boot_progress", 21920f38712SPatrick Williams "host", 22020f38712SPatrick Williams "os_ping", 22120f38712SPatrick Williams "os_login", 22220f38712SPatrick Williams "os_run_cmd", 22320f38712SPatrick Williams ] 224bdd1dceaSMichael Shepos 225bdd1dceaSMichael Shepos # valid_req_states is a list of sub states supported by the get_state function. 226bdd1dceaSMichael Shepos # valid_req_states, default_req_states and master_os_up_match are used by the 227bdd1dceaSMichael Shepos # get_state function. 228bdd1dceaSMichael Shepos 22920f38712SPatrick Williams valid_req_states = [ 23020f38712SPatrick Williams "ping", 23120f38712SPatrick Williams "packet_loss", 23220f38712SPatrick Williams "uptime", 23320f38712SPatrick Williams "epoch_seconds", 23420f38712SPatrick Williams "elapsed_boot_time", 23520f38712SPatrick Williams "redfish", 23620f38712SPatrick Williams "chassis", 23720f38712SPatrick Williams "requested_chassis", 23820f38712SPatrick Williams "bmc", 23920f38712SPatrick Williams "requested_bmc", 24020f38712SPatrick Williams "boot_progress", 24120f38712SPatrick Williams "host", 24220f38712SPatrick Williams "requested_host", 24320f38712SPatrick Williams "attempts_left", 24420f38712SPatrick Williams "os_ping", 24520f38712SPatrick Williams "os_login", 24620f38712SPatrick Williams "os_run_cmd", 24720f38712SPatrick Williams ] 248bdd1dceaSMichael Shepos 249da40c1d2SMichael Shepos # default_state is an initial value which may be of use to callers. 25020f38712SPatrick Williams default_state = DotDict( 25120f38712SPatrick Williams [ 25220f38712SPatrick Williams ("redfish", "1"), 25320f38712SPatrick Williams ("chassis", "On"), 25420f38712SPatrick Williams ("bmc", "Enabled"), 25520f38712SPatrick Williams ( 25620f38712SPatrick Williams "boot_progress", 25720f38712SPatrick Williams "SystemHardwareInitializationComplete|OSBootStarted|OSRunning", 25820f38712SPatrick Williams ), 25920f38712SPatrick Williams ("host", "Enabled"), 26020f38712SPatrick Williams ("os_ping", "1"), 26120f38712SPatrick Williams ("os_login", "1"), 26220f38712SPatrick Williams ("os_run_cmd", "1"), 26320f38712SPatrick Williams ] 26420f38712SPatrick Williams ) 265da40c1d2SMichael Shepos 266da40c1d2SMichael Shepos # A match state for checking that the system is at "standby". 26720f38712SPatrick Williams standby_match_state = DotDict( 26820f38712SPatrick Williams [ 26920f38712SPatrick Williams ("redfish", "^1$"), 27020f38712SPatrick Williams ("chassis", "^Off$"), 27120f38712SPatrick Williams ("bmc", "^Enabled$"), 27220f38712SPatrick Williams ("boot_progress", "^None$"), 27320f38712SPatrick Williams ("host", "^Disabled$"), 27420f38712SPatrick Williams ] 27520f38712SPatrick Williams ) 276da40c1d2SMichael Shepos 277da40c1d2SMichael Shepos # A match state for checking that the system is at "os running". 27820f38712SPatrick Williams os_running_match_state = DotDict( 27920f38712SPatrick Williams [ 28020f38712SPatrick Williams ("chassis", "^On$"), 28120f38712SPatrick Williams ("bmc", "^Enabled$"), 28220f38712SPatrick Williams ( 28320f38712SPatrick Williams "boot_progress", 28420f38712SPatrick Williams "SystemHardwareInitializationComplete|OSBootStarted|OSRunning", 28520f38712SPatrick Williams ), 28620f38712SPatrick Williams ("host", "^Enabled$"), 28720f38712SPatrick Williams ("os_ping", "^1$"), 28820f38712SPatrick Williams ("os_login", "^1$"), 28920f38712SPatrick Williams ("os_run_cmd", "^1$"), 29020f38712SPatrick Williams ] 29120f38712SPatrick Williams ) 292da40c1d2SMichael Shepos 293da40c1d2SMichael Shepos # A master dictionary to determine whether the os may be up. 29420f38712SPatrick Williams master_os_up_match = DotDict( 29520f38712SPatrick Williams [ 29620f38712SPatrick Williams ("chassis", "^On$"), 29720f38712SPatrick Williams ("bmc", "^Enabled$"), 29820f38712SPatrick Williams ( 29920f38712SPatrick Williams "boot_progress", 30020f38712SPatrick Williams "SystemHardwareInitializationComplete|OSBootStarted|OSRunning", 30120f38712SPatrick Williams ), 30220f38712SPatrick Williams ("host", "^Enabled$"), 30320f38712SPatrick Williams ] 30420f38712SPatrick Williams ) 305da40c1d2SMichael Shepos 30620f38712SPatrick Williams invalid_state_match = DotDict( 30720f38712SPatrick Williams [ 30820f38712SPatrick Williams ("redfish", "^$"), 30920f38712SPatrick Williams ("chassis", "^$"), 31020f38712SPatrick Williams ("bmc", "^$"), 31120f38712SPatrick Williams ("boot_progress", "^$"), 31220f38712SPatrick Williams ("host", "^$"), 31320f38712SPatrick Williams ] 31420f38712SPatrick Williams ) 31545ca6e4cSMichael Walsh 3161e2fbee9SGeorge Keishing# Filter the states based on platform type. 3171e2fbee9SGeorge Keishingif platform_arch_type == "x86": 318b51d1505SGeorge Keishing if not redfish_support_trans_state: 3191e2fbee9SGeorge Keishing default_req_states.remove("operating_system") 3201e2fbee9SGeorge Keishing valid_req_states.remove("operating_system") 3211e2fbee9SGeorge Keishing del default_state["operating_system"] 3221e2fbee9SGeorge Keishing del standby_match_state["operating_system"] 3231e2fbee9SGeorge Keishing del os_running_match_state["operating_system"] 3241e2fbee9SGeorge Keishing del master_os_up_match["operating_system"] 3251e2fbee9SGeorge Keishing del invalid_state_match["operating_system"] 326b51d1505SGeorge Keishing 327b51d1505SGeorge Keishing default_req_states.remove("boot_progress") 328b51d1505SGeorge Keishing valid_req_states.remove("boot_progress") 329b51d1505SGeorge Keishing del default_state["boot_progress"] 330b51d1505SGeorge Keishing del standby_match_state["boot_progress"] 331b51d1505SGeorge Keishing del os_running_match_state["boot_progress"] 332b51d1505SGeorge Keishing del master_os_up_match["boot_progress"] 3331e2fbee9SGeorge Keishing del invalid_state_match["boot_progress"] 3341e2fbee9SGeorge Keishing 335341c21ebSMichael Walsh 33620f38712SPatrick Williamsdef return_state_constant(state_name="default_state"): 337619aa332SMichael Walsh r""" 3387dc885b6SMichael Walsh Return the named state dictionary constant. 339619aa332SMichael Walsh """ 340619aa332SMichael Walsh 34136efbc04SGeorge Keishing return eval(state_name) 342619aa332SMichael Walsh 343619aa332SMichael Walsh 34470369fdcSMichael Walshdef anchor_state(state): 34570369fdcSMichael Walsh r""" 34670369fdcSMichael Walsh Add regular expression anchors ("^" and "$") to the beginning and end of 34770369fdcSMichael Walsh each item in the state dictionary passed in. Return the resulting 34870369fdcSMichael Walsh dictionary. 34970369fdcSMichael Walsh 3502a0df683SMichael Walsh Description of argument(s): 35170369fdcSMichael Walsh state A dictionary such as the one returned by the get_state() 35270369fdcSMichael Walsh function. 35370369fdcSMichael Walsh """ 35470369fdcSMichael Walsh 3552ce067aeSMichael Walsh anchored_state = state.copy() 3562a0df683SMichael Walsh for key in anchored_state.keys(): 35770369fdcSMichael Walsh anchored_state[key] = "^" + str(anchored_state[key]) + "$" 35870369fdcSMichael Walsh 35970369fdcSMichael Walsh return anchored_state 36070369fdcSMichael Walsh 36170369fdcSMichael Walsh 3628fae6eaeSMichael Walshdef strip_anchor_state(state): 3638fae6eaeSMichael Walsh r""" 3648fae6eaeSMichael Walsh Strip regular expression anchors ("^" and "$") from the beginning and end 3658fae6eaeSMichael Walsh of each item in the state dictionary passed in. Return the resulting 3668fae6eaeSMichael Walsh dictionary. 3678fae6eaeSMichael Walsh 3682a0df683SMichael Walsh Description of argument(s): 3698fae6eaeSMichael Walsh state A dictionary such as the one returned by the get_state() 3708fae6eaeSMichael Walsh function. 3718fae6eaeSMichael Walsh """ 3728fae6eaeSMichael Walsh 3732ce067aeSMichael Walsh stripped_state = state.copy() 3742a0df683SMichael Walsh for key in stripped_state.keys(): 3758fae6eaeSMichael Walsh stripped_state[key] = stripped_state[key].strip("^$") 3768fae6eaeSMichael Walsh 3778fae6eaeSMichael Walsh return stripped_state 3788fae6eaeSMichael Walsh 3798fae6eaeSMichael Walsh 3802a0df683SMichael Walshdef expressions_key(): 3812a0df683SMichael Walsh r""" 3822a0df683SMichael Walsh Return expressions key constant. 3832a0df683SMichael Walsh """ 38420f38712SPatrick Williams return "<expressions>" 3852a0df683SMichael Walsh 3862a0df683SMichael Walsh 38720f38712SPatrick Williamsdef compare_states(state, match_state, match_type="and"): 38870369fdcSMichael Walsh r""" 3898fae6eaeSMichael Walsh Compare 2 state dictionaries. Return True if they match and False if they 39070369fdcSMichael Walsh don't. Note that the match_state dictionary does not need to have an entry 39170369fdcSMichael Walsh corresponding to each entry in the state dictionary. But for each entry 39270369fdcSMichael Walsh that it does have, the corresponding state entry will be checked for a 39370369fdcSMichael Walsh match. 39470369fdcSMichael Walsh 3952a0df683SMichael Walsh Description of argument(s): 39670369fdcSMichael Walsh state A state dictionary such as the one returned by the 39770369fdcSMichael Walsh get_state function. 39870369fdcSMichael Walsh match_state A dictionary whose key/value pairs are "state field"/ 39970369fdcSMichael Walsh "state value". The state value is interpreted as a 40070369fdcSMichael Walsh regular expression. Every value in this dictionary is 40145ca6e4cSMichael Walsh considered. When match_type is 'and', if each and every 40245ca6e4cSMichael Walsh comparison matches, the two dictionaries are considered to 40345ca6e4cSMichael Walsh be matching. If match_type is 'or', if any two of the 40445ca6e4cSMichael Walsh elements compared match, the two dictionaries are 40545ca6e4cSMichael Walsh considered to be matching. 4062a0df683SMichael Walsh 4077dc885b6SMichael Walsh This value may also be any string accepted by 4082a0df683SMichael Walsh return_state_constant (e.g. "standby_match_state"). In 4092a0df683SMichael Walsh such a case this function will call return_state_constant 4102a0df683SMichael Walsh to convert it to a proper dictionary as described above. 4112a0df683SMichael Walsh 4122a0df683SMichael Walsh Finally, one special value is accepted for the key field: 4132a0df683SMichael Walsh expression_key(). If such an entry exists, its value is 4142a0df683SMichael Walsh taken to be a list of expressions to be evaluated. These 4152a0df683SMichael Walsh expressions may reference state dictionary entries by 4162a0df683SMichael Walsh simply coding them in standard python syntax (e.g. 4172a0df683SMichael Walsh state['key1']). What follows is an example expression: 4182a0df683SMichael Walsh 4192a0df683SMichael Walsh "int(float(state['uptime'])) < int(state['elapsed_boot_time'])" 4202a0df683SMichael Walsh 4212a0df683SMichael Walsh In this example, if the state dictionary's 'uptime' entry 4222a0df683SMichael Walsh is less than its 'elapsed_boot_time' entry, it would 4232a0df683SMichael Walsh qualify as a match. 42445ca6e4cSMichael Walsh match_type This may be 'and' or 'or'. 42570369fdcSMichael Walsh """ 42670369fdcSMichael Walsh 42720f38712SPatrick Williams error_message = gv.valid_value(match_type, valid_values=["and", "or"]) 42845ca6e4cSMichael Walsh if error_message != "": 42945ca6e4cSMichael Walsh BuiltIn().fail(gp.sprint_error(error_message)) 43045ca6e4cSMichael Walsh 43136efbc04SGeorge Keishing try: 4327dc885b6SMichael Walsh match_state = return_state_constant(match_state) 43336efbc04SGeorge Keishing except TypeError: 43436efbc04SGeorge Keishing pass 4357dc885b6SMichael Walsh 43620f38712SPatrick Williams default_match = match_type == "and" 43770369fdcSMichael Walsh for key, match_state_value in match_state.items(): 43897df71ceSMichael Walsh # Blank match_state_value means "don't care". 43997df71ceSMichael Walsh if match_state_value == "": 44097df71ceSMichael Walsh continue 4412a0df683SMichael Walsh if key == expressions_key(): 4422a0df683SMichael Walsh for expr in match_state_value: 4432a0df683SMichael Walsh # Use python interpreter to evaluate the expression. 4442a0df683SMichael Walsh match = eval(expr) 4452a0df683SMichael Walsh if match != default_match: 4462a0df683SMichael Walsh return match 4472a0df683SMichael Walsh else: 44870369fdcSMichael Walsh try: 44920f38712SPatrick Williams match = ( 45020f38712SPatrick Williams re.match(match_state_value, str(state[key])) is not None 45120f38712SPatrick Williams ) 45270369fdcSMichael Walsh except KeyError: 45370369fdcSMichael Walsh match = False 45445ca6e4cSMichael Walsh if match != default_match: 45570369fdcSMichael Walsh return match 45670369fdcSMichael Walsh 45745ca6e4cSMichael Walsh return default_match 45845ca6e4cSMichael Walsh 45970369fdcSMichael Walsh 46020f38712SPatrick Williamsdef get_os_state( 46120f38712SPatrick Williams os_host="", 46270369fdcSMichael Walsh os_username="", 46370369fdcSMichael Walsh os_password="", 4648fae6eaeSMichael Walsh req_states=default_os_req_states, 4658fae6eaeSMichael Walsh os_up=True, 46620f38712SPatrick Williams quiet=None, 46720f38712SPatrick Williams): 46870369fdcSMichael Walsh r""" 46970369fdcSMichael Walsh Get component states for the operating system such as ping, login, 47070369fdcSMichael Walsh etc, put them into a dictionary and return them to the caller. 47170369fdcSMichael Walsh 4728fae6eaeSMichael Walsh Note that all substate values are strings. 4738fae6eaeSMichael Walsh 4742a0df683SMichael Walsh Description of argument(s): 47570369fdcSMichael Walsh os_host The DNS name or IP address of the operating system. 47670369fdcSMichael Walsh This defaults to global ${OS_HOST}. 47770369fdcSMichael Walsh os_username The username to be used to login to the OS. 47870369fdcSMichael Walsh This defaults to global ${OS_USERNAME}. 47970369fdcSMichael Walsh os_password The password to be used to login to the OS. 48070369fdcSMichael Walsh This defaults to global ${OS_PASSWORD}. 4818fae6eaeSMichael Walsh req_states This is a list of states whose values are being requested by 4828fae6eaeSMichael Walsh the caller. 4838fae6eaeSMichael Walsh os_up If the caller knows that the os can't possibly be up, it can 4848fae6eaeSMichael Walsh improve performance by passing os_up=False. This function 4858fae6eaeSMichael Walsh will then simply return default values for all requested os 4868fae6eaeSMichael Walsh sub states. 48770369fdcSMichael Walsh quiet Indicates whether status details (e.g. curl commands) should 48870369fdcSMichael Walsh be written to the console. 48970369fdcSMichael Walsh Defaults to either global value of ${QUIET} or to 1. 49070369fdcSMichael Walsh """ 49170369fdcSMichael Walsh 492619aa332SMichael Walsh quiet = int(gp.get_var_value(quiet, 0)) 49370369fdcSMichael Walsh 49470369fdcSMichael Walsh # Set parm defaults where necessary and validate all parms. 49570369fdcSMichael Walsh if os_host == "": 49670369fdcSMichael Walsh os_host = BuiltIn().get_variable_value("${OS_HOST}") 4972a0df683SMichael Walsh error_message = gv.valid_value(os_host, invalid_values=[None, ""]) 49870369fdcSMichael Walsh if error_message != "": 49970369fdcSMichael Walsh BuiltIn().fail(gp.sprint_error(error_message)) 50070369fdcSMichael Walsh 50170369fdcSMichael Walsh if os_username == "": 50270369fdcSMichael Walsh os_username = BuiltIn().get_variable_value("${OS_USERNAME}") 5032a0df683SMichael Walsh error_message = gv.valid_value(os_username, invalid_values=[None, ""]) 50470369fdcSMichael Walsh if error_message != "": 50570369fdcSMichael Walsh BuiltIn().fail(gp.sprint_error(error_message)) 50670369fdcSMichael Walsh 50770369fdcSMichael Walsh if os_password == "": 50870369fdcSMichael Walsh os_password = BuiltIn().get_variable_value("${OS_PASSWORD}") 5092a0df683SMichael Walsh error_message = gv.valid_value(os_password, invalid_values=[None, ""]) 51070369fdcSMichael Walsh if error_message != "": 51170369fdcSMichael Walsh BuiltIn().fail(gp.sprint_error(error_message)) 51270369fdcSMichael Walsh 51320f38712SPatrick Williams invalid_req_states = [ 51420f38712SPatrick Williams sub_state 51520f38712SPatrick Williams for sub_state in req_states 51620f38712SPatrick Williams if sub_state not in valid_os_req_states 51720f38712SPatrick Williams ] 5188fae6eaeSMichael Walsh if len(invalid_req_states) > 0: 51920f38712SPatrick Williams error_message = ( 52020f38712SPatrick Williams "The following req_states are not supported:\n" 52120f38712SPatrick Williams + gp.sprint_var(invalid_req_states) 52220f38712SPatrick Williams ) 5238fae6eaeSMichael Walsh BuiltIn().fail(gp.sprint_error(error_message)) 5248fae6eaeSMichael Walsh 5258fae6eaeSMichael Walsh # Initialize all substate values supported by this function. 5268fae6eaeSMichael Walsh os_ping = 0 5278fae6eaeSMichael Walsh os_login = 0 5288fae6eaeSMichael Walsh os_run_cmd = 0 5298fae6eaeSMichael Walsh 5308fae6eaeSMichael Walsh if os_up: 53120f38712SPatrick Williams if "os_ping" in req_states: 53270369fdcSMichael Walsh # See if the OS pings. 53320f38712SPatrick Williams rc, out_buf = gc.shell_cmd( 53420f38712SPatrick Williams "ping -c 1 -w 2 " + os_host, 53520f38712SPatrick Williams print_output=0, 53620f38712SPatrick Williams show_err=0, 53720f38712SPatrick Williams ignore_err=1, 53820f38712SPatrick Williams ) 53970369fdcSMichael Walsh if rc == 0: 5408fae6eaeSMichael Walsh os_ping = 1 54170369fdcSMichael Walsh 5428fae6eaeSMichael Walsh # Programming note: All attributes which do not require an ssh login 5438fae6eaeSMichael Walsh # should have been processed by this point. 54420f38712SPatrick Williams master_req_login = ["os_login", "os_run_cmd"] 54520f38712SPatrick Williams req_login = [ 54620f38712SPatrick Williams sub_state 54720f38712SPatrick Williams for sub_state in req_states 54820f38712SPatrick Williams if sub_state in master_req_login 54920f38712SPatrick Williams ] 55020f38712SPatrick Williams must_login = len(req_login) > 0 5518fae6eaeSMichael Walsh 5528fae6eaeSMichael Walsh if must_login: 55320f38712SPatrick Williams output, stderr, rc = bsu.os_execute_command( 55420f38712SPatrick Williams "uptime", 55520f38712SPatrick Williams quiet=quiet, 5567fc3397aSMichael Walsh ignore_err=1, 5573390c85eSMichael Shepos time_out=20, 5583390c85eSMichael Shepos os_host=os_host, 5593390c85eSMichael Shepos os_username=os_username, 56020f38712SPatrick Williams os_password=os_password, 56120f38712SPatrick Williams ) 5626a9bd143SMichael Walsh if rc == 0: 5638fae6eaeSMichael Walsh os_login = 1 5648fae6eaeSMichael Walsh os_run_cmd = 1 5653eb50027SMichael Walsh else: 5666a9bd143SMichael Walsh gp.dprint_vars(output, stderr) 5676a9bd143SMichael Walsh gp.dprint_vars(rc, 1) 56870369fdcSMichael Walsh 5698fae6eaeSMichael Walsh os_state = DotDict() 5708fae6eaeSMichael Walsh for sub_state in req_states: 5718fae6eaeSMichael Walsh cmd_buf = "os_state['" + sub_state + "'] = str(" + sub_state + ")" 5728fae6eaeSMichael Walsh exec(cmd_buf) 57370369fdcSMichael Walsh 57470369fdcSMichael Walsh return os_state 57570369fdcSMichael Walsh 57670369fdcSMichael Walsh 57720f38712SPatrick Williamsdef get_state( 57820f38712SPatrick Williams openbmc_host="", 57970369fdcSMichael Walsh openbmc_username="", 58070369fdcSMichael Walsh openbmc_password="", 58170369fdcSMichael Walsh os_host="", 58270369fdcSMichael Walsh os_username="", 58370369fdcSMichael Walsh os_password="", 5848fae6eaeSMichael Walsh req_states=default_req_states, 58520f38712SPatrick Williams quiet=None, 58620f38712SPatrick Williams): 58770369fdcSMichael Walsh r""" 588619aa332SMichael Walsh Get component states such as chassis state, bmc state, etc, put them into a 58970369fdcSMichael Walsh dictionary and return them to the caller. 59070369fdcSMichael Walsh 5918fae6eaeSMichael Walsh Note that all substate values are strings. 5928fae6eaeSMichael Walsh 5932a0df683SMichael Walsh Note: If elapsed_boot_time is included in req_states, it is the caller's 5942a0df683SMichael Walsh duty to call set_start_boot_seconds() in order to set global 5952a0df683SMichael Walsh start_boot_seconds. elapsed_boot_time is the current time minus 5962a0df683SMichael Walsh start_boot_seconds. 5972a0df683SMichael Walsh 5982a0df683SMichael Walsh Description of argument(s): 59970369fdcSMichael Walsh openbmc_host The DNS name or IP address of the BMC. 60070369fdcSMichael Walsh This defaults to global ${OPENBMC_HOST}. 60170369fdcSMichael Walsh openbmc_username The username to be used to login to the BMC. 60270369fdcSMichael Walsh This defaults to global ${OPENBMC_USERNAME}. 60370369fdcSMichael Walsh openbmc_password The password to be used to login to the BMC. 60470369fdcSMichael Walsh This defaults to global ${OPENBMC_PASSWORD}. 60570369fdcSMichael Walsh os_host The DNS name or IP address of the operating system. 60670369fdcSMichael Walsh This defaults to global ${OS_HOST}. 60770369fdcSMichael Walsh os_username The username to be used to login to the OS. 60870369fdcSMichael Walsh This defaults to global ${OS_USERNAME}. 60970369fdcSMichael Walsh os_password The password to be used to login to the OS. 61070369fdcSMichael Walsh This defaults to global ${OS_PASSWORD}. 6118fae6eaeSMichael Walsh req_states This is a list of states whose values are being requested 6128fae6eaeSMichael Walsh by the caller. 61370369fdcSMichael Walsh quiet Indicates whether status details (e.g. curl commands) 61470369fdcSMichael Walsh should be written to the console. 61570369fdcSMichael Walsh Defaults to either global value of ${QUIET} or to 1. 61670369fdcSMichael Walsh """ 61770369fdcSMichael Walsh 618619aa332SMichael Walsh quiet = int(gp.get_var_value(quiet, 0)) 61970369fdcSMichael Walsh 62070369fdcSMichael Walsh # Set parm defaults where necessary and validate all parms. 62170369fdcSMichael Walsh if openbmc_host == "": 62270369fdcSMichael Walsh openbmc_host = BuiltIn().get_variable_value("${OPENBMC_HOST}") 6232a0df683SMichael Walsh error_message = gv.valid_value(openbmc_host, invalid_values=[None, ""]) 62470369fdcSMichael Walsh if error_message != "": 62570369fdcSMichael Walsh BuiltIn().fail(gp.sprint_error(error_message)) 62670369fdcSMichael Walsh 62770369fdcSMichael Walsh if openbmc_username == "": 62870369fdcSMichael Walsh openbmc_username = BuiltIn().get_variable_value("${OPENBMC_USERNAME}") 6292a0df683SMichael Walsh error_message = gv.valid_value(openbmc_username, invalid_values=[None, ""]) 63070369fdcSMichael Walsh if error_message != "": 63170369fdcSMichael Walsh BuiltIn().fail(gp.sprint_error(error_message)) 63270369fdcSMichael Walsh 63370369fdcSMichael Walsh if openbmc_password == "": 63470369fdcSMichael Walsh openbmc_password = BuiltIn().get_variable_value("${OPENBMC_PASSWORD}") 6352a0df683SMichael Walsh error_message = gv.valid_value(openbmc_password, invalid_values=[None, ""]) 63670369fdcSMichael Walsh if error_message != "": 63770369fdcSMichael Walsh BuiltIn().fail(gp.sprint_error(error_message)) 63870369fdcSMichael Walsh 6398fae6eaeSMichael Walsh # NOTE: OS parms are optional. 64070369fdcSMichael Walsh if os_host == "": 64170369fdcSMichael Walsh os_host = BuiltIn().get_variable_value("${OS_HOST}") 64270369fdcSMichael Walsh if os_host is None: 64370369fdcSMichael Walsh os_host = "" 64470369fdcSMichael Walsh 645e7e9171eSGeorge Keishing if os_username == "": 64670369fdcSMichael Walsh os_username = BuiltIn().get_variable_value("${OS_USERNAME}") 64770369fdcSMichael Walsh if os_username is None: 64870369fdcSMichael Walsh os_username = "" 64970369fdcSMichael Walsh 650e7e9171eSGeorge Keishing if os_password == "": 65170369fdcSMichael Walsh os_password = BuiltIn().get_variable_value("${OS_PASSWORD}") 65270369fdcSMichael Walsh if os_password is None: 65370369fdcSMichael Walsh os_password = "" 65470369fdcSMichael Walsh 65520f38712SPatrick Williams invalid_req_states = [ 65620f38712SPatrick Williams sub_state 65720f38712SPatrick Williams for sub_state in req_states 65820f38712SPatrick Williams if sub_state not in valid_req_states 65920f38712SPatrick Williams ] 6608fae6eaeSMichael Walsh if len(invalid_req_states) > 0: 66120f38712SPatrick Williams error_message = ( 66220f38712SPatrick Williams "The following req_states are not supported:\n" 66320f38712SPatrick Williams + gp.sprint_var(invalid_req_states) 66420f38712SPatrick Williams ) 6658fae6eaeSMichael Walsh BuiltIn().fail(gp.sprint_error(error_message)) 6668fae6eaeSMichael Walsh 6678fae6eaeSMichael Walsh # Initialize all substate values supported by this function. 6688fae6eaeSMichael Walsh ping = 0 66920f38712SPatrick Williams packet_loss = "" 67020f38712SPatrick Williams uptime = "" 67120f38712SPatrick Williams epoch_seconds = "" 67220f38712SPatrick Williams elapsed_boot_time = "" 67320f38712SPatrick Williams rest = "" 67420f38712SPatrick Williams redfish = "" 67520f38712SPatrick Williams chassis = "" 67620f38712SPatrick Williams requested_chassis = "" 67720f38712SPatrick Williams bmc = "" 67820f38712SPatrick Williams requested_bmc = "" 67918f15dd7SGeorge Keishing # BootProgress state will get populated when state logic enumerates the 68018f15dd7SGeorge Keishing # state URI. This is to prevent state dictionary boot_progress value 68118f15dd7SGeorge Keishing # getting empty when the BootProgress is NOT found, making it optional. 68220f38712SPatrick Williams boot_progress = "NA" 68320f38712SPatrick Williams operating_system = "" 68420f38712SPatrick Williams host = "" 68520f38712SPatrick Williams requested_host = "" 68620f38712SPatrick Williams attempts_left = "" 6878fae6eaeSMichael Walsh 68870369fdcSMichael Walsh # Get the component states. 68920f38712SPatrick Williams if "ping" in req_states: 6908fae6eaeSMichael Walsh # See if the OS pings. 69120f38712SPatrick Williams rc, out_buf = gc.shell_cmd( 69220f38712SPatrick Williams "ping -c 1 -w 2 " + openbmc_host, 69320f38712SPatrick Williams print_output=0, 69420f38712SPatrick Williams show_err=0, 69520f38712SPatrick Williams ignore_err=1, 69620f38712SPatrick Williams ) 6978fae6eaeSMichael Walsh if rc == 0: 6988fae6eaeSMichael Walsh ping = 1 6998fae6eaeSMichael Walsh 70020f38712SPatrick Williams if "packet_loss" in req_states: 7018fae6eaeSMichael Walsh # See if the OS pings. 70220f38712SPatrick Williams cmd_buf = ( 70320f38712SPatrick Williams "ping -c 5 -w 5 " 70420f38712SPatrick Williams + openbmc_host 70520f38712SPatrick Williams + " | egrep 'packet loss' | sed -re 's/.* ([0-9]+)%.*/\\1/g'" 70620f38712SPatrick Williams ) 70720f38712SPatrick Williams rc, out_buf = gc.shell_cmd( 70820f38712SPatrick Williams cmd_buf, print_output=0, show_err=0, ignore_err=1 70920f38712SPatrick Williams ) 7108fae6eaeSMichael Walsh if rc == 0: 7118fae6eaeSMichael Walsh packet_loss = out_buf.rstrip("\n") 7128fae6eaeSMichael Walsh 71320f38712SPatrick Williams if "uptime" in req_states: 714fa76593aSMichael Walsh # Sometimes reading uptime results in a blank value. Call with 715fa76593aSMichael Walsh # wait_until_keyword_succeeds to ensure a non-blank value is obtained. 71620f38712SPatrick Williams remote_cmd_buf = ( 71720f38712SPatrick Williams "bash -c 'read uptime filler 2>/dev/null < /proc/uptime" 71820f38712SPatrick Williams + ' && [ ! -z "${uptime}" ] && echo ${uptime}\'' 71920f38712SPatrick Williams ) 72020f38712SPatrick Williams cmd_buf = [ 72120f38712SPatrick Williams "BMC Execute Command", 72220f38712SPatrick Williams re.sub("\\$", "\\$", remote_cmd_buf), 72320f38712SPatrick Williams "quiet=1", 72420f38712SPatrick Williams "test_mode=0", 72520f38712SPatrick Williams "time_out=5", 72620f38712SPatrick Williams ] 7272a0df683SMichael Walsh gp.qprint_issuing(cmd_buf, 0) 7282a0df683SMichael Walsh gp.qprint_issuing(remote_cmd_buf, 0) 729fa76593aSMichael Walsh try: 73020f38712SPatrick Williams stdout, stderr, rc = BuiltIn().wait_until_keyword_succeeds( 73120f38712SPatrick Williams "10 sec", "5 sec", *cmd_buf 73220f38712SPatrick Williams ) 7333eb50027SMichael Walsh if rc == 0 and stderr == "": 7343eb50027SMichael Walsh uptime = stdout 735fa76593aSMichael Walsh except AssertionError as my_assertion_error: 736fa76593aSMichael Walsh pass 7378fae6eaeSMichael Walsh 73820f38712SPatrick Williams if "epoch_seconds" in req_states or "elapsed_boot_time" in req_states: 7398fae6eaeSMichael Walsh date_cmd_buf = "date -u +%s" 7408fae6eaeSMichael Walsh if USE_BMC_EPOCH_TIME: 74120f38712SPatrick Williams cmd_buf = ["BMC Execute Command", date_cmd_buf, "quiet=${1}"] 7428fae6eaeSMichael Walsh if not quiet: 743edb5c949SMichael Walsh gp.print_issuing(cmd_buf) 74420f38712SPatrick Williams status, ret_values = BuiltIn().run_keyword_and_ignore_error( 74520f38712SPatrick Williams *cmd_buf 74620f38712SPatrick Williams ) 74797df71ceSMichael Walsh if status == "PASS": 74897df71ceSMichael Walsh stdout, stderr, rc = ret_values 7493eb50027SMichael Walsh if rc == 0 and stderr == "": 7503eb50027SMichael Walsh epoch_seconds = stdout.rstrip("\n") 7518fae6eaeSMichael Walsh else: 75220f38712SPatrick Williams shell_rc, out_buf = gc.cmd_fnc_u( 75320f38712SPatrick Williams date_cmd_buf, quiet=quiet, print_output=0 75420f38712SPatrick Williams ) 7558fae6eaeSMichael Walsh if shell_rc == 0: 7568fae6eaeSMichael Walsh epoch_seconds = out_buf.rstrip("\n") 7578fae6eaeSMichael Walsh 75820f38712SPatrick Williams if "elapsed_boot_time" in req_states: 7592a0df683SMichael Walsh global start_boot_seconds 7602a0df683SMichael Walsh elapsed_boot_time = int(epoch_seconds) - start_boot_seconds 7612a0df683SMichael Walsh 762bdd1dceaSMichael Shepos if not redfish_support_trans_state: 76320f38712SPatrick Williams master_req_rest = [ 76420f38712SPatrick Williams "rest", 76520f38712SPatrick Williams "host", 76620f38712SPatrick Williams "requested_host", 76720f38712SPatrick Williams "operating_system", 76820f38712SPatrick Williams "attempts_left", 76920f38712SPatrick Williams "boot_progress", 77020f38712SPatrick Williams "chassis", 77120f38712SPatrick Williams "requested_chassisbmcrequested_bmc", 77220f38712SPatrick Williams ] 7735674922eSMichael Walsh 77420f38712SPatrick Williams req_rest = [ 77520f38712SPatrick Williams sub_state 77620f38712SPatrick Williams for sub_state in req_states 77720f38712SPatrick Williams if sub_state in master_req_rest 77820f38712SPatrick Williams ] 77920f38712SPatrick Williams need_rest = len(req_rest) > 0 7805674922eSMichael Walsh state = DotDict() 7815674922eSMichael Walsh if need_rest: 78220f38712SPatrick Williams cmd_buf = [ 78320f38712SPatrick Williams "Read Properties", 78420f38712SPatrick Williams SYSTEM_STATE_URI + "enumerate", 78520f38712SPatrick Williams "quiet=${" + str(quiet) + "}", 78620f38712SPatrick Williams "timeout=30", 78720f38712SPatrick Williams ] 788edb5c949SMichael Walsh gp.dprint_issuing(cmd_buf) 78920f38712SPatrick Williams status, ret_values = BuiltIn().run_keyword_and_ignore_error( 79020f38712SPatrick Williams *cmd_buf 79120f38712SPatrick Williams ) 79297df71ceSMichael Walsh if status == "PASS": 79320f38712SPatrick Williams state["rest"] = "1" 7945674922eSMichael Walsh else: 79520f38712SPatrick Williams state["rest"] = "0" 79670369fdcSMichael Walsh 79720f38712SPatrick Williams if int(state["rest"]): 7985674922eSMichael Walsh for url_path in ret_values: 7993adda95eSGeorge Keishing # Skip conflicting "CurrentHostState" URL from the enum 8003adda95eSGeorge Keishing # /xyz/openbmc_project/state/hypervisor0 8013adda95eSGeorge Keishing if "hypervisor0" in url_path: 8023adda95eSGeorge Keishing continue 8033adda95eSGeorge Keishing 8048c9cf9c8SKonstantin Aladyshev if platform_arch_type == "x86": 8058c9cf9c8SKonstantin Aladyshev # Skip conflicting "CurrentPowerState" URL from the enum 8068c9cf9c8SKonstantin Aladyshev # /xyz/openbmc_project/state/chassis_system0 8078c9cf9c8SKonstantin Aladyshev if "chassis_system0" in url_path: 8088c9cf9c8SKonstantin Aladyshev continue 8098c9cf9c8SKonstantin Aladyshev 8105674922eSMichael Walsh for attr_name in ret_values[url_path]: 8115674922eSMichael Walsh # Create a state key value based on the attr_name. 81236efbc04SGeorge Keishing try: 81320f38712SPatrick Williams ret_values[url_path][attr_name] = re.sub( 81420f38712SPatrick Williams r".*\.", "", ret_values[url_path][attr_name] 81520f38712SPatrick Williams ) 81636efbc04SGeorge Keishing except TypeError: 81736efbc04SGeorge Keishing pass 8185674922eSMichael Walsh # Do some key name manipulations. 81920f38712SPatrick Williams new_attr_name = re.sub( 82020f38712SPatrick Williams r"^Current|(State|Transition)$", "", attr_name 82120f38712SPatrick Williams ) 82220f38712SPatrick Williams new_attr_name = re.sub(r"BMC", r"Bmc", new_attr_name) 82320f38712SPatrick Williams new_attr_name = re.sub( 82420f38712SPatrick Williams r"([A-Z][a-z])", r"_\1", new_attr_name 82520f38712SPatrick Williams ) 8265674922eSMichael Walsh new_attr_name = new_attr_name.lower().lstrip("_") 82720f38712SPatrick Williams new_attr_name = re.sub( 82820f38712SPatrick Williams r"power", r"chassis", new_attr_name 82920f38712SPatrick Williams ) 8305674922eSMichael Walsh if new_attr_name in req_states: 83120f38712SPatrick Williams state[new_attr_name] = ret_values[url_path][ 83220f38712SPatrick Williams attr_name 83320f38712SPatrick Williams ] 834bdd1dceaSMichael Shepos else: 83520f38712SPatrick Williams master_req_rf = [ 83620f38712SPatrick Williams "redfish", 83720f38712SPatrick Williams "host", 83820f38712SPatrick Williams "requested_host", 83920f38712SPatrick Williams "attempts_left", 84020f38712SPatrick Williams "boot_progress", 84120f38712SPatrick Williams "chassis", 84220f38712SPatrick Williams "requested_chassisbmcrequested_bmc", 84320f38712SPatrick Williams ] 844bdd1dceaSMichael Shepos 84520f38712SPatrick Williams req_rf = [ 84620f38712SPatrick Williams sub_state for sub_state in req_states if sub_state in master_req_rf 84720f38712SPatrick Williams ] 84820f38712SPatrick Williams need_rf = len(req_rf) > 0 849bdd1dceaSMichael Shepos state = DotDict() 850bdd1dceaSMichael Shepos if need_rf: 851bdd1dceaSMichael Shepos cmd_buf = ["Redfish Get States"] 852bdd1dceaSMichael Shepos gp.dprint_issuing(cmd_buf) 85321e28b47SGeorge Keishing try: 85420f38712SPatrick Williams status, ret_values = BuiltIn().run_keyword_and_ignore_error( 85520f38712SPatrick Williams *cmd_buf 85620f38712SPatrick Williams ) 85721e28b47SGeorge Keishing except Exception as ex: 85821e28b47SGeorge Keishing # Robot raised UserKeywordExecutionFailed error exception. 85921e28b47SGeorge Keishing gp.dprint_issuing("Retrying Redfish Get States") 86020f38712SPatrick Williams status, ret_values = BuiltIn().run_keyword_and_ignore_error( 86120f38712SPatrick Williams *cmd_buf 86220f38712SPatrick Williams ) 86321e28b47SGeorge Keishing 864bdd1dceaSMichael Shepos gp.dprint_vars(status, ret_values) 865bdd1dceaSMichael Shepos if status == "PASS": 86620f38712SPatrick Williams state["redfish"] = "1" 867bdd1dceaSMichael Shepos else: 86820f38712SPatrick Williams state["redfish"] = "0" 869bdd1dceaSMichael Shepos 87020f38712SPatrick Williams if int(state["redfish"]): 87120f38712SPatrick Williams state["chassis"] = ret_values["chassis"] 87220f38712SPatrick Williams state["host"] = ret_values["host"] 87320f38712SPatrick Williams state["bmc"] = ret_values["bmc"] 874b51d1505SGeorge Keishing if platform_arch_type != "x86": 87520f38712SPatrick Williams state["boot_progress"] = ret_values["boot_progress"] 87670369fdcSMichael Walsh 8778fae6eaeSMichael Walsh for sub_state in req_states: 8785674922eSMichael Walsh if sub_state in state: 8795674922eSMichael Walsh continue 8808fae6eaeSMichael Walsh if sub_state.startswith("os_"): 8818fae6eaeSMichael Walsh # We pass "os_" requests on to get_os_state. 8828fae6eaeSMichael Walsh continue 8838fae6eaeSMichael Walsh cmd_buf = "state['" + sub_state + "'] = str(" + sub_state + ")" 8848fae6eaeSMichael Walsh exec(cmd_buf) 885341c21ebSMichael Walsh 8868fae6eaeSMichael Walsh if os_host == "": 8878fae6eaeSMichael Walsh # The caller has not specified an os_host so as far as we're concerned, 8888fae6eaeSMichael Walsh # it doesn't exist. 8898fae6eaeSMichael Walsh return state 89070369fdcSMichael Walsh 89120f38712SPatrick Williams os_req_states = [ 89220f38712SPatrick Williams sub_state for sub_state in req_states if sub_state.startswith("os_") 89320f38712SPatrick Williams ] 8948fae6eaeSMichael Walsh 8958fae6eaeSMichael Walsh if len(os_req_states) > 0: 8968fae6eaeSMichael Walsh # The caller has specified an os_host and they have requested 8978fae6eaeSMichael Walsh # information on os substates. 8988fae6eaeSMichael Walsh 8998fae6eaeSMichael Walsh # Based on the information gathered on bmc, we'll try to make a 9008fae6eaeSMichael Walsh # determination of whether the os is even up. We'll pass the result 9018fae6eaeSMichael Walsh # of that assessment to get_os_state to enhance performance. 9028fae6eaeSMichael Walsh os_up_match = DotDict() 9038fae6eaeSMichael Walsh for sub_state in master_os_up_match: 9048fae6eaeSMichael Walsh if sub_state in req_states: 9058fae6eaeSMichael Walsh os_up_match[sub_state] = master_os_up_match[sub_state] 90670369fdcSMichael Walsh os_up = compare_states(state, os_up_match) 90720f38712SPatrick Williams os_state = get_os_state( 90820f38712SPatrick Williams os_host=os_host, 90970369fdcSMichael Walsh os_username=os_username, 91070369fdcSMichael Walsh os_password=os_password, 9118fae6eaeSMichael Walsh req_states=os_req_states, 9128fae6eaeSMichael Walsh os_up=os_up, 91320f38712SPatrick Williams quiet=quiet, 91420f38712SPatrick Williams ) 9158fae6eaeSMichael Walsh # Append os_state dictionary to ours. 9168fae6eaeSMichael Walsh state.update(os_state) 91770369fdcSMichael Walsh 91870369fdcSMichael Walsh return state 91970369fdcSMichael Walsh 92070369fdcSMichael Walsh 921fd5a868dSMichael Walshexit_wait_early_message = "" 922fd5a868dSMichael Walsh 923fd5a868dSMichael Walsh 924fd5a868dSMichael Walshdef set_exit_wait_early_message(value): 925fd5a868dSMichael Walsh r""" 926fd5a868dSMichael Walsh Set global exit_wait_early_message to the indicated value. 927fd5a868dSMichael Walsh 928fd5a868dSMichael Walsh This is a mechanism by which the programmer can do an early exit from 929fd5a868dSMichael Walsh wait_until_keyword_succeeds() based on some special condition. 930fd5a868dSMichael Walsh 931fd5a868dSMichael Walsh Description of argument(s): 932fd5a868dSMichael Walsh value The value to assign to the global 933fd5a868dSMichael Walsh exit_wait_early_message. 934fd5a868dSMichael Walsh """ 935fd5a868dSMichael Walsh 936fd5a868dSMichael Walsh global exit_wait_early_message 937fd5a868dSMichael Walsh exit_wait_early_message = value 938fd5a868dSMichael Walsh 939fd5a868dSMichael Walsh 94020f38712SPatrick Williamsdef check_state( 94120f38712SPatrick Williams match_state, 94270369fdcSMichael Walsh invert=0, 94370369fdcSMichael Walsh print_string="", 94470369fdcSMichael Walsh openbmc_host="", 94570369fdcSMichael Walsh openbmc_username="", 94670369fdcSMichael Walsh openbmc_password="", 94770369fdcSMichael Walsh os_host="", 94870369fdcSMichael Walsh os_username="", 94970369fdcSMichael Walsh os_password="", 95020f38712SPatrick Williams quiet=None, 95120f38712SPatrick Williams): 95270369fdcSMichael Walsh r""" 95370369fdcSMichael Walsh Check that the Open BMC machine's composite state matches the specified 95470369fdcSMichael Walsh state. On success, this keyword returns the machine's composite state as a 95570369fdcSMichael Walsh dictionary. 95670369fdcSMichael Walsh 9572a0df683SMichael Walsh Description of argument(s): 95870369fdcSMichael Walsh match_state A dictionary whose key/value pairs are "state field"/ 95970369fdcSMichael Walsh "state value". The state value is interpreted as a 96070369fdcSMichael Walsh regular expression. Example call from robot: 961341c21ebSMichael Walsh ${match_state}= Create Dictionary chassis=^On$ 962341c21ebSMichael Walsh ... bmc=^Ready$ 96301975fa8SMichael Walsh ... boot_progress=^OSStart$ 96470369fdcSMichael Walsh ${state}= Check State &{match_state} 96570369fdcSMichael Walsh invert If this flag is set, this function will succeed if the 96670369fdcSMichael Walsh states do NOT match. 96770369fdcSMichael Walsh print_string This function will print this string to the console prior 96870369fdcSMichael Walsh to getting the state. 96970369fdcSMichael Walsh openbmc_host The DNS name or IP address of the BMC. 97070369fdcSMichael Walsh This defaults to global ${OPENBMC_HOST}. 97170369fdcSMichael Walsh openbmc_username The username to be used to login to the BMC. 97270369fdcSMichael Walsh This defaults to global ${OPENBMC_USERNAME}. 97370369fdcSMichael Walsh openbmc_password The password to be used to login to the BMC. 97470369fdcSMichael Walsh This defaults to global ${OPENBMC_PASSWORD}. 97570369fdcSMichael Walsh os_host The DNS name or IP address of the operating system. 97670369fdcSMichael Walsh This defaults to global ${OS_HOST}. 97770369fdcSMichael Walsh os_username The username to be used to login to the OS. 97870369fdcSMichael Walsh This defaults to global ${OS_USERNAME}. 97970369fdcSMichael Walsh os_password The password to be used to login to the OS. 98070369fdcSMichael Walsh This defaults to global ${OS_PASSWORD}. 98170369fdcSMichael Walsh quiet Indicates whether status details should be written to the 98270369fdcSMichael Walsh console. Defaults to either global value of ${QUIET} or 98370369fdcSMichael Walsh to 1. 98470369fdcSMichael Walsh """ 98570369fdcSMichael Walsh 986619aa332SMichael Walsh quiet = int(gp.get_var_value(quiet, 0)) 98770369fdcSMichael Walsh 988edb5c949SMichael Walsh gp.gp_print(print_string) 989edb5c949SMichael Walsh 990edb5c949SMichael Walsh try: 991edb5c949SMichael Walsh match_state = return_state_constant(match_state) 992edb5c949SMichael Walsh except TypeError: 993edb5c949SMichael Walsh pass 99470369fdcSMichael Walsh 9952a0df683SMichael Walsh req_states = list(match_state.keys()) 9962a0df683SMichael Walsh # Remove special-case match key from req_states. 9972a0df683SMichael Walsh if expressions_key() in req_states: 9982a0df683SMichael Walsh req_states.remove(expressions_key()) 99970369fdcSMichael Walsh # Initialize state. 100020f38712SPatrick Williams state = get_state( 100120f38712SPatrick Williams openbmc_host=openbmc_host, 100270369fdcSMichael Walsh openbmc_username=openbmc_username, 100370369fdcSMichael Walsh openbmc_password=openbmc_password, 100470369fdcSMichael Walsh os_host=os_host, 100570369fdcSMichael Walsh os_username=os_username, 100670369fdcSMichael Walsh os_password=os_password, 10078fae6eaeSMichael Walsh req_states=req_states, 100820f38712SPatrick Williams quiet=quiet, 100920f38712SPatrick Williams ) 101070369fdcSMichael Walsh if not quiet: 10113eb50027SMichael Walsh gp.print_var(state) 101270369fdcSMichael Walsh 1013fd5a868dSMichael Walsh if exit_wait_early_message != "": 1014fd5a868dSMichael Walsh # The exit_wait_early_message has been set by a signal handler so we 1015fd5a868dSMichael Walsh # will exit "successfully". It is incumbent upon the calling function 1016fd5a868dSMichael Walsh # (e.g. wait_state) to check/clear this variable and to fail 1017fd5a868dSMichael Walsh # appropriately. 1018fd5a868dSMichael Walsh return state 1019fd5a868dSMichael Walsh 102070369fdcSMichael Walsh match = compare_states(state, match_state) 102170369fdcSMichael Walsh 102270369fdcSMichael Walsh if invert and match: 102320f38712SPatrick Williams fail_msg = ( 102420f38712SPatrick Williams "The current state of the machine matches the match" 102520f38712SPatrick Williams + " state:\n" 102620f38712SPatrick Williams + gp.sprint_varx("state", state) 102720f38712SPatrick Williams ) 102870369fdcSMichael Walsh BuiltIn().fail("\n" + gp.sprint_error(fail_msg)) 102970369fdcSMichael Walsh elif not invert and not match: 103020f38712SPatrick Williams fail_msg = ( 103120f38712SPatrick Williams "The current state of the machine does NOT match the" 103220f38712SPatrick Williams + " match state:\n" 103320f38712SPatrick Williams + gp.sprint_varx("state", state) 103420f38712SPatrick Williams ) 103570369fdcSMichael Walsh BuiltIn().fail("\n" + gp.sprint_error(fail_msg)) 103670369fdcSMichael Walsh 103770369fdcSMichael Walsh return state 103870369fdcSMichael Walsh 103970369fdcSMichael Walsh 104020f38712SPatrick Williamsdef wait_state( 104120f38712SPatrick Williams match_state=(), 104270369fdcSMichael Walsh wait_time="1 min", 104370369fdcSMichael Walsh interval="1 second", 104470369fdcSMichael Walsh invert=0, 104570369fdcSMichael Walsh openbmc_host="", 104670369fdcSMichael Walsh openbmc_username="", 104770369fdcSMichael Walsh openbmc_password="", 104870369fdcSMichael Walsh os_host="", 104970369fdcSMichael Walsh os_username="", 105070369fdcSMichael Walsh os_password="", 105120f38712SPatrick Williams quiet=None, 105220f38712SPatrick Williams): 105370369fdcSMichael Walsh r""" 105470369fdcSMichael Walsh Wait for the Open BMC machine's composite state to match the specified 105570369fdcSMichael Walsh state. On success, this keyword returns the machine's composite state as 105670369fdcSMichael Walsh a dictionary. 105770369fdcSMichael Walsh 10582a0df683SMichael Walsh Description of argument(s): 105970369fdcSMichael Walsh match_state A dictionary whose key/value pairs are "state field"/ 106070369fdcSMichael Walsh "state value". See check_state (above) for details. 1061619aa332SMichael Walsh This value may also be any string accepted by 1062619aa332SMichael Walsh return_state_constant (e.g. "standby_match_state"). 1063619aa332SMichael Walsh In such a case this function will call 1064619aa332SMichael Walsh return_state_constant to convert it to a proper 1065619aa332SMichael Walsh dictionary as described above. 106670369fdcSMichael Walsh wait_time The total amount of time to wait for the desired state. 106770369fdcSMichael Walsh This value may be expressed in Robot Framework's time 106870369fdcSMichael Walsh format (e.g. 1 minute, 2 min 3 s, 4.5). 106970369fdcSMichael Walsh interval The amount of time between state checks. 107070369fdcSMichael Walsh This value may be expressed in Robot Framework's time 107170369fdcSMichael Walsh format (e.g. 1 minute, 2 min 3 s, 4.5). 107270369fdcSMichael Walsh invert If this flag is set, this function will for the state of 107370369fdcSMichael Walsh the machine to cease to match the match state. 107470369fdcSMichael Walsh openbmc_host The DNS name or IP address of the BMC. 107570369fdcSMichael Walsh This defaults to global ${OPENBMC_HOST}. 107670369fdcSMichael Walsh openbmc_username The username to be used to login to the BMC. 107770369fdcSMichael Walsh This defaults to global ${OPENBMC_USERNAME}. 107870369fdcSMichael Walsh openbmc_password The password to be used to login to the BMC. 107970369fdcSMichael Walsh This defaults to global ${OPENBMC_PASSWORD}. 108070369fdcSMichael Walsh os_host The DNS name or IP address of the operating system. 108170369fdcSMichael Walsh This defaults to global ${OS_HOST}. 108270369fdcSMichael Walsh os_username The username to be used to login to the OS. 108370369fdcSMichael Walsh This defaults to global ${OS_USERNAME}. 108470369fdcSMichael Walsh os_password The password to be used to login to the OS. 108570369fdcSMichael Walsh This defaults to global ${OS_PASSWORD}. 108670369fdcSMichael Walsh quiet Indicates whether status details should be written to the 108770369fdcSMichael Walsh console. Defaults to either global value of ${QUIET} or 108870369fdcSMichael Walsh to 1. 108970369fdcSMichael Walsh """ 109070369fdcSMichael Walsh 1091619aa332SMichael Walsh quiet = int(gp.get_var_value(quiet, 0)) 1092619aa332SMichael Walsh 109336efbc04SGeorge Keishing try: 1094619aa332SMichael Walsh match_state = return_state_constant(match_state) 109536efbc04SGeorge Keishing except TypeError: 109636efbc04SGeorge Keishing pass 109770369fdcSMichael Walsh 109870369fdcSMichael Walsh if not quiet: 109970369fdcSMichael Walsh if invert: 110070369fdcSMichael Walsh alt_text = "cease to " 110170369fdcSMichael Walsh else: 110270369fdcSMichael Walsh alt_text = "" 110320f38712SPatrick Williams gp.print_timen( 110420f38712SPatrick Williams "Checking every " 110520f38712SPatrick Williams + str(interval) 110620f38712SPatrick Williams + " for up to " 110720f38712SPatrick Williams + str(wait_time) 110820f38712SPatrick Williams + " for the state of the machine to " 110920f38712SPatrick Williams + alt_text 111020f38712SPatrick Williams + "match the state shown below." 111120f38712SPatrick Williams ) 11123eb50027SMichael Walsh gp.print_var(match_state) 111370369fdcSMichael Walsh 1114f893ba09SMichael Walsh if quiet: 1115f893ba09SMichael Walsh print_string = "" 1116f893ba09SMichael Walsh else: 1117f893ba09SMichael Walsh print_string = "#" 11188fae6eaeSMichael Walsh 11198fae6eaeSMichael Walsh debug = int(BuiltIn().get_variable_value("${debug}", "0")) 11208fae6eaeSMichael Walsh if debug: 11218fae6eaeSMichael Walsh # In debug we print state so no need to print the "#". 11228fae6eaeSMichael Walsh print_string = "" 11238fae6eaeSMichael Walsh check_state_quiet = 1 - debug 112420f38712SPatrick Williams cmd_buf = [ 112520f38712SPatrick Williams "Check State", 112620f38712SPatrick Williams match_state, 112720f38712SPatrick Williams "invert=${" + str(invert) + "}", 112820f38712SPatrick Williams "print_string=" + print_string, 112920f38712SPatrick Williams "openbmc_host=" + openbmc_host, 113070369fdcSMichael Walsh "openbmc_username=" + openbmc_username, 113120f38712SPatrick Williams "openbmc_password=" + openbmc_password, 113220f38712SPatrick Williams "os_host=" + os_host, 113320f38712SPatrick Williams "os_username=" + os_username, 113420f38712SPatrick Williams "os_password=" + os_password, 113520f38712SPatrick Williams "quiet=${" + str(check_state_quiet) + "}", 113620f38712SPatrick Williams ] 1137edb5c949SMichael Walsh gp.dprint_issuing(cmd_buf) 1138619aa332SMichael Walsh try: 113920f38712SPatrick Williams state = BuiltIn().wait_until_keyword_succeeds( 114020f38712SPatrick Williams wait_time, interval, *cmd_buf 114120f38712SPatrick Williams ) 1142619aa332SMichael Walsh except AssertionError as my_assertion_error: 1143619aa332SMichael Walsh gp.printn() 1144619aa332SMichael Walsh message = my_assertion_error.args[0] 1145619aa332SMichael Walsh BuiltIn().fail(message) 1146619aa332SMichael Walsh 1147fd5a868dSMichael Walsh if exit_wait_early_message: 1148fd5a868dSMichael Walsh # The global exit_wait_early_message was set by a signal handler 1149fd5a868dSMichael Walsh # indicating that we should fail. 1150fd5a868dSMichael Walsh message = exit_wait_early_message 1151fd5a868dSMichael Walsh # Clear the exit_wait_early_message variable for future use. 1152fd5a868dSMichael Walsh set_exit_wait_early_message("") 1153fd5a868dSMichael Walsh BuiltIn().fail(gp.sprint_error(message)) 1154fd5a868dSMichael Walsh 115570369fdcSMichael Walsh if not quiet: 11563eb50027SMichael Walsh gp.printn() 115770369fdcSMichael Walsh if invert: 11583eb50027SMichael Walsh gp.print_timen("The states no longer match:") 115970369fdcSMichael Walsh else: 11603eb50027SMichael Walsh gp.print_timen("The states match:") 11613eb50027SMichael Walsh gp.print_var(state) 116270369fdcSMichael Walsh 116370369fdcSMichael Walsh return state 116470369fdcSMichael Walsh 11658fae6eaeSMichael Walsh 11662a0df683SMichael Walshdef set_start_boot_seconds(value=0): 11672a0df683SMichael Walsh global start_boot_seconds 11682a0df683SMichael Walsh start_boot_seconds = int(value) 11692a0df683SMichael Walsh 11702a0df683SMichael Walsh 11712a0df683SMichael Walshset_start_boot_seconds(0) 11722a0df683SMichael Walsh 11732a0df683SMichael Walsh 117420f38712SPatrick Williamsdef wait_for_comm_cycle(start_boot_seconds, quiet=None): 11758fae6eaeSMichael Walsh r""" 11762a0df683SMichael Walsh Wait for the BMC uptime to be less than elapsed_boot_time. 11778fae6eaeSMichael Walsh 11782a0df683SMichael Walsh This function will tolerate an expected loss of communication to the BMC. 11792a0df683SMichael Walsh This function is useful when some kind of reboot has been initiated by the 11802a0df683SMichael Walsh caller. 11812a0df683SMichael Walsh 11822a0df683SMichael Walsh Description of argument(s): 11838fae6eaeSMichael Walsh start_boot_seconds The time that the boot test started. The format is the 11848fae6eaeSMichael Walsh epoch time in seconds, i.e. the number of seconds since 11858fae6eaeSMichael Walsh 1970-01-01 00:00:00 UTC. This value should be obtained 11868fae6eaeSMichael Walsh from the BMC so that it is not dependent on any kind of 11878fae6eaeSMichael Walsh synchronization between this machine and the target BMC 11888fae6eaeSMichael Walsh This will allow this program to work correctly even in 11898fae6eaeSMichael Walsh a simulated environment. This value should be obtained 11908fae6eaeSMichael Walsh by the caller prior to initiating a reboot. It can be 11918fae6eaeSMichael Walsh obtained as follows: 11928fae6eaeSMichael Walsh state = st.get_state(req_states=['epoch_seconds']) 11938fae6eaeSMichael Walsh """ 11948fae6eaeSMichael Walsh 1195619aa332SMichael Walsh quiet = int(gp.get_var_value(quiet, 0)) 1196619aa332SMichael Walsh 11978fae6eaeSMichael Walsh # Validate parms. 11982a0df683SMichael Walsh error_message = gv.valid_integer(start_boot_seconds) 11992a0df683SMichael Walsh if error_message: 12008fae6eaeSMichael Walsh BuiltIn().fail(gp.sprint_error(error_message)) 12018fae6eaeSMichael Walsh 12022a0df683SMichael Walsh # Wait for uptime to be less than elapsed_boot_time. 12032a0df683SMichael Walsh set_start_boot_seconds(start_boot_seconds) 120420f38712SPatrick Williams expr = "int(float(state['uptime'])) < int(state['elapsed_boot_time'])" 120520f38712SPatrick Williams match_state = DotDict( 120620f38712SPatrick Williams [ 120720f38712SPatrick Williams ("uptime", "^[0-9\\.]+$"), 120820f38712SPatrick Williams ("elapsed_boot_time", "^[0-9]+$"), 120920f38712SPatrick Williams (expressions_key(), [expr]), 121020f38712SPatrick Williams ] 121120f38712SPatrick Williams ) 1212e9192561SDavid Shaw wait_state(match_state, wait_time="12 mins", interval="5 seconds") 12138fae6eaeSMichael Walsh 1214bdd1dceaSMichael Shepos gp.qprint_timen("Verifying that REST/Redfish API interface is working.") 1215bdd1dceaSMichael Shepos if not redfish_support_trans_state: 121620f38712SPatrick Williams match_state = DotDict([("rest", "^1$")]) 1217bdd1dceaSMichael Shepos else: 121820f38712SPatrick Williams match_state = DotDict([("redfish", "^1$")]) 12198fae6eaeSMichael Walsh state = wait_state(match_state, wait_time="5 mins", interval="2 seconds") 1220