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
25# We will build eventually the mapping for warm, cold reset as well.
26VALID_STATES = {
27    'reboot':
28    {
29        # (Power Policy, BMC state, Chassis State, Host State)
30        ('LEAVE_OFF', 'Ready', 'Off', 'Off'),
31        ('ALWAYS_POWER_ON', 'Ready', 'On', 'Running'),
32        ('ALWAYS_POWER_ON', 'Ready', 'On', 'Off'),
33        ('RESTORE_LAST_STATE', 'Ready', 'On', 'Running'),
34        ('RESTORE_LAST_STATE', 'Ready', 'On', 'Off'),
35        ('ALWAYS_POWER_OFF', 'Ready', 'On', 'Running'),
36        ('ALWAYS_POWER_OFF', 'Ready', 'Off', 'Off'),
37    },
38}
39
40VALID_BOOT_STATES = {
41    'Off':  # Valid states when Host is Off.
42    {
43        # (BMC , Chassis , Host , BootProgress, OperatingSystemState)
44        (
45            "xyz.openbmc_project.State.BMC.BMCState.Ready",
46            "xyz.openbmc_project.State.Chassis.PowerState.Off",
47            "xyz.openbmc_project.State.Host.HostState.Off",
48            "xyz.openbmc_project.State.Boot.Progress.ProgressStages.Unspecified",
49            "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus.Inactive"
50        ),
51    },
52    'Reboot':  # Valid states when BMC reset to standby.
53    {
54        # (BMC , Chassis , Host , BootProgress, OperatingSystemState)
55        (
56            "xyz.openbmc_project.State.BMC.BMCState.Ready",
57            "xyz.openbmc_project.State.Chassis.PowerState.Off",
58            "xyz.openbmc_project.State.Host.HostState.Off",
59            "xyz.openbmc_project.State.Boot.Progress.ProgressStages.Unspecified",
60            "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus.Inactive"
61        ),
62    },
63    'Running':  # Valid states when Host is powering on.
64    {
65        # (BMC , Chassis , Host , BootProgress, OperatingSystemState)
66        (
67            "xyz.openbmc_project.State.BMC.BMCState.Ready",
68            "xyz.openbmc_project.State.Chassis.PowerState.On",
69            "xyz.openbmc_project.State.Host.HostState.Running",
70            "xyz.openbmc_project.State.Boot.Progress.ProgressStages.MotherboardInit",
71            "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus.Inactive"
72        ),
73    },
74    'Booted':  # Valid state when Host is booted.
75    {
76        # (BMC , Chassis , Host , BootProgress, OperatingSystemState)
77        (
78            "xyz.openbmc_project.State.BMC.BMCState.Ready",
79            "xyz.openbmc_project.State.Chassis.PowerState.On",
80            "xyz.openbmc_project.State.Host.HostState.Running",
81            "xyz.openbmc_project.State.Boot.Progress.ProgressStages.OSStart",
82            "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus.BootComplete"
83        ),
84    },
85    'ResetReload':  # Valid state BMC reset reload when host is booted.
86    {
87        # (BMC , Chassis , Host , BootProgress, OperatingSystemState)
88        (
89            "xyz.openbmc_project.State.BMC.BMCState.Ready",
90            "xyz.openbmc_project.State.Chassis.PowerState.On",
91            "xyz.openbmc_project.State.Host.HostState.Running",
92            "xyz.openbmc_project.State.Boot.Progress.ProgressStages.OSStart",
93            "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus.BootComplete"
94        ),
95    },
96}
97
98
99class state_map():
100
101    def get_boot_state(self):
102        r"""
103        Return the system state as a tuple of bmc, chassis, host state,
104        BootProgress and OperatingSystemState.
105        """
106
107        status, state = keyword.run_key("Read Properties  "
108                                        + var.SYSTEM_STATE_URI + "enumerate")
109        bmc_state = state[var.SYSTEM_STATE_URI + 'bmc0']['CurrentBMCState']
110        chassis_state = \
111            state[var.SYSTEM_STATE_URI + 'chassis0']['CurrentPowerState']
112        host_state = state[var.SYSTEM_STATE_URI + 'host0']['CurrentHostState']
113        boot_state = state[var.SYSTEM_STATE_URI + 'host0']['BootProgress']
114        os_state = \
115            state[var.SYSTEM_STATE_URI + 'host0']['OperatingSystemState']
116
117        return (str(bmc_state),
118                str(chassis_state),
119                str(host_state),
120                str(boot_state),
121                str(os_state))
122
123    def valid_boot_state(self, boot_type, state_set):
124        r"""
125        Validate a given set of states is valid.
126
127        Description of argument(s):
128        boot_type                   Boot type (e.g. off/running/host booted
129                                    etc.)
130        state_set                   State set (e.g.bmc,chassis,host,
131                                    BootProgress,OperatingSystemState)
132        """
133
134        if state_set in set(VALID_BOOT_STATES[boot_type]):
135            return True
136        else:
137            return False
138