| George Keishing | e7e9171 | 2021-09-03 11:28:44 -0500 | [diff] [blame] | 1 | #!/usr/bin/env python3 | 
| George Keishing | df9ad39 | 2017-01-25 13:01:15 -0600 | [diff] [blame] | 2 |  | 
 | 3 | r""" | 
 | 4 | State Manager module: | 
 | 5 |  | 
 | 6 |    - Defines Valid states of the system | 
 | 7 |  | 
 | 8 | """ | 
| George Keishing | 678b65c | 2017-08-31 16:16:39 -0500 | [diff] [blame] | 9 | import os | 
 | 10 | import re | 
 | 11 | import sys | 
 | 12 |  | 
| George Keishing | df9ad39 | 2017-01-25 13:01:15 -0600 | [diff] [blame] | 13 | from robot.libraries.BuiltIn import BuiltIn | 
 | 14 |  | 
| George Keishing | 678b65c | 2017-08-31 16:16:39 -0500 | [diff] [blame] | 15 | robot_pgm_dir_path = os.path.dirname(__file__) + os.sep | 
 | 16 | repo_data_dir_path = re.sub('/lib', '/data', robot_pgm_dir_path) | 
 | 17 | sys.path.append(repo_data_dir_path) | 
 | 18 |  | 
 | 19 | import gen_robot_keyword as keyword | 
 | 20 | import variables as var | 
 | 21 |  | 
| George Keishing | df9ad39 | 2017-01-25 13:01:15 -0600 | [diff] [blame] | 22 | BuiltIn().import_resource("state_manager.robot") | 
| George Keishing | 678b65c | 2017-08-31 16:16:39 -0500 | [diff] [blame] | 23 | BuiltIn().import_resource("rest_client.robot") | 
| George Keishing | df9ad39 | 2017-01-25 13:01:15 -0600 | [diff] [blame] | 24 |  | 
| Konstantin Aladyshev | c056c2b | 2021-03-25 11:59:39 +0300 | [diff] [blame] | 25 | platform_arch_type = os.environ.get('PLATFORM_ARCH_TYPE', '') or \ | 
 | 26 |     BuiltIn().get_variable_value("${PLATFORM_ARCH_TYPE}", default="power") | 
