1#!/usr/bin/env python
2
3r"""
4State Manager module:
5
6   - Defines Valid states of the system
7
8"""
9import os
10import re
11import sys
12
13from robot.libraries.BuiltIn import BuiltIn
14
15robot_pgm_dir_path = os.path.dirname(__file__) + os.sep
16repo_data_dir_path = re.sub('/lib', '/data', robot_pgm_dir_path)
17sys.path.append(repo_data_dir_path)
18
19import gen_robot_keyword as keyword
20import variables as var
21
22BuiltIn().import_resource("state_manager.robot")
23BuiltIn().import_resource("rest_client.robot")
24
25platform_arch_type = os.environ.get('PLATFORM_ARCH_TYPE', '') or \
26    BuiltIn().get_variable_value("${PLATFORM_ARCH_TYPE}", default="power")
27
28# We will build eventually the mapping for warm, cold reset as well.
29VALID_STATES = {
30    'reboot':
31    {
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'),
38        ('ALWAYS_POWER_OFF', 'Ready', 'On', 'Running'),
39        ('ALWAYS_POWER_OFF', 'Ready', 'Off', 'Off'),
40    },
41}
42
43VALID_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        ),
98    },
99}
100
101if platform_arch_type == "x86":
102    VALID_BOOT_STATES_X86 = {}
103    for state_name, state_set in VALID_BOOT_STATES.items():
104        VALID_BOOT_STATES_X86[state_name] = set()
105        for state_tuple in state_set:
106            state_tuple_new = tuple(
107                x
108                for x in state_tuple
109                if not (
110                    x.startswith("xyz.openbmc_project.State.Boot.Progress")
111                    or x.startswith("xyz.openbmc_project.State.OperatingSystem")
112                )
113            )
114            VALID_BOOT_STATES_X86[state_name].add(state_tuple_new)
115    VALID_BOOT_STATES = VALID_BOOT_STATES_X86
116
117
118class state_map():
119
120    def get_boot_state(self):
121        r"""
122        Return the system state as a tuple of bmc, chassis, host state,
123        BootProgress and OperatingSystemState.
124        """
125
126        status, state = keyword.run_key("Read Properties  "
127                                        + var.SYSTEM_STATE_URI + "enumerate")
128        bmc_state = state[var.SYSTEM_STATE_URI + 'bmc0']['CurrentBMCState']
129        chassis_state = \
130            state[var.SYSTEM_STATE_URI + 'chassis0']['CurrentPowerState']
131        host_state = state[var.SYSTEM_STATE_URI + 'host0']['CurrentHostState']
132        if platform_arch_type == "x86":
133            return (str(bmc_state),
134                    str(chassis_state),
135                    str(host_state))
136        else:
137            boot_state = state[var.SYSTEM_STATE_URI + 'host0']['BootProgress']
138            os_state = \
139                state[var.SYSTEM_STATE_URI + 'host0']['OperatingSystemState']
140
141            return (str(bmc_state),
142                    str(chassis_state),
143                    str(host_state),
144                    str(boot_state),
145                    str(os_state))
146
147    def valid_boot_state(self, boot_type, state_set):
148        r"""
149        Validate a given set of states is valid.
150
151        Description of argument(s):
152        boot_type                   Boot type (e.g. off/running/host booted
153                                    etc.)
154        state_set                   State set (e.g.bmc,chassis,host,
155                                    BootProgress,OperatingSystemState)
156        """
157
158        if state_set in set(VALID_BOOT_STATES[boot_type]):
159            return True
160        else:
161            return False
162