def bmc_power_on():
    r"""
    Power the Open BMC machine on and monitor status to verify.
    """

    grp.rprint_timen("Refreshing state data.")
    state = state_mod.get_state()
    grp.rprint_var(state)

    match_state = state_mod.anchor_state(state)

    grp.rprintn()
    cmd_buf = ["Initiate Power On", "wait=${0}"]
    grp.rpissuing_keyword(cmd_buf)
    power = BuiltIn().run_keyword(*cmd_buf)

    state_change_timeout = BuiltIn().get_variable_value(
        "${STATE_CHANGE_TIMEOUT}", default="1 min")

    # Wait for the state to change in any way.
    state_mod.wait_state(match_state,
                         wait_time=state_change_timeout,
                         interval="3 seconds",
                         invert=1)

    if state_mod.OBMC_STATES_VERSION == 0:
        cmd_buf = [
            "Create Dictionary", "power=${1}", "bmc=HOST_BOOTED",
            "boot_progress=FW Progress, Starting OS"
        ]
    else:
        # TODO: Add back boot_progress when ipmi is enabled on Witherspoon.
        cmd_buf = [
            "Create Dictionary",
            "chassis=On",
            "bmc=Ready",
            #  "boot_progress=FW Progress, Starting OS",
            "host=Running"
        ]
    grp.rdpissuing_keyword(cmd_buf)
    final_state = BuiltIn().run_keyword(*cmd_buf)

    os_host = BuiltIn().get_variable_value("${OS_HOST}", default="")

    if os_host != "":
        final_state['os_ping'] = 1
        final_state['os_login'] = 1
        final_state['os_run_cmd'] = 1

    final_state = state_mod.anchor_state(final_state)

    grp.rprintn()
    power_on_timeout = BuiltIn().get_variable_value("${POWER_ON_TIMEOUT}",
                                                    default="14 mins")
    state_mod.wait_state(final_state,
                         wait_time=power_on_timeout,
                         interval="3 seconds")
def bmc_power_on():

    r"""
    Power the Open BMC machine on and monitor status to verify.
    """

    grp.rprint_timen("Refreshing state data.")
    state = state_mod.get_state()
    grp.rprint_var(state)

    match_state = state_mod.anchor_state(state)

    grp.rprintn()
    cmd_buf = ["Initiate Power On", "wait=${0}"]
    grp.rpissuing_keyword(cmd_buf)
    power = BuiltIn().run_keyword(*cmd_buf)

    state_change_timeout = BuiltIn().get_variable_value(
        "${STATE_CHANGE_TIMEOUT}", default="1 min")

    # Wait for the state to change in any way.
    state_mod.wait_state(match_state, wait_time=state_change_timeout,
                         interval="3 seconds", invert=1)

    if state_mod.OBMC_STATES_VERSION == 0:
        cmd_buf = ["Create Dictionary", "power=${1}",
                   "bmc=HOST_BOOTED",
                   "boot_progress=FW Progress, Starting OS"]
    else:
        # TODO: Add back boot_progress when ipmi is enabled on Witherspoon.
        cmd_buf = ["Create Dictionary", "chassis=On",
                   "bmc=Ready",
                   #  "boot_progress=FW Progress, Starting OS",
                   "host=Running"]
    grp.rdpissuing_keyword(cmd_buf)
    final_state = BuiltIn().run_keyword(*cmd_buf)

    os_host = BuiltIn().get_variable_value("${OS_HOST}", default="")

    if os_host != "":
        final_state['os_ping'] = 1
        final_state['os_login'] = 1
        final_state['os_run_cmd'] = 1

    final_state = state_mod.anchor_state(final_state)

    grp.rprintn()
    power_on_timeout = BuiltIn().get_variable_value(
        "${POWER_ON_TIMEOUT}", default="14 mins")
    state_mod.wait_state(final_state, wait_time=power_on_timeout,
                         interval="3 seconds")
def bmc_power_off():
    r"""
    Power the Open BMC machine off and monitor status to verify.
    """

    grp.rprint_timen("Refreshing state data.")
    state = state_mod.get_state()
    grp.rprint_var(state)

    match_state = state_mod.anchor_state(state)

    grp.rprintn()
    cmd_buf = ["Initiate Power Off"]
    grp.rpissuing_keyword(cmd_buf)
    power = BuiltIn().run_keyword(*cmd_buf)

    state_change_timeout = BuiltIn().get_variable_value(
        "${STATE_CHANGE_TIMEOUT}", default="1 min")

    # Wait for the state to change in any way.
    state_mod.wait_state(match_state,
                         wait_time=state_change_timeout,
                         interval="3 seconds",
                         invert=1)

    if state_mod.OBMC_STATES_VERSION == 0:
        cmd_buf = [
            "Create Dictionary", "power=${0}", "bmc=HOST_POWERED_OFF",
            "boot_progress=Off"
        ]
    else:
        # TODO: Add back boot_progress when ipmi is enabled on Witherspoon.
        cmd_buf = [
            "Create Dictionary",
            "chassis=Off",
            "bmc=Ready",
            #  "boot_progress=Off",
            "host=Off"
        ]
    grp.rdpissuing_keyword(cmd_buf)
    final_state = BuiltIn().run_keyword(*cmd_buf)

    final_state = state_mod.anchor_state(final_state)

    grp.rprintn()
    power_off_timeout = BuiltIn().get_variable_value("${POWER_OFF_TIMEOUT}",
                                                     default="2 mins")
    state_mod.wait_state(final_state,
                         wait_time=power_off_timeout,
                         interval="3 seconds")