| Konstantin Aladyshev | d78dc93 | 2021-03-24 18:17:17 +0300 | [diff] [blame] | 27 |  | 
| George Keishing | df9ad39 | 2017-01-25 13:01:15 -0600 | [diff] [blame] | 28 | # We will build eventually the mapping for warm, cold reset as well. | 
 | 29 | VALID_STATES = { | 
 | 30 |     'reboot': | 
 | 31 |     { | 
| George Keishing | 678b65c | 2017-08-31 16:16:39 -0500 | [diff] [blame] | 32 |         # (Power Policy, BMC state, Chassis State, Host State) | 
 | 33 |         ('LEAVE_OFF', 'Ready', 'Off', 'Off'), | 
 | 34 |         ('ALWAYS_POWER_ON', 'Ready', 'On', 'Running'), | 
 | 35 |         ('ALWAYS_POWER_ON', 'Ready', 'On', 'Off'), | 
 | 36 |         ('RESTORE_LAST_STATE', 'Ready', 'On', 'Running'), | 
 | 37 |         ('RESTORE_LAST_STATE', 'Ready', 'On', 'Off'), | 
| George Keishing | efc3ff2 | 2017-12-12 11:49:25 -0600 | [diff] [blame] | 38 |         ('ALWAYS_POWER_OFF', 'Ready', 'On', 'Running'), | 
 | 39 |         ('ALWAYS_POWER_OFF', 'Ready', 'Off', 'Off'), | 
| George Keishing | 678b65c | 2017-08-31 16:16:39 -0500 | [diff] [blame] | 40 |     }, | 
 | 41 | } | 
 | 42 |  | 
 | 43 | VALID_BOOT_STATES = { | 
 | 44 |     'Off':  # Valid states when Host is Off. | 
 | 45 |     { | 
 | 46 |         # (BMC , Chassis , Host , BootProgress, OperatingSystemState) | 
 | 47 |         ( | 
 | 48 |             "xyz.openbmc_project.State.BMC.BMCState.Ready", | 
 | 49 |             "xyz.openbmc_project.State.Chassis.PowerState.Off", | 
 | 50 |             "xyz.openbmc_project.State.Host.HostState.Off", | 
 | 51 |             "xyz.openbmc_project.State.Boot.Progress.ProgressStages.Unspecified", | 
 | 52 |             "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus.Inactive" | 
 | 53 |         ), | 
 | 54 |     }, | 
 | 55 |     'Reboot':  # Valid states when BMC reset to standby. | 
 | 56 |     { | 
 | 57 |         # (BMC , Chassis , Host , BootProgress, OperatingSystemState) | 
 | 58 |         ( | 
 | 59 |             "xyz.openbmc_project.State.BMC.BMCState.Ready", | 
 | 60 |             "xyz.openbmc_project.State.Chassis.PowerState.Off", | 
 | 61 |             "xyz.openbmc_project.State.Host.HostState.Off", | 
 | 62 |             "xyz.openbmc_project.State.Boot.Progress.ProgressStages.Unspecified", | 
 | 63 |             "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus.Inactive" | 
 | 64 |         ), | 
 | 65 |     }, | 
 | 66 |     'Running':  # Valid states when Host is powering on. | 
 | 67 |     { | 
 | 68 |         # (BMC , Chassis , Host , BootProgress, OperatingSystemState) | 
 | 69 |         ( | 
 | 70 |             "xyz.openbmc_project.State.BMC.BMCState.Ready", | 
 | 71 |             "xyz.openbmc_project.State.Chassis.PowerState.On", | 
 | 72 |             "xyz.openbmc_project.State.Host.HostState.Running", | 
 | 73 |             "xyz.openbmc_project.State.Boot.Progress.ProgressStages.MotherboardInit", | 
 | 74 |             "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus.Inactive" | 
 | 75 |         ), | 
 | 76 |     }, | 
 | 77 |     'Booted':  # Valid state when Host is booted. | 
 | 78 |     { | 
 | 79 |         # (BMC , Chassis , Host , BootProgress, OperatingSystemState) | 
 | 80 |         ( | 
 | 81 |             "xyz.openbmc_project.State.BMC.BMCState.Ready", | 
 | 82 |             "xyz.openbmc_project.State.Chassis.PowerState.On", | 
 | 83 |             "xyz.openbmc_project.State.Host.HostState.Running", | 
 | 84 |             "xyz.openbmc_project.State.Boot.Progress.ProgressStages.OSStart", | 
 | 85 |             "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus.BootComplete" | 
 | 86 |         ), | 
 | 87 |     }, | 
 | 88 |     'ResetReload':  # Valid state BMC reset reload when host is booted. | 
 | 89 |     { | 
 | 90 |         # (BMC , Chassis , Host , BootProgress, OperatingSystemState) | 
 | 91 |         ( | 
 | 92 |             "xyz.openbmc_project.State.BMC.BMCState.Ready", | 
 | 93 |             "xyz.openbmc_project.State.Chassis.PowerState.On", | 
 | 94 |             "xyz.openbmc_project.State.Host.HostState.Running", | 
 | 95 |             "xyz.openbmc_project.State.Boot.Progress.ProgressStages.OSStart", | 
 | 96 |             "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus.BootComplete" | 
 | 97 |         ), | 
| George Keishing | df9ad39 | 2017-01-25 13:01:15 -0600 | [diff] [blame] | 98 |     }, | 
 | 99 | } | 
| George Keishing | 90b555a | 2021-05-20 11:54:16 -0500 | [diff] [blame] | 100 | REDFISH_VALID_BOOT_STATES = { | 
 | 101 |     'Off':  # Valid states when Host is Off. | 
 | 102 |     { | 
 | 103 |         # (BMC , Chassis , Host , BootProgress) | 
 | 104 |         ( | 
 | 105 |             "Enabled", | 
 | 106 |             "Off", | 
 | 107 |             "Disabled", | 
 | 108 |             "None", | 
 | 109 |         ), | 
 | 110 |     }, | 
 | 111 |     'Reboot':  # Valid states when BMC reset to standby. | 
 | 112 |     { | 
 | 113 |         # (BMC , Chassis , Host , BootProgress) | 
 | 114 |         ( | 
 | 115 |             "Enabled", | 
 | 116 |             "Off", | 
 | 117 |             "Disabled", | 
 | 118 |             "None", | 
 | 119 |         ), | 
 | 120 |     }, | 
 | 121 |     'Running':  # Valid states when Host is powering on. | 
 | 122 |     { | 
 | 123 |         # (BMC , Chassis , Host , BootProgress) | 
 | 124 |         ( | 
 | 125 |             "Enabled", | 
 | 126 |             "On", | 
 | 127 |             "Enabled", | 
 | 128 |             "OSRunning", | 
 | 129 |         ), | 
 | 130 |     }, | 
 | 131 |     'Booted':  # Valid state when Host is booted. | 
 | 132 |     { | 
 | 133 |         # (BMC , Chassis , Host , BootProgress) | 
 | 134 |         ( | 
 | 135 |             "Enabled", | 
 | 136 |             "On", | 
 | 137 |             "Enabled", | 
 | 138 |             "OSRunning", | 
 | 139 |         ), | 
 | 140 |     }, | 
 | 141 |     'ResetReload':  # Valid state BMC reset reload when host is booted. | 
 | 142 |     { | 
 | 143 |         # (BMC , Chassis , Host , BootProgress) | 
 | 144 |         ( | 
 | 145 |             "Enabled", | 
 | 146 |             "On", | 
 | 147 |             "Enabled", | 
 | 148 |             "OSRunning", | 
 | 149 |         ), | 
 | 150 |     }, | 
 | 151 | } | 
| George Keishing | df9ad39 | 2017-01-25 13:01:15 -0600 | [diff] [blame] | 152 |  | 
| Konstantin Aladyshev | d78dc93 | 2021-03-24 18:17:17 +0300 | [diff] [blame] | 153 | if platform_arch_type == "x86": | 
 | 154 |     VALID_BOOT_STATES_X86 = {} | 
 | 155 |     for state_name, state_set in VALID_BOOT_STATES.items(): | 
 | 156 |         VALID_BOOT_STATES_X86[state_name] = set() | 
 | 157 |         for state_tuple in state_set: | 
 | 158 |             state_tuple_new = tuple( | 
 | 159 |                 x | 
 | 160 |                 for x in state_tuple | 
 | 161 |                 if not ( | 
 | 162 |                     x.startswith("xyz.openbmc_project.State.Boot.Progress") | 
 | 163 |                     or x.startswith("xyz.openbmc_project.State.OperatingSystem") | 
 | 164 |                 ) | 
 | 165 |             ) | 
 | 166 |             VALID_BOOT_STATES_X86[state_name].add(state_tuple_new) | 
 | 167 |     VALID_BOOT_STATES = VALID_BOOT_STATES_X86 | 
 | 168 |  | 
| George Keishing | df9ad39 | 2017-01-25 13:01:15 -0600 | [diff] [blame] | 169 |  | 
 | 170 | class state_map(): | 
 | 171 |  | 
| George Keishing | 678b65c | 2017-08-31 16:16:39 -0500 | [diff] [blame] | 172 |     def get_boot_state(self): | 
| George Keishing | df9ad39 | 2017-01-25 13:01:15 -0600 | [diff] [blame] | 173 |         r""" | 
| George Keishing | 678b65c | 2017-08-31 16:16:39 -0500 | [diff] [blame] | 174 |         Return the system state as a tuple of bmc, chassis, host state, | 
 | 175 |         BootProgress and OperatingSystemState. | 
| George Keishing | df9ad39 | 2017-01-25 13:01:15 -0600 | [diff] [blame] | 176 |         """ | 
| George Keishing | 678b65c | 2017-08-31 16:16:39 -0500 | [diff] [blame] | 177 |  | 
| Joy Onyerikwu | 004ad3c | 2018-06-11 16:29:56 -0500 | [diff] [blame] | 178 |         status, state = keyword.run_key("Read Properties  " | 
 | 179 |                                         + var.SYSTEM_STATE_URI + "enumerate") | 