def bmc_power_off():

    r"""
    Power the Open BMC machine off and monitor status to verify.
    """

    grp.rprint_timen("Refreshing state data.")
    state = state_mod.get_state()
    grp.rprint_var(state)

    match_state = state_mod.anchor_state(state)

    grp.rprintn()
    cmd_buf = ["Initiate Power Off"]
    grp.rpissuing_keyword(cmd_buf)
    power = BuiltIn().run_keyword(*cmd_buf)

    state_change_timeout = BuiltIn().get_variable_value(
        "${STATE_CHANGE_TIMEOUT}", default="1 min")

    # Wait for the state to change in any way.
    state_mod.wait_state(match_state, wait_time=state_change_timeout,
                         interval="3 seconds", invert=1)

    if state_mod.OBMC_STATES_VERSION == 0:
        cmd_buf = ["Create Dictionary", "power=${0}",
                   "bmc=HOST_POWERED_OFF", "boot_progress=Off"]
    else:
        # TODO: Add back boot_progress when ipmi is enabled on Witherspoon.
        cmd_buf = ["Create Dictionary", "chassis=Off",
                   "bmc=Ready",
                   #  "boot_progress=Off",
                   "host=Off"]
    grp.rdpissuing_keyword(cmd_buf)
    final_state = BuiltIn().run_keyword(*cmd_buf)

    final_state = state_mod.anchor_state(final_state)

    grp.rprintn()
    power_off_timeout = BuiltIn().get_variable_value(
        "${POWER_OFF_TIMEOUT}", default="2 mins")
    state_mod.wait_state(final_state, wait_time=power_off_timeout,
                         interval="3 seconds")
def get_state(openbmc_host="",
              openbmc_username="",
              openbmc_password="",
              os_host="",
              os_username="",
              os_password="",
              req_states=default_req_states,
              quiet=None):
    r"""
    Get component states such as chassis state, bmc state, etc, put them into a
    dictionary and return them to the caller.

    Note that all substate values are strings.

    Description of arguments:
    openbmc_host      The DNS name or IP address of the BMC.
                      This defaults to global ${OPENBMC_HOST}.
    openbmc_username  The username to be used to login to the BMC.
                      This defaults to global ${OPENBMC_USERNAME}.
    openbmc_password  The password to be used to login to the BMC.
                      This defaults to global ${OPENBMC_PASSWORD}.
    os_host           The DNS name or IP address of the operating system.
                      This defaults to global ${OS_HOST}.
    os_username       The username to be used to login to the OS.
                      This defaults to global ${OS_USERNAME}.
    os_password       The password to be used to login to the OS.
                      This defaults to global ${OS_PASSWORD}.
    req_states        This is a list of states whose values are being requested
                      by the caller.
    quiet             Indicates whether status details (e.g. curl commands)
                      should be written to the console.
                      Defaults to either global value of ${QUIET} or to 1.
    """

    quiet = int(gp.get_var_value(quiet, 0))

    # Set parm defaults where necessary and validate all parms.
    if openbmc_host == "":
        openbmc_host = BuiltIn().get_variable_value("${OPENBMC_HOST}")
    error_message = gv.svalid_value(openbmc_host,
                                    var_name="openbmc_host",
                                    invalid_values=[None, ""])
    if error_message != "":
        BuiltIn().fail(gp.sprint_error(error_message))

    if openbmc_username == "":
        openbmc_username = BuiltIn().get_variable_value("${OPENBMC_USERNAME}")
    error_message = gv.svalid_value(openbmc_username,
                                    var_name="openbmc_username",
                                    invalid_values=[None, ""])
    if error_message != "":
        BuiltIn().fail(gp.sprint_error(error_message))

    if openbmc_password == "":
        openbmc_password = BuiltIn().get_variable_value("${OPENBMC_PASSWORD}")
    error_message = gv.svalid_value(openbmc_password,
                                    var_name="openbmc_password",
                                    invalid_values=[None, ""])
    if error_message != "":
        BuiltIn().fail(gp.sprint_error(error_message))

    # NOTE: OS parms are optional.
    if os_host == "":
        os_host = BuiltIn().get_variable_value("${OS_HOST}")
        if os_host is None:
            os_host = ""

    if os_username is "":
        os_username = BuiltIn().get_variable_value("${OS_USERNAME}")
        if os_username is None:
            os_username = ""

    if os_password is "":
        os_password = BuiltIn().get_variable_value("${OS_PASSWORD}")
        if os_password is None:
            os_password = ""

    invalid_req_states = [
        sub_state for sub_state in req_states
        if sub_state not in valid_req_states
    ]
    if len(invalid_req_states) > 0:
        error_message = "The following req_states are not supported:\n" +\
            gp.sprint_var(invalid_req_states)
        BuiltIn().fail(gp.sprint_error(error_message))

    # Initialize all substate values supported by this function.
    ping = 0
    packet_loss = ''
    uptime = ''
    epoch_seconds = ''
    rest = ''
    chassis = ''
    requested_chassis = ''
    bmc = ''
    requested_bmc = ''
    boot_progress = ''
    operating_system = ''
    host = ''
    requested_host = ''
    attempts_left = ''

    # Get the component states.
    if 'ping' in req_states:
        # See if the OS pings.
        cmd_buf = "ping -c 1 -w 2 " + openbmc_host
        if not quiet:
            gp.pissuing(cmd_buf)
        rc, out_buf = commands.getstatusoutput(cmd_buf)
        if rc == 0:
            ping = 1

    if 'packet_loss' in req_states:
        # See if the OS pings.
        cmd_buf = "ping -c 5 -w 5 " + openbmc_host +\
            " | egrep 'packet loss' | sed -re 's/.* ([0-9]+)%.*/\\1/g'"
        if not quiet:
            gp.pissuing(cmd_buf)
        rc, out_buf = commands.getstatusoutput(cmd_buf)
        if rc == 0:
            packet_loss = out_buf.rstrip("\n")

    if 'uptime' in req_states:
        # Sometimes reading uptime results in a blank value. Call with
        # wait_until_keyword_succeeds to ensure a non-blank value is obtained.
        remote_cmd_buf = "read uptime filler 2>/dev/null < /proc/uptime" +\
            " && [ ! -z \"${uptime}\" ] && echo ${uptime}"
        cmd_buf = [
            "BMC Execute Command",
            re.sub('\\$', '\\$', remote_cmd_buf), 'quiet=1'
        ]
        if not quiet:
            grp.rpissuing_keyword(cmd_buf)
            grp.rpissuing(remote_cmd_buf)
        try:
            stdout, stderr, rc =\
                BuiltIn().wait_until_keyword_succeeds("10 sec", "0 sec",
                                                      *cmd_buf)
            if rc == 0 and stderr == "":
                uptime = stdout
        except AssertionError as my_assertion_error:
            pass

    if 'epoch_seconds' in req_states:
        date_cmd_buf = "date -u +%s"
        if USE_BMC_EPOCH_TIME:
            cmd_buf = ["BMC Execute Command", date_cmd_buf, 'quiet=${1}']
            if not quiet:
                grp.rpissuing_keyword(cmd_buf)
            status, ret_values = \
                BuiltIn().run_keyword_and_ignore_error(*cmd_buf)
            if status == "PASS":
                stdout, stderr, rc = ret_values
                if rc == 0 and stderr == "":
                    epoch_seconds = stdout.rstrip("\n")
        else:
            shell_rc, out_buf = gc.cmd_fnc_u(date_cmd_buf,
                                             quiet=quiet,
                                             print_output=0)
            if shell_rc == 0:
                epoch_seconds = out_buf.rstrip("\n")

    master_req_rest = [
        'rest', 'host', 'requested_host', 'operating_system', 'attempts_left',
        'boot_progress', 'chassis', 'requested_chassis'
        'bmc'
        'requested_bmc'
    ]

    req_rest = [
        sub_state for sub_state in req_states if sub_state in master_req_rest
    ]
    need_rest = (len(req_rest) > 0)
    state = DotDict()
    if need_rest:
        cmd_buf = [
            "Read Properties", SYSTEM_STATE_URI + "enumerate",
            "quiet=${" + str(quiet) + "}"
        ]
        grp.rdpissuing_keyword(cmd_buf)
        status, ret_values = \
            BuiltIn().run_keyword_and_ignore_error(*cmd_buf)
        if status == "PASS":
            state['rest'] = '1'
        else:
            state['rest'] = '0'

        if int(state['rest']):
            for url_path in ret_values:
                for attr_name in ret_values[url_path]:
                    # Create a state key value based on the attr_name.
                    if isinstance(ret_values[url_path][attr_name], unicode):
                        ret_values[url_path][attr_name] = \
                            re.sub(r'.*\.', "",
                                   ret_values[url_path][attr_name])
                    # Do some key name manipulations.
                    new_attr_name = re.sub(r'^Current|(State|Transition)$', "",
                                           attr_name)
                    new_attr_name = re.sub(r'BMC', r'Bmc', new_attr_name)
                    new_attr_name = re.sub(r'([A-Z][a-z])', r'_\1',
                                           new_attr_name)
                    new_attr_name = new_attr_name.lower().lstrip("_")
                    new_attr_name = re.sub(r'power', r'chassis', new_attr_name)
                    if new_attr_name in req_states:
                        state[new_attr_name] = ret_values[url_path][attr_name]

    for sub_state in req_states:
        if sub_state in state:
            continue
        if sub_state.startswith("os_"):
            # We pass "os_" requests on to get_os_state.
            continue
        cmd_buf = "state['" + sub_state + "'] = str(" + sub_state + ")"
        exec(cmd_buf)

    if os_host == "":
        # The caller has not specified an os_host so as far as we're concerned,
        # it doesn't exist.
        return state

    os_req_states = [
        sub_state for sub_state in req_states if sub_state.startswith('os_')
    ]

    if len(os_req_states) > 0:
        # The caller has specified an os_host and they have requested
        # information on os substates.

        # Based on the information gathered on bmc, we'll try to make a
        # determination of whether the os is even up.  We'll pass the result
        # of that assessment to get_os_state to enhance performance.
        os_up_match = DotDict()
        for sub_state in master_os_up_match:
            if sub_state in req_states:
                os_up_match[sub_state] = master_os_up_match[sub_state]
        os_up = compare_states(state, os_up_match)
        os_state = get_os_state(os_host=os_host,
                                os_username=os_username,
                                os_password=os_password,
                                req_states=os_req_states,
                                os_up=os_up,
                                quiet=quiet)
        # Append os_state dictionary to ours.
        state.update(os_state)

    return state