| George Keishing | 678b65c | 2017-08-31 16:16:39 -0500 | [diff] [blame] | 180 |         bmc_state = state[var.SYSTEM_STATE_URI + 'bmc0']['CurrentBMCState'] | 
 | 181 |         chassis_state = \ | 
 | 182 |             state[var.SYSTEM_STATE_URI + 'chassis0']['CurrentPowerState'] | 
 | 183 |         host_state = state[var.SYSTEM_STATE_URI + 'host0']['CurrentHostState'] | 
| Konstantin Aladyshev | d78dc93 | 2021-03-24 18:17:17 +0300 | [diff] [blame] | 184 |         if platform_arch_type == "x86": | 
 | 185 |             return (str(bmc_state), | 
 | 186 |                     str(chassis_state), | 
 | 187 |                     str(host_state)) | 
 | 188 |         else: | 
 | 189 |             boot_state = state[var.SYSTEM_STATE_URI + 'host0']['BootProgress'] | 
 | 190 |             os_state = \ | 
 | 191 |                 state[var.SYSTEM_STATE_URI + 'host0']['OperatingSystemState'] | 
| George Keishing | 678b65c | 2017-08-31 16:16:39 -0500 | [diff] [blame] | 192 |  | 
| Konstantin Aladyshev | d78dc93 | 2021-03-24 18:17:17 +0300 | [diff] [blame] | 193 |             return (str(bmc_state), | 
 | 194 |                     str(chassis_state), | 
 | 195 |                     str(host_state), | 
 | 196 |                     str(boot_state), | 
 | 197 |                     str(os_state)) | 
| George Keishing | df9ad39 | 2017-01-25 13:01:15 -0600 | [diff] [blame] | 198 |  | 
 | 199 |     def valid_boot_state(self, boot_type, state_set): | 
 | 200 |         r""" | 
 | 201 |         Validate a given set of states is valid. | 
 | 202 |  | 
| George Keishing | 678b65c | 2017-08-31 16:16:39 -0500 | [diff] [blame] | 203 |         Description of argument(s): | 
| Joy Onyerikwu | 004ad3c | 2018-06-11 16:29:56 -0500 | [diff] [blame] | 204 |         boot_type                   Boot type (e.g. off/running/host booted | 
 | 205 |                                     etc.) | 
 | 206 |         state_set                   State set (e.g.bmc,chassis,host, | 
 | 207 |                                     BootProgress,OperatingSystemState) | 
| George Keishing | df9ad39 | 2017-01-25 13:01:15 -0600 | [diff] [blame] | 208 |         """ | 
| George Keishing | 678b65c | 2017-08-31 16:16:39 -0500 | [diff] [blame] | 209 |  | 
 | 210 |         if state_set in set(VALID_BOOT_STATES[boot_type]): | 
| George Keishing | df9ad39 | 2017-01-25 13:01:15 -0600 | [diff] [blame] | 211 |             return True | 
 | 212 |         else: | 
 | 213 |             return False | 
| George Keishing | 90b555a | 2021-05-20 11:54:16 -0500 | [diff] [blame] | 214 |  | 
 | 215 |     def redfish_valid_boot_state(self, boot_type, state_dict): | 
 | 216 |         r""" | 
 | 217 |         Validate a given set of states is valid. | 
 | 218 |  | 
 | 219 |         Description of argument(s): | 
 | 220 |         boot_type                   Boot type (e.g. off/running/host booted | 
 | 221 |                                     etc.) | 
 | 222 |         state_dict                  State dictionary. | 
 | 223 |         """ | 
 | 224 |  | 
 | 225 |         if set(state_dict.values()) in set(REDFISH_VALID_BOOT_STATES[boot_type]): | 
 | 226 |             return True | 
 | 227 |         else: | 
 | 228 |             return False |