Exemple #6
0
def set_ffdc_defaults(ffdc_dir_path=None, ffdc_prefix=None):
    r"""
    Set a default value for ffdc_dir_path and ffdc_prefix if they don't
    already have values.  Return both values.

    Description of arguments:
    ffdc_dir_path  The dir path where FFDC data should be put.
    ffdc_prefix    The prefix to be given to each FFDC file name generated.

    NOTE: If global variable ffdc_dir_path_style is set to ${1}, this function
    will create default values in a newer way.  Otherwise, its behavior
    will remain unchanged.
    """

    # Note: Several subordinate functions like 'Get Test Dir and Name' and
    # 'Header Message' expect global variable FFDC_TIME to be set.
    cmd_buf = ["Get Current Time Stamp"]
    grp.rdpissuing_keyword(cmd_buf)
    FFDC_TIME = BuiltIn().run_keyword(*cmd_buf)
    BuiltIn().set_global_variable("${FFDC_TIME}", FFDC_TIME)

    ffdc_dir_path_style = BuiltIn().get_variable_value(
        "${ffdc_dir_path_style}")

    if ffdc_dir_path is None:
        if ffdc_dir_path_style:
            try:
                ffdc_dir_path = os.environ['FFDC_DIR_PATH']
            except KeyError:
                ffdc_dir_path = os.path.dirname(
                    BuiltIn().get_variable_value("${LOG_FILE}")) + "/"
        else:
            FFDC_LOG_PATH = os.getcwd() + "/logs/"
            if FFDC_LOG_PATH is None:
                FFDC_LOG_PATH = ""
            if FFDC_LOG_PATH == "":
                FFDC_LOG_PATH = os.path.dirname(
                    BuiltIn().get_variable_value("${LOG_FILE}")) + "/"
            error_message = gv.svalid_value(FFDC_LOG_PATH,
                                            var_name="FFDC_LOG_PATH")
            if error_message != "":
                error_message = grp.sprint_error_report(error_message)
                BuiltIn().fail(error_message)
            FFDC_LOG_PATH = os.path.normpath(FFDC_LOG_PATH) + os.sep

            cmd_buf = ["Get Test Dir and Name"]
            grp.rpissuing_keyword(cmd_buf)
            suitename, testname = BuiltIn().run_keyword(*cmd_buf)

            ffdc_dir_path = FFDC_LOG_PATH + suitename + "/" + testname + "/"

    # Add trailing slash.
    ffdc_dir_path = os.path.normpath(ffdc_dir_path) + os.sep

    if ffdc_prefix is None:
        FFDC_TIME = BuiltIn().get_variable_value("${FFDC_TIME}")
        if ffdc_prefix is None:
            if ffdc_dir_path_style:
                OPENBMC_HOST = BuiltIn().get_variable_value("${OPENBMC_HOST}")
                OPENBMC_NICKNAME = BuiltIn().get_variable_value(
                    "${OPENBMC_NICKNAME}", default=OPENBMC_HOST)
                ffdc_prefix = OPENBMC_NICKNAME + "." + FFDC_TIME[2:8] + "." +\
                    FFDC_TIME[8:14] + "."
            else:
                ffdc_prefix = FFDC_TIME + "_"

    BuiltIn().set_global_variable("${FFDC_DIR_PATH}", ffdc_dir_path)
    BuiltIn().set_global_variable("${FFDC_PREFIX}", ffdc_prefix)

    return ffdc_dir_path, ffdc_prefix
def get_state(openbmc_host="",
              openbmc_username="",
              openbmc_password="",
              os_host="",
              os_username="",
              os_password="",
              req_states=default_req_states,
              quiet=None):
    r"""
    Get component states such as chassis state, bmc state, etc, put them into a
    dictionary and return them to the caller.

    Note that all substate values are strings.

    Description of arguments:
    openbmc_host      The DNS name or IP address of the BMC.
                      This defaults to global ${OPENBMC_HOST}.
    openbmc_username  The username to be used to login to the BMC.
                      This defaults to global ${OPENBMC_USERNAME}.
    openbmc_password  The password to be used to login to the BMC.
                      This defaults to global ${OPENBMC_PASSWORD}.
    os_host           The DNS name or IP address of the operating system.
                      This defaults to global ${OS_HOST}.
    os_username       The username to be used to login to the OS.
                      This defaults to global ${OS_USERNAME}.
    os_password       The password to be used to login to the OS.
                      This defaults to global ${OS_PASSWORD}.
    req_states        This is a list of states whose values are being requested
                      by the caller.
    quiet             Indicates whether status details (e.g. curl commands)
                      should be written to the console.
                      Defaults to either global value of ${QUIET} or to 1.
    """

    quiet = int(gp.get_var_value(quiet, 0))

    # Set parm defaults where necessary and validate all parms.
    if openbmc_host == "":
        openbmc_host = BuiltIn().get_variable_value("${OPENBMC_HOST}")
    error_message = gv.svalid_value(openbmc_host,
                                    var_name="openbmc_host",
                                    invalid_values=[None, ""])
    if error_message != "":
        BuiltIn().fail(gp.sprint_error(error_message))

    if openbmc_username == "":
        openbmc_username = BuiltIn().get_variable_value("${OPENBMC_USERNAME}")
    error_message = gv.svalid_value(openbmc_username,
                                    var_name="openbmc_username",
                                    invalid_values=[None, ""])
    if error_message != "":
        BuiltIn().fail(gp.sprint_error(error_message))

    if openbmc_password == "":
        openbmc_password = BuiltIn().get_variable_value("${OPENBMC_PASSWORD}")
    error_message = gv.svalid_value(openbmc_password,
                                    var_name="openbmc_password",
                                    invalid_values=[None, ""])
    if error_message != "":
        BuiltIn().fail(gp.sprint_error(error_message))

    # NOTE: OS parms are optional.
    if os_host == "":
        os_host = BuiltIn().get_variable_value("${OS_HOST}")
        if os_host is None:
            os_host = ""

    if os_username is "":
        os_username = BuiltIn().get_variable_value("${OS_USERNAME}")
        if os_username is None:
            os_username = ""

    if os_password is "":
        os_password = BuiltIn().get_variable_value("${OS_PASSWORD}")
        if os_password is None:
            os_password = ""

    invalid_req_states = [
        sub_state for sub_state in req_states
        if sub_state not in valid_req_states
    ]
    if len(invalid_req_states) > 0:
        error_message = "The following req_states are not supported:\n" +\
            gp.sprint_var(invalid_req_states)
        BuiltIn().fail(gp.sprint_error(error_message))

    # Initialize all substate values supported by this function.
    ping = 0
    packet_loss = ''
    uptime = ''
    epoch_seconds = ''
    rest = '1'
    chassis = ''
    bmc = ''
    boot_progress = ''
    host = ''

    # Get the component states.
    if 'ping' in req_states:
        # See if the OS pings.
        cmd_buf = "ping -c 1 -w 2 " + openbmc_host
        if not quiet:
            gp.pissuing(cmd_buf)
        rc, out_buf = commands.getstatusoutput(cmd_buf)
        if rc == 0:
            ping = 1

    if 'packet_loss' in req_states:
        # See if the OS pings.
        cmd_buf = "ping -c 5 -w 5 " + openbmc_host +\
            " | egrep 'packet loss' | sed -re 's/.* ([0-9]+)%.*/\\1/g'"
        if not quiet:
            gp.pissuing(cmd_buf)
        rc, out_buf = commands.getstatusoutput(cmd_buf)
        if rc == 0:
            packet_loss = out_buf.rstrip("\n")

    if 'uptime' in req_states:
        cmd_buf = [
            "BMC Execute Command", "cat /proc/uptime | cut -f 1 -d ' '",
            'quiet=${1}'
        ]
        if not quiet:
            grp.rpissuing_keyword(cmd_buf)
        status, ret_values = \
            BuiltIn().run_keyword_and_ignore_error(*cmd_buf)
        if status == "PASS":
            stdout, stderr, rc = ret_values
            if rc == 0 and stderr == "":
                uptime = stdout

    if 'epoch_seconds' in req_states:
        date_cmd_buf = "date -u +%s"
        if USE_BMC_EPOCH_TIME:
            cmd_buf = ["BMC Execute Command", date_cmd_buf, 'quiet=${1}']
            if not quiet:
                grp.rpissuing_keyword(cmd_buf)
            status, ret_values = \
                BuiltIn().run_keyword_and_ignore_error(*cmd_buf)
            if status == "PASS":
                stdout, stderr, rc = ret_values
                if rc == 0 and stderr == "":
                    epoch_seconds = stdout.rstrip("\n")
        else:
            shell_rc, out_buf = gc.cmd_fnc_u(date_cmd_buf,
                                             quiet=1,
                                             print_output=0)
            if shell_rc == 0:
                epoch_seconds = out_buf.rstrip("\n")

    master_req_rest = ['rest', 'chassis', 'bmc', 'boot_progress', 'host']
    req_rest = [
        sub_state for sub_state in req_states if sub_state in master_req_rest
    ]
    need_rest = (len(req_rest) > 0)

    # Though we could try to determine 'rest' state on any of several calls,
    # for simplicity, we'll use 'chassis' to figure it out (even if the caller
    # hasn't explicitly asked for 'chassis').
    if 'chassis' in req_states or need_rest:
        cmd_buf = ["Get Chassis Power State", "quiet=${" + str(quiet) + "}"]
        grp.rdpissuing_keyword(cmd_buf)
        status, ret_values = \
            BuiltIn().run_keyword_and_ignore_error(*cmd_buf)
        if status == "PASS":
            chassis = ret_values
            chassis = re.sub(r'.*\.', "", chassis)
            rest = '1'
        else:
            rest = ret_values

    if rest == '1':
        if 'bmc' in req_states:
            if OBMC_STATES_VERSION == 0:
                qualifier = "utils"
            else:
                # This will not be supported much longer.
                qualifier = "state_manager"
            cmd_buf = [
                qualifier + ".Get BMC State", "quiet=${" + str(quiet) + "}"
            ]
            grp.rdpissuing_keyword(cmd_buf)
            status, ret_values = \
                BuiltIn().run_keyword_and_ignore_error(*cmd_buf)
            if status == "PASS":
                bmc = ret_values

        if 'boot_progress' in req_states:
            cmd_buf = ["Get Boot Progress", "quiet=${" + str(quiet) + "}"]
            grp.rdpissuing_keyword(cmd_buf)
            status, ret_values = \
                BuiltIn().run_keyword_and_ignore_error(*cmd_buf)
            if status == "PASS":
                boot_progress = ret_values

        if 'host' in req_states:
            if OBMC_STATES_VERSION > 0:
                cmd_buf = ["Get Host State", "quiet=${" + str(quiet) + "}"]
                grp.rdpissuing_keyword(cmd_buf)
                status, ret_values = \
                    BuiltIn().run_keyword_and_ignore_error(*cmd_buf)
                if status == "PASS":
                    host = ret_values
                    # Strip everything up to the final period.
                    host = re.sub(r'.*\.', "", host)

    state = DotDict()
    for sub_state in req_states:
        if sub_state.startswith("os_"):
            # We pass "os_" requests on to get_os_state.
            continue
        cmd_buf = "state['" + sub_state + "'] = str(" + sub_state + ")"
        exec(cmd_buf)

    if os_host == "":
        # The caller has not specified an os_host so as far as we're concerned,
        # it doesn't exist.
        return state

    os_req_states = [
        sub_state for sub_state in req_states if sub_state.startswith('os_')
    ]

    if len(os_req_states) > 0:
        # The caller has specified an os_host and they have requested
        # information on os substates.

        # Based on the information gathered on bmc, we'll try to make a
        # determination of whether the os is even up.  We'll pass the result
        # of that assessment to get_os_state to enhance performance.
        os_up_match = DotDict()
        for sub_state in master_os_up_match:
            if sub_state in req_states:
                os_up_match[sub_state] = master_os_up_match[sub_state]
        os_up = compare_states(state, os_up_match)
        os_state = get_os_state(os_host=os_host,
                                os_username=os_username,
                                os_password=os_password,
                                req_states=os_req_states,
                                os_up=os_up,
                                quiet=quiet)
        # Append os_state dictionary to ours.
        state.update(os_state)

    return state
def get_os_state(os_host="",
                 os_username="",
                 os_password="",
                 req_states=default_os_req_states,
                 os_up=True,
                 quiet=None):
    r"""
    Get component states for the operating system such as ping, login,
    etc, put them into a dictionary and return them to the caller.

    Note that all substate values are strings.

    Description of arguments:
    os_host      The DNS name or IP address of the operating system.
                 This defaults to global ${OS_HOST}.
    os_username  The username to be used to login to the OS.
                 This defaults to global ${OS_USERNAME}.
    os_password  The password to be used to login to the OS.
                 This defaults to global ${OS_PASSWORD}.
    req_states   This is a list of states whose values are being requested by
                 the caller.
    os_up        If the caller knows that the os can't possibly be up, it can
                 improve performance by passing os_up=False.  This function
                 will then simply return default values for all requested os
                 sub states.
    quiet        Indicates whether status details (e.g. curl commands) should
                 be written to the console.
                 Defaults to either global value of ${QUIET} or to 1.
    """

    quiet = int(gp.get_var_value(quiet, 0))

    # Set parm defaults where necessary and validate all parms.
    if os_host == "":
        os_host = BuiltIn().get_variable_value("${OS_HOST}")
    error_message = gv.svalid_value(os_host,
                                    var_name="os_host",
                                    invalid_values=[None, ""])
    if error_message != "":
        BuiltIn().fail(gp.sprint_error(error_message))

    if os_username == "":
        os_username = BuiltIn().get_variable_value("${OS_USERNAME}")
    error_message = gv.svalid_value(os_username,
                                    var_name="os_username",
                                    invalid_values=[None, ""])
    if error_message != "":
        BuiltIn().fail(gp.sprint_error(error_message))

    if os_password == "":
        os_password = BuiltIn().get_variable_value("${OS_PASSWORD}")
    error_message = gv.svalid_value(os_password,
                                    var_name="os_password",
                                    invalid_values=[None, ""])
    if error_message != "":
        BuiltIn().fail(gp.sprint_error(error_message))

    invalid_req_states = [
        sub_state for sub_state in req_states
        if sub_state not in valid_os_req_states
    ]
    if len(invalid_req_states) > 0:
        error_message = "The following req_states are not supported:\n" +\
            gp.sprint_var(invalid_req_states)
        BuiltIn().fail(gp.sprint_error(error_message))

    # Initialize all substate values supported by this function.
    os_ping = 0
    os_login = 0
    os_run_cmd = 0

    if os_up:
        if 'os_ping' in req_states:
            # See if the OS pings.
            cmd_buf = "ping -c 1 -w 2 " + os_host
            if not quiet:
                gp.pissuing(cmd_buf)
            rc, out_buf = commands.getstatusoutput(cmd_buf)
            if rc == 0:
                os_ping = 1

        # Programming note: All attributes which do not require an ssh login
        # should have been processed by this point.
        master_req_login = ['os_login', 'os_run_cmd']
        req_login = [
            sub_state for sub_state in req_states
            if sub_state in master_req_login
        ]
        must_login = (len(req_login) > 0)

        if must_login:
            # Open SSH connection to OS.  Note that this doesn't fail even when
            # the OS is not up.
            cmd_buf = ["SSHLibrary.Open Connection", os_host]
            if not quiet:
                grp.rpissuing_keyword(cmd_buf)
            ix = BuiltIn().run_keyword(*cmd_buf)

            # Login to OS.
            cmd_buf = ["Login", os_username, os_password]
            if not quiet:
                grp.rpissuing_keyword(cmd_buf)
            status, ret_values = \
                BuiltIn().run_keyword_and_ignore_error(*cmd_buf)
            if status == "PASS":
                os_login = 1
            else:
                gp.dprint_var(status)
                gp.dprint_var(ret_values)

            if os_login:
                if 'os_run_cmd' in req_states:
                    # Try running a simple command (uptime) on the OS.
                    cmd_buf = [
                        "Execute Command", "uptime", "return_stderr=True",
                        "return_rc=True"
                    ]
                    if not quiet:
                        grp.rpissuing_keyword(cmd_buf)
                    # Note that in spite of its name, there are occasions
                    # where run_keyword_and_ignore_error can fail.
                    status, ret_values = \
                        BuiltIn().run_keyword_and_ignore_error(*cmd_buf)
                    if status == "PASS":
                        stdout, stderr, rc = ret_values
                        if rc == 0 and stderr == "":
                            os_run_cmd = 1
                        else:
                            gp.dprint_var(status)
                            gp.dprint_var(stdout)
                            gp.dprint_var(stderr)
                            gp.dprint_var(rc)
                    else:
                        gp.dprint_var(status)
                        gp.dprint_var(ret_values)

    os_state = DotDict()
    for sub_state in req_states:
        cmd_buf = "os_state['" + sub_state + "'] = str(" + sub_state + ")"
        exec(cmd_buf)

    return os_state
def set_ffdc_defaults(ffdc_dir_path=None,
                      ffdc_prefix=None):
    r"""
    Set a default value for ffdc_dir_path and ffdc_prefix if they don't
    already have values.  Return both values.

    Description of arguments:
    ffdc_dir_path  The dir path where FFDC data should be put.
    ffdc_prefix    The prefix to be given to each FFDC file name generated.

    NOTE: If global variable ffdc_dir_path_style is set to ${1}, this function
    will create default values in a newer way.  Otherwise, its behavior
    will remain unchanged.
    """

    # Note: Several subordinate functions like 'Get Test Dir and Name' and
    # 'Header Message' expect global variable FFDC_TIME to be set.
    cmd_buf = ["Get Current Time Stamp"]
    grp.rdpissuing_keyword(cmd_buf)
    FFDC_TIME = BuiltIn().run_keyword(*cmd_buf)
    BuiltIn().set_global_variable("${FFDC_TIME}", FFDC_TIME)

    ffdc_dir_path_style = BuiltIn().get_variable_value(
        "${ffdc_dir_path_style}")

    if ffdc_dir_path is None:
        if ffdc_dir_path_style:
            try:
                ffdc_dir_path = os.environ['FFDC_DIR_PATH']
            except KeyError:
                ffdc_dir_path = os.path.dirname(
                    BuiltIn().get_variable_value("${LOG_FILE}")) + "/"
        else:
            FFDC_LOG_PATH = os.getcwd() + "/logs/"
            if FFDC_LOG_PATH is None:
                FFDC_LOG_PATH = ""
            if FFDC_LOG_PATH == "":
                FFDC_LOG_PATH = os.path.dirname(
                    BuiltIn().get_variable_value("${LOG_FILE}")) + "/"
            error_message = gv.svalid_value(FFDC_LOG_PATH,
                                            var_name="FFDC_LOG_PATH")
            if error_message != "":
                error_message = grp.sprint_error_report(error_message)
                BuiltIn().fail(error_message)
            FFDC_LOG_PATH = os.path.normpath(FFDC_LOG_PATH) + os.sep

            cmd_buf = ["Get Test Dir and Name"]
            grp.rpissuing_keyword(cmd_buf)
            suitename, testname = BuiltIn().run_keyword(*cmd_buf)

            ffdc_dir_path = FFDC_LOG_PATH + suitename + "/" + testname + "/"

    # Add trailing slash.
    ffdc_dir_path = os.path.normpath(ffdc_dir_path) + os.sep

    if ffdc_prefix is None:
        FFDC_TIME = BuiltIn().get_variable_value("${FFDC_TIME}")
        if ffdc_prefix is None:
            if ffdc_dir_path_style:
                OPENBMC_HOST = BuiltIn().get_variable_value("${OPENBMC_HOST}")
                OPENBMC_NICKNAME = BuiltIn().get_variable_value(
                    "${OPENBMC_NICKNAME}", default=OPENBMC_HOST)
                ffdc_prefix = OPENBMC_NICKNAME + "." + FFDC_TIME[2:8] + "." +\
                    FFDC_TIME[8:14] + "."
            else:
                ffdc_prefix = FFDC_TIME + "_"

    BuiltIn().set_global_variable("${FFDC_DIR_PATH}", ffdc_dir_path)
    BuiltIn().set_global_variable("${FFDC_PREFIX}", ffdc_prefix)

    return ffdc_dir_path, ffdc_prefix
def ffdc(ffdc_dir_path=None,
         ffdc_prefix=None,
         ffdc_function_list=""):

    r"""
    Gather First Failure Data Capture (FFDC).

    This includes:
    - Set global FFDC_TIME.
    - Create FFDC work space directory.
    - Write test info details.
    - Call BMC methods to write/collect FFDC data.

    Description of arguments:
    ffdc_dir_path       The dir path where FFDC data should be put.
    ffdc_prefix         The prefix to be given to each FFDC file name
                        generated.
    ffdc_function_list  A colon-delimited list of all the types of FFDC data
                        you wish to have collected.  A blank value means that
                        all possible kinds of FFDC are to be collected.  See
                        FFDC_METHOD_CALL object in lib/openbmc_ffdc_list.py
                        for possible choices.
    """

    # Check if Ping and SSH connection is alive
    OPENBMC_HOST = BuiltIn().get_variable_value("${OPENBMC_HOST}")
    status, status_ping = grk.run_key("Ping Host  " + OPENBMC_HOST)
    grp.rprint_var(status_ping)
    if status_ping:
        status_ssh = \
            BuiltIn().run_keyword_and_return_status("Open Connection And" +
                                                    " Log In")
        grp.rprint_var(status_ssh)
        if not status_ssh:
            grp.rprint_error("BMC is not communicating. \
                              Aborting FFDC collection.\n")
            BuiltIn().run_keyword_and_return_status("Close All Connections")
            return

    grp.rprint_timen("Collecting FFDC.")

    # Get default values for arguments.
    ffdc_dir_path, ffdc_prefix = set_ffdc_defaults(ffdc_dir_path, ffdc_prefix)
    grp.rprint_var(ffdc_dir_path)
    grp.rprint_var(ffdc_prefix)

    # LOG_PREFIX is used by subordinate functions.
    LOG_PREFIX = ffdc_dir_path + ffdc_prefix
    BuiltIn().set_global_variable("${LOG_PREFIX}", LOG_PREFIX)

    cmd_buf = ["Create Directory", ffdc_dir_path]
    grp.rpissuing_keyword(cmd_buf)
    status, output = BuiltIn().run_keyword_and_ignore_error(*cmd_buf)
    if status != "PASS":
        error_message = grp.sprint_error_report("Create Directory failed" +
                                                " with the following" +
                                                " error:\n" + output)
        BuiltIn().fail(error_message)

    # FFDC_FILE_PATH is used by Header Message.
    FFDC_FILE_PATH = ffdc_dir_path + ffdc_prefix + "BMC_general.txt"
    BuiltIn().set_global_variable("${FFDC_FILE_PATH}", FFDC_FILE_PATH)

    grk.run_key("Header Message")

    grk.run_key_u("Call FFDC Methods  ffdc_function_list=" +
                  ffdc_function_list)

    grp.rprint_timen("Finished collecting FFDC.")