Example #1
0
def get_sol_info():
    r"""
    Get all SOL info and return it as a dictionary.

    Example use:

    Robot code:
    ${sol_info}=  get_sol_info
    Rpvars  sol_info

    Output:
    sol_info:
      sol_info[Info]:                                SOL parameter 'Payload Channel (7)'
                                                     not supported - defaulting to 0x0e
      sol_info[Character Send Threshold]:            1
      sol_info[Force Authentication]:                true
      sol_info[Privilege Level]:                     USER
      sol_info[Set in progress]:                     set-complete
      sol_info[Retry Interval (ms)]:                 100
      sol_info[Non-Volatile Bit Rate (kbps)]:        IPMI-Over-Serial-Setting
      sol_info[Character Accumulate Level (ms)]:     100
      sol_info[Enabled]:                             true
      sol_info[Volatile Bit Rate (kbps)]:            IPMI-Over-Serial-Setting
      sol_info[Payload Channel]:                     14 (0x0e)
      sol_info[Payload Port]:                        623
      sol_info[Force Encryption]:                    true
      sol_info[Retry Count]:                         7
    """

    status, ret_values = grk.run_key_u("Run IPMI Standard Command  sol info")

    # Create temp file path.
    temp = tempfile.NamedTemporaryFile()
    temp_file_path = temp.name

    # Write sol info to temp file path.
    text_file = open(temp_file_path, "w")
    text_file.write(ret_values)
    text_file.close()

    # Use my_parm_file to interpret data.
    sol_info = gm.my_parm_file(temp_file_path)

    return sol_info
def get_sol_info():

    r"""
    Get all SOL info and return it as a dictionary.

    Example use:

    Robot code:
    ${sol_info}=  get_sol_info
    Rpvars  sol_info

    Output:
    sol_info:
      sol_info[Info]:                                SOL parameter 'Payload Channel (7)' not supported - defaulting to 0x0e
      sol_info[Character Send Threshold]:            1
      sol_info[Force Authentication]:                true
      sol_info[Privilege Level]:                     USER
      sol_info[Set in progress]:                     set-complete
      sol_info[Retry Interval (ms)]:                 100
      sol_info[Non-Volatile Bit Rate (kbps)]:        IPMI-Over-Serial-Setting
      sol_info[Character Accumulate Level (ms)]:     100
      sol_info[Enabled]:                             true
      sol_info[Volatile Bit Rate (kbps)]:            IPMI-Over-Serial-Setting
      sol_info[Payload Channel]:                     14 (0x0e)
      sol_info[Payload Port]:                        623
      sol_info[Force Encryption]:                    true
      sol_info[Retry Count]:                         7
    """

    status, ret_values = grk.run_key_u("Run IPMI Standard Command  sol info")

    # Create temp file path.
    temp = tempfile.NamedTemporaryFile()
    temp_file_path = temp.name

    # Write sol info to temp file path.
    text_file = open(temp_file_path, "w")
    text_file.write(ret_values)
    text_file.close()

    # Use my_parm_file to interpret data.
    sol_info = gm.my_parm_file(temp_file_path)

    return sol_info
def return_plug_vars(general=True, custom=True, plug_in_package_name=None):
    r"""
    Return an OrderedDict which is sorted by key and which contains all of the plug-in environment variables.

    Example excerpt of resulting dictionary:

    plug_var_dict:
      [AUTOBOOT_BASE_TOOL_DIR_PATH]:  /tmp/
      [AUTOBOOT_BB_LEVEL]:            <blank>
      [AUTOBOOT_BOOT_FAIL]:           0
      ...

    This function also does the following:
    - Set a default value for environment variable AUTOBOOT_OPENBMC_NICKNAME/AUTOIPL_FSP1_NICKNAME if it is
      not already set.
    - Register PASSWORD variables to prevent their values from being printed.

    Note: The programmer may set a default for any given environment variable by declaring a global variable
    of the same name and setting its value.  For example, let's say the calling program has this global
    declaration:

    PERF_EXERCISERS_TOTAL_TIMEOUT = '180'

    If environment variable PERF_EXERCISERS_TOTAL_TIMEOUT is blank or not set, this function will set it to
    '180'.

    Furthermore, if such a default variable declaration is not a string, this function will preserve that
    non-string type in setting global variables (with the exception of os.environ values which must be
    string).  Example:

    NVDIMM_ENCRYPT = 0

    Description of argument(s):
    general                         Return general plug-in parms (e.g. those beginning with "AUTOBOOT" or
                                    "AUTOGUI").
    custom                          Return custom plug-in parms (i.e. those beginning with the upper case
                                    name of the plug-in package, for example "OBMC_SAMPLE_PARM1").
    plug_in_package_name            The name of the plug-in package for which custom parms are to be
                                    returned.  The default is the current plug in package name.
    """

    regex_list = []
    if not (general or custom):
        return collections.OrderedDict()
    plug_in_package_name = gm.dft(plug_in_package_name,
                                  get_plug_in_package_name())
    if general:
        regex_list = [PLUG_VAR_PREFIX, "AUTOGUI"]
    if custom:
        regex_list.append(plug_in_package_name.upper())

    regex = "^(" + "|".join(regex_list) + ")_"

    # Set a default for nickname.
    if os.environ.get("AUTOBOOT_OPENBMC_NICKNAME", "") == "":
        os.environ['AUTOBOOT_OPENBMC_NICKNAME'] = \
            os.environ.get("AUTOBOOT_OPENBMC_HOST", "")

    if os.environ.get("AUTOIPL_FSP1_NICKNAME", "") == "":
        os.environ['AUTOIPL_FSP1_NICKNAME'] = \
            os.environ.get("AUTOIPL_FSP1_NAME", "").split(".")[0]

    # For all variables specified in the parm_def file, we want them to default to "" rather than being unset.
    # Process the parm_def file if it exists.
    parm_def_file_path = os.path.dirname(gp.pgm_dir_path.rstrip("/")) + "/" + plug_in_package_name \
        + "/parm_def"
    if os.path.exists(parm_def_file_path):
        parm_defs = gm.my_parm_file(parm_def_file_path)
    else:
        parm_defs = collections.OrderedDict()
    # Example parm_defs:
    # parm_defs:
    #   parm_defs[rest_fail]:           boolean
    #   parm_defs[command]:             string
    #   parm_defs[esel_stop_file_path]: string

    # Create a list of plug-in environment variables by pre-pending <all caps plug-in package name>_<all
    # caps var name>
    plug_in_parm_names = [
        plug_in_package_name.upper() + "_" + x
        for x in map(str.upper, parm_defs.keys())
    ]
    # Example plug_in_parm_names:
    # plug_in_parm_names:
    #  plug_in_parm_names[0]: STOP_REST_FAIL
    #  plug_in_parm_names[1]: STOP_COMMAND
    #  plug_in_parm_names[2]: STOP_ESEL_STOP_FILE_PATH

    # os.environ only accepts string values.  However, if the user defines default values of other types
    # (e.g. int), we wish to preserve the type.
    non_string_defaults = {}
    # Initialize unset plug-in vars.
    for var_name in plug_in_parm_names:
        # If there is a global variable with the same name as the environment variable, use its value as a
        # default.
        default_value = gm.get_mod_global(var_name, "")
        if type(default_value) is not str:
            non_string_defaults[var_name] = type(default_value)
        os.environ[var_name] = os.environ.get(var_name, str(default_value))
        if os.environ[var_name] == "":
            os.environ[var_name] = str(default_value)

    plug_var_dict = \
        collections.OrderedDict(sorted({k: v for (k, v) in
                                        os.environ.items()
                                        if re.match(regex, k)}.items()))
    # Restore the types of any variables where the caller had defined default values.
    for key, value in non_string_defaults.items():
        cmd_buf = "plug_var_dict[key] = " + str(value).split(
            "'")[1] + "(plug_var_dict[key]"
        if value is int:
            # Use int base argument of 0 to allow it to interpret hex strings.
            cmd_buf += ", 0)"
        else:
            cmd_buf += ")"
        exec(cmd_buf) in globals(), locals()
    # Register password values to prevent printing them out.  Any plug var whose name ends in PASSWORD will
    # be registered.
    password_vals = {
        k: v
        for (k, v) in plug_var_dict.items() if re.match(r".*_PASSWORD$", k)
    }.values()
    map(gp.register_passwords, password_vals)

    return plug_var_dict
def rprocess_plug_in_packages(plug_in_packages_list=None,
                              call_point="setup",
                              shell_rc="0x00000000",
                              stop_on_plug_in_failure=1,
                              stop_on_non_zero_rc=0,
                              release_type="obmc",
                              quiet=None,
                              debug=None):
    r"""
    Call the external process_plug_in_packages.py to process the plug-in
    packages.  Return the following:
    rc                              The return code - 0 = PASS, 1 = FAIL.
    shell_rc                        The shell return code returned by
                                    process_plug_in_packages.py.
    failed_plug_in_name             The failed plug in name (if any).

    Description of arguments:
    plug_in_packages_list           A python list of plug-in directory paths.
    call_point                      The call point program to be called for
                                    each plug-in package (e.g. post_boot).
                                    This name should not include the "cp_"
                                    prefix.
    shell_rc                        The user may supply a value other than
                                    zero to indicate an acceptable non-zero
                                    return code.  For example, if this value
                                    equals 0x00000200, it means that for each
                                    plug-in call point that runs, a 0x00000200
                                    will not be counted as a failure.
    stop_on_plug_in_failure         If this parameter is set to 1, this
                                    program will stop and return non-zero if
                                    the call point program from any plug-in
                                    directory fails.  Conversely, if it is set
                                    to false, this program will run the call
                                    point program from each and every plug-in
                                    directory regardless of their return
                                    values.  Typical example cases where you'd
                                    want to run all plug-in call points
                                    regardless of success or failure would be
                                    "cleanup" or "ffdc" call points.
    stop_on_non_zero_rc             If this parm is set to 1 and a plug-in
                                    call point program returns a valid
                                    non-zero return code (see "shell_rc" parm
                                    above), this program will stop processing
                                    and return 0 (success).  Since this
                                    constitutes a successful exit, this would
                                    normally be used where the caller wishes
                                    to stop processing if one of the plug-in
                                    directory call point programs returns a
                                    special value indicating that some special
                                    case has been found.  An example might be
                                    in calling some kind of "check_errl" call
                                    point program.  Such a call point program
                                    might return a 2 (i.e. 0x00000200) to
                                    indicate that a given error log entry was
                                    found in an "ignore" list and is therefore
                                    to be ignored.  That being the case, no
                                    other "check_errl" call point program
                                    would need to be called.
    release_type                    The type of release being tested (e.g.
                                    "obmc", "op", "fips").  This influences
                                    which integrated plug-ins are selected.
    quiet                           If quiet is set to 1, this function will
                                    NOT write status messages to stdout.  This
                                    will default to the global quiet program
                                    parm or to 0.
    debug                           If this parameter is set to 1, this
                                    function will print additional debug
                                    information.  This is mainly to be used by
                                    the developer of this function.  This will
                                    default to the global quiet program parm
                                    or to 0.
    """

    rc = 0

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

    # If there are no plug-in packages to process, return successfully.
    if len(plug_in_packages_list) == 0:
        return 0, 0, ""

    if quiet is None:
        try:
            quiet = int(BuiltIn().get_variable_value("${quiet}"))
        except TypeError:
            quiet = 0

    if debug is None:
        try:
            debug = int(BuiltIn().get_variable_value("${debug}"))
        except TypeError:
            debug = 0

    # Create string from list.
    plug_in_dir_paths = ':'.join(plug_in_packages_list)

    temp = tempfile.NamedTemporaryFile()
    temp_file_path = temp.name
    temp2 = tempfile.NamedTemporaryFile()
    temp_properties_file_path = temp2.name

    if int(debug) == 1:
        os.environ["PERF_TRACE"] = "1"
        debug_string = " --quiet=0"
    else:
        debug_string = ""

    loc_shell_rc = 0

    sub_cmd_buf = "process_plug_in_packages.py" + debug_string +\
                  " --call_point=" + call_point + " --allow_shell_rc=" +\
                  str(shell_rc) + " --stop_on_plug_in_failure=" +\
                  str(stop_on_plug_in_failure) + " --stop_on_non_zero_rc=" +\
                  str(stop_on_non_zero_rc) + " " + plug_in_dir_paths
    if int(quiet) == 1:
        cmd_buf = sub_cmd_buf + " > " + temp_file_path + " 2>&1"
    else:
        cmd_buf = "set -o pipefail ; " + sub_cmd_buf + " 2>&1 | tee " +\
                  temp_file_path

        if int(debug) == 1:
            grp.rpissuing(cmd_buf)
        else:
            grp.rprint_timen("Processing " + call_point +
                             " call point programs.")

    proc_plug_pkg_rc = subprocess.call(cmd_buf,
                                       shell=True,
                                       executable='/bin/bash')

    # As process_plug_in_packages.py help text states, it will print the
    # values of failed_plug_in_name and shell_rc in the following format:
    # failed_plug_in_name:               <failed plug-in value, if any>
    # shell_rc:                          <shell return code value of last
    # call point program>

    # We want to obtain those values from the output.  To make the task
    # simpler, we'll start by grepping the output for lines that might fit
    # such a format:
    # A valid bash variable against the left margin
    # - A colon
    # - Zero or more spaces
    bash_var_regex = "[_[:alpha:]][_[:alnum:]]*"
    regex = "^" + bash_var_regex + ":[ ]*"
    cmd_buf = "egrep '" + regex + "' " + temp_file_path + " > " +\
              temp_properties_file_path
    if int(debug) == 1:
        grp.rpissuing(cmd_buf)
    grep_rc = os.system(cmd_buf)

    # Next we call my_parm_file to create a properties dictionary.
    properties = gm.my_parm_file(temp_properties_file_path)

    # Finally, we access the 2 values that we need.
    try:
        shell_rc = int(properties['shell_rc'], 16)
    except KeyError:
        shell_rc = 0
    try:
        failed_plug_in_name = properties['failed_plug_in_name']
    except KeyError:
        failed_plug_in_name = ""

    if proc_plug_pkg_rc != 0:
        hex = 1
        grp.rprint_error("Call to process_plug_in_packages failed.\n")
        grp.rprint_varx("grep_rc", grep_rc, hex)
        grp.rprint_varx("proc_plug_pkg_rc", proc_plug_pkg_rc, hex)
        # Show all of the failed plug in names and shell_rcs.
        gc.cmd_fnc_u("egrep -A 1 '^failed_plug_in_name:[ ]+' " +
                     temp_properties_file_path,
                     quiet=1,
                     show_err=0)
        rc = 1

    return rc, shell_rc, failed_plug_in_name
def return_plug_vars(general=True, custom=True):
    r"""
    Return an OrderedDict which is sorted by key and which contains all of the
    plug-in environment variables.

    Example excerpt of resulting dictionary:

    plug_var_dict:
      [AUTOBOOT_BASE_TOOL_DIR_PATH]:  /tmp/
      [AUTOBOOT_BB_LEVEL]:            <blank>
      [AUTOBOOT_BOOT_FAIL]:           0
      ...

    This function also does the following:
    - Set a default value for environment variable
      AUTOBOOT_OPENBMC_NICKNAME/AUTOIPL_FSP1_NICKNAME if it is not already set.
    - Register PASSWORD variables to prevent their values from being printed.

    Note: The programmer may set a default for any given environment variable
    by declaring a global variable of the same name and setting its value.
    For example, let's say the calling program has this global declaration:

    PERF_EXERCISERS_TOTAL_TIMEOUT = '180'

    If environment variable PERF_EXERCISERS_TOTAL_TIMEOUT is blank or not set,
    this function will set it to 180.

    Description of argument(s):
    general                         Return general plug-in parms (e.g. those
                                    beginning with "AUTOBOOT" or "AUTOGUI").
    custom                          Return custom plug-in parms (i.e. those
                                    beginning with the upper case name of the
                                    plug-in package, for example
                                    "OBMC_SAMPLE_PARM1").
    """

    regex_list = []
    if not (general or custom):
        return collections.OrderedDict()
    plug_in_package_name = get_plug_in_package_name(case="upper")
    if general:
        regex_list = [PLUG_VAR_PREFIX, "AUTOGUI"]
    if custom:
        regex_list.append(plug_in_package_name)

    regex = "^(" + "|".join(regex_list) + ")_"

    # Set a default for nickname.
    if os.environ.get("AUTOBOOT_OPENBMC_NICKNAME", "") == "":
        os.environ['AUTOBOOT_OPENBMC_NICKNAME'] = \
            os.environ.get("AUTOBOOT_OPENBMC_HOST", "")

    if os.environ.get("AUTOIPL_FSP1_NICKNAME", "") == "":
        os.environ['AUTOIPL_FSP1_NICKNAME'] = \
            os.environ.get("AUTOIPL_FSP1_NAME", "").split(".")[0]

    # For all variables specified in the parm_def file, we want them to
    # default to "" rather than being unset.
    # Process the parm_def file if it exists.
    parm_def_file_path = gp.pgm_dir_path + "parm_def"
    if os.path.exists(parm_def_file_path):
        parm_defs = gm.my_parm_file(parm_def_file_path)
    else:
        parm_defs = collections.OrderedDict()
    # Example parm_defs:
    # parm_defs:
    #   parm_defs[rest_fail]:           boolean
    #   parm_defs[command]:             string
    #   parm_defs[esel_stop_file_path]: string

    # Create a list of plug-in environment variables by pre-pending <all caps
    # plug-in package name>_<all caps var name>
    plug_in_parm_names = [
        plug_in_package_name + "_" + x
        for x in map(str.upper, parm_defs.keys())
    ]
    # Example plug_in_parm_names:
    # plug_in_parm_names:
    #  plug_in_parm_names[0]: STOP_REST_FAIL
    #  plug_in_parm_names[1]: STOP_COMMAND
    #  plug_in_parm_names[2]: STOP_ESEL_STOP_FILE_PATH

    # Initialize unset plug-in vars.
    for var_name in plug_in_parm_names:
        # If there is a global variable with the same name as the environment
        # variable, use its value as a default.
        default_value = gm.get_mod_global(var_name, "")
        os.environ[var_name] = os.environ.get(var_name, default_value)
        if os.environ[var_name] == "":
            os.environ[var_name] = default_value

    plug_var_dict = \
        collections.OrderedDict(sorted({k: v for (k, v) in
                                        os.environ.items()
                                        if re.match(regex, k)}.items()))
    # Register password values to prevent printing them out.  Any plug var
    # whose name ends in PASSWORD will be registered.
    password_vals = {
        k: v
        for (k, v) in plug_var_dict.items() if re.match(r".*_PASSWORD$", k)
    }.values()
    map(gp.register_passwords, password_vals)

    return plug_var_dict
def rprocess_plug_in_packages(plug_in_packages_list=None,
                              call_point="setup",
                              shell_rc="0x00000000",
                              stop_on_plug_in_failure=1,
                              stop_on_non_zero_rc=0,
                              release_type="obmc",
                              quiet=None,
                              debug=None,
                              return_history=False):
    r"""
    Call the external process_plug_in_packages.py to process the plug-in packages.  Return the following:
    rc                              The return code - 0 = PASS, 1 = FAIL.
    shell_rc                        The shell return code returned by process_plug_in_packages.py.
    failed_plug_in_name             The failed plug in name (if any).

    Description of arguments:
    plug_in_packages_list           A python list of plug-in directory paths.
    call_point                      The call point program to be called for each plug-in package (e.g.
                                    post_boot).  This name should not include the "cp_" prefix.
    shell_rc                        The user may supply a value other than zero to indicate an acceptable
                                    non-zero return code.  For example, if this value equals 0x00000200, it
                                    means that for each plug-in call point that runs, a 0x00000200 will not
                                    be counted as a failure.
    stop_on_plug_in_failure         If this parameter is set to 1, this program will stop and return non-zero
                                    if the call point program from any plug-in directory fails.  Conversely,
                                    if it is set to false, this program will run the call point program from
                                    each and every plug-in directory regardless of their return values.
                                    Typical example cases where you'd want to run all plug-in call points
                                    regardless of success or failure would be "cleanup" or "ffdc" call points.
    stop_on_non_zero_rc             If this parm is set to 1 and a plug-in call point program returns a valid
                                    non-zero return code (see "shell_rc" parm above), this program will stop
                                    processing and return 0 (success).  Since this constitutes a successful
                                    exit, this would normally be used where the caller wishes to stop
                                    processing if one of the plug-in directory call point programs returns a
                                    special value indicating that some special case has been found.  An
                                    example might be in calling some kind of "check_errl" call point program.
                                    Such a call point program might return a 2 (i.e. 0x00000200) to indicate
                                    that a given error log entry was found in an "ignore" list and is
                                    therefore to be ignored.  That being the case, no other "check_errl" call
                                    point program would need to be called.
    release_type                    The type of release being tested (e.g. "obmc", "op", "fips").  This
                                    influences which integrated plug-ins are selected.
    quiet                           If quiet is set to 1, this function will NOT write status messages to
                                    stdout.  This will default to the global quiet program parm or to 0.
    debug                           If this parameter is set to 1, this function will print additional debug
                                    information.  This is mainly to be used by the developer of this
                                    function.  This will default to the global quiet program parm or to 0.
    return_history                  In addition to rc, shell_rc and failed_plug_in_name, return a list
                                    containing historical output that looks like the following:

    history:
      history[0]:                   #(CDT) 2018/10/30 12:25:49 - Running OBMC_Sample/cp_post_stack
    """

    rc = 0

    plug_in_packages_list = gp.get_var_value(plug_in_packages_list, [])

    # If there are no plug-in packages to process, return successfully.
    if len(plug_in_packages_list) == 0:
        if return_history:
            return 0, 0, "", []
        else:
            return 0, 0, ""

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

    # Create string from list.
    plug_in_dir_paths = ':'.join(plug_in_packages_list)

    temp = tempfile.NamedTemporaryFile()
    temp_file_path = temp.name
    temp2 = tempfile.NamedTemporaryFile()
    temp_properties_file_path = temp2.name

    if debug:
        os.environ["PERF_TRACE"] = "1"
        debug_string = " --quiet=0"
    else:
        debug_string = ""

    loc_shell_rc = 0

    sub_cmd_buf = "process_plug_in_packages.py" + debug_string +\
                  " --call_point=" + call_point + " --allow_shell_rc=" +\
                  str(shell_rc) + " --stop_on_plug_in_failure=" +\
                  str(stop_on_plug_in_failure) + " --stop_on_non_zero_rc=" +\
                  str(stop_on_non_zero_rc) + " " + plug_in_dir_paths
    if quiet:
        cmd_buf = sub_cmd_buf + " > " + temp_file_path + " 2>&1"
    else:
        cmd_buf = "set -o pipefail ; " + sub_cmd_buf + " 2>&1 | tee " +\
                  temp_file_path
        if debug:
            gp.print_issuing(cmd_buf)
        else:
            gp.print_timen("Processing " + call_point +
                           " call point programs.")

    sub_proc = subprocess.Popen(cmd_buf, shell=True, executable='/bin/bash')
    sub_proc.communicate()
    proc_plug_pkg_rc = sub_proc.returncode

    if return_history:
        # Get the "Running" statements from the output.
        regex = " Running [^/]+/cp_"
        cmd_buf = "egrep '" + regex + "' " + temp_file_path
        _, history = gc.shell_cmd(cmd_buf,
                                  quiet=(not debug),
                                  print_output=0,
                                  show_err=0,
                                  ignore_err=1)
        history = [x + "\n" for x in filter(None, history.split("\n"))]
    else:
        history = []

    # As process_plug_in_packages.py help text states, it will print the values of failed_plug_in_name and
    # shell_rc in the following format:
    # failed_plug_in_name:               <failed plug-in value, if any>
    # shell_rc:                          <shell return code value of last call point program>

    # We want to obtain those values from the output.  To make the task simpler, we'll start by grepping the
    # output for lines that might fit such a format:
    # A valid bash variable against the left margin followed by...
    # - A colon followed by...
    # - Zero or more spaces
    bash_var_regex = "[_[:alpha:]][_[:alnum:]]*"
    regex = "^" + bash_var_regex + ":[ ]*"
    cmd_buf = "egrep '" + regex + "' " + temp_file_path + " > " +\
              temp_properties_file_path
    gp.dprint_issuing(cmd_buf)
    grep_rc = os.system(cmd_buf)

    # Next we call my_parm_file to create a properties dictionary.
    properties = gm.my_parm_file(temp_properties_file_path)

    # Finally, we access the 2 values that we need.
    shell_rc = int(properties.get('shell_rc', '0x0000000000000000'), 16)
    failed_plug_in_name = properties.get('failed_plug_in_name', '')

    if proc_plug_pkg_rc != 0:
        if quiet:
            os.system("cat " + temp_file_path + " >&2")
        if grep_rc != 0:
            gp.print_var(grep_rc, gp.hexa())
        gp.print_var(proc_plug_pkg_rc, gp.hexa())
        gp.print_timen("Re-cap of plug-in failures:")
        gc.cmd_fnc_u("egrep -A 1 '^failed_plug_in_name:[ ]+' " +
                     temp_properties_file_path + " | egrep -v '^\\--'",
                     quiet=1,
                     show_err=0)
        rc = 1

    if return_history:
        return rc, shell_rc, failed_plug_in_name, history
    else:
        return rc, shell_rc, failed_plug_in_name
def rprocess_plug_in_packages(plug_in_packages_list=None,
                              call_point="setup",
                              shell_rc="0x00000000",
                              stop_on_plug_in_failure=1,
                              stop_on_non_zero_rc=0,
                              release_type="obmc",
                              quiet=None,
                              debug=None):

    r"""
    Call the external process_plug_in_packages.py to process the plug-in
    packages.  Return the following:
    rc                              The return code - 0 = PASS, 1 = FAIL.
    shell_rc                        The shell return code returned by
                                    process_plug_in_packages.py.
    failed_plug_in_name             The failed plug in name (if any).

    Description of arguments:
    plug_in_packages_list           A python list of plug-in directory paths.
    call_point                      The call point program to be called for
                                    each plug-in package (e.g. post_boot).
                                    This name should not include the "cp_"
                                    prefix.
    shell_rc                        The user may supply a value other than
                                    zero to indicate an acceptable non-zero
                                    return code.  For example, if this value
                                    equals 0x00000200, it means that for each
                                    plug-in call point that runs, a 0x00000200
                                    will not be counted as a failure.
    stop_on_plug_in_failure         If this parameter is set to 1, this
                                    program will stop and return non-zero if
                                    the call point program from any plug-in
                                    directory fails.  Conversely, if it is set
                                    to false, this program will run the call
                                    point program from each and every plug-in
                                    directory regardless of their return
                                    values.  Typical example cases where you'd
                                    want to run all plug-in call points
                                    regardless of success or failure would be
                                    "cleanup" or "ffdc" call points.
    stop_on_non_zero_rc             If this parm is set to 1 and a plug-in
                                    call point program returns a valid
                                    non-zero return code (see "shell_rc" parm
                                    above), this program will stop processing
                                    and return 0 (success).  Since this
                                    constitutes a successful exit, this would
                                    normally be used where the caller wishes
                                    to stop processing if one of the plug-in
                                    directory call point programs returns a
                                    special value indicating that some special
                                    case has been found.  An example might be
                                    in calling some kind of "check_errl" call
                                    point program.  Such a call point program
                                    might return a 2 (i.e. 0x00000200) to
                                    indicate that a given error log entry was
                                    found in an "ignore" list and is therefore
                                    to be ignored.  That being the case, no
                                    other "check_errl" call point program
                                    would need to be called.
    release_type                    The type of release being tested (e.g.
                                    "obmc", "op", "fips").  This influences
                                    which integrated plug-ins are selected.
    quiet                           If quiet is set to 1, this function will
                                    NOT write status messages to stdout.  This
                                    will default to the global quiet program
                                    parm or to 0.
    debug                           If this parameter is set to 1, this
                                    function will print additional debug
                                    information.  This is mainly to be used by
                                    the developer of this function.  This will
                                    default to the global quiet program parm
                                    or to 0.
    """

    rc = 0

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

    # If there are no plug-in packages to process, return successfully.
    if len(plug_in_packages_list) == 0:
        return 0, 0, ""

    if quiet is None:
        try:
            quiet = int(BuiltIn().get_variable_value("${quiet}"))
        except TypeError:
            quiet = 0

    if debug is None:
        try:
            debug = int(BuiltIn().get_variable_value("${debug}"))
        except TypeError:
            debug = 0

    # Create string from list.
    plug_in_dir_paths = ':'.join(plug_in_packages_list)

    temp = tempfile.NamedTemporaryFile()
    temp_file_path = temp.name
    temp2 = tempfile.NamedTemporaryFile()
    temp_properties_file_path = temp2.name

    if int(debug) == 1:
        os.environ["PERF_TRACE"] = "1"
        debug_string = " --quiet=0"
    else:
        debug_string = ""

    loc_shell_rc = 0

    sub_cmd_buf = "process_plug_in_packages.py" + debug_string +\
                  " --call_point=" + call_point + " --shell_rc=" +\
                  str(shell_rc) + " --stop_on_plug_in_failure=" +\
                  str(stop_on_plug_in_failure) + " --stop_on_non_zero_rc=" +\
                  str(stop_on_non_zero_rc) + " " + plug_in_dir_paths
    if int(quiet) == 1:
        cmd_buf = sub_cmd_buf + " > " + temp_file_path + " 2>&1"
    else:
        cmd_buf = "set -o pipefail ; " + sub_cmd_buf + " 2>&1 | tee " +\
                  temp_file_path

        if int(debug) == 1:
            grp.rpissuing(cmd_buf)
        else:
            grp.rprint_timen("Processing " + call_point +
                             " call point programs.")

    proc_plug_pkg_rc = subprocess.call(cmd_buf, shell=True)

    # As process_plug_in_packages.py help text states, it will print the
    # values of failed_plug_in_name and shell_rc in the following format:
    # failed_plug_in_name:               <failed plug-in value, if any>
    # shell_rc:                          <shell return code value of last
    # call point program>

    # We want to obtain those values from the output.  To make the task
    # simpler, we'll start by grepping the output for lines that might fit
    # such a format:
    # A valid bash variable against the left margin
    # - A colon
    # - Zero or more spaces
    bash_var_regex = "[_[:alpha:]][_[:alnum:]]*"
    regex = "^" + bash_var_regex + ":[ ]*"
    cmd_buf = "egrep '" + regex + "' " + temp_file_path + " > " +\
              temp_properties_file_path
    if int(debug) == 1:
        grp.rpissuing(cmd_buf)
    grep_rc = os.system(cmd_buf)

    # Next we call my_parm_file to create a properties dictionary.
    properties = gm.my_parm_file(temp_properties_file_path)

    # Finally, we access the 2 values that we need.
    try:
        shell_rc = int(properties['shell_rc'], 16)
    except KeyError:
        shell_rc = 0
    try:
        failed_plug_in_name = properties['failed_plug_in_name']
    except KeyError:
        failed_plug_in_name = ""

    if proc_plug_pkg_rc != 0:
        hex = 1
        grp.rprint_error("Call to process_plug_in_packages failed.\n")
        grp.rprint_varx("grep_rc", grep_rc, hex)
        grp.rprint_varx("proc_plug_pkg_rc", proc_plug_pkg_rc, hex)
        # Show all of the failed plug in names and shell_rcs.
        gc.cmd_fnc_u("egrep -A 1 '^failed_plug_in_name:[ ]+' " +
                     temp_properties_file_path, quiet=1, show_err=0)
        rc = 1

    return rc, shell_rc, failed_plug_in_name
def return_plug_vars():
    r"""
    Return an OrderedDict which is sorted by key and which contains all of the
    plug-in environment variables.

    Example excerpt of resulting dictionary:

    plug_var_dict:
      [AUTOBOOT_BASE_TOOL_DIR_PATH]:  /fspmount/
      [AUTOBOOT_BB_LEVEL]:            <blank>
      [AUTOBOOT_BOOT_FAIL]:           0
      ...

    This function also does the following:
    - Set a default value for environment variable
      AUTOBOOT_OPENBMC_NICKNAME/AUTOIPL_FSP1_NICKNAME if it is not already set.
    - Register PASSWORD variables to prevent their values from being printed.

    Note: The programmer may set a default for any given environment variable
    by declaring a global variable of the same name and setting its value.
    For example, let's say the calling program has this global declaration:

    PERF_EXERCISERS_TOTAL_TIMEOUT = '180'

    If environment variable PERF_EXERCISERS_TOTAL_TIMEOUT is blank or not set,
    this function will set it to 180.
    """

    plug_in_package_name = get_plug_in_package_name(case="upper")
    regex = "^(" + PLUG_VAR_PREFIX + "|AUTOGUI|" + plug_in_package_name + ")_"

    # Set a default for nickname.
    if os.environ.get("AUTOBOOT_OPENBMC_NICKNAME", "") == "":
        os.environ['AUTOBOOT_OPENBMC_NICKNAME'] = \
            os.environ.get("AUTOBOOT_OPENBMC_HOST", "")

    if os.environ.get("AUTOIPL_FSP1_NICKNAME", "") == "":
        os.environ['AUTOIPL_FSP1_NICKNAME'] = \
            os.environ.get("AUTOIPL_FSP1_NAME", "").split(".")[0]

    # For all variables specified in the parm_def file, we want them to
    # default to "" rather than being unset.
    # Process the parm_def file if it exists.
    parm_def_file_path = gp.pgm_dir_path + "parm_def"
    if os.path.exists(parm_def_file_path):
        parm_defs = gm.my_parm_file(parm_def_file_path)
    else:
        parm_defs = collections.OrderedDict()
    # Example parm_defs:
    # parm_defs:
    #   parm_defs[rest_fail]:           boolean
    #   parm_defs[command]:             string
    #   parm_defs[esel_stop_file_path]: string

    # Create a list of plug-in environment variables by pre-pending <all caps
    # plug-in package name>_<all caps var name>
    plug_in_parm_names = [plug_in_package_name + "_" + x for x in
                          map(str.upper, parm_defs.keys())]
    # Example plug_in_parm_names:
    # plug_in_parm_names:
    #  plug_in_parm_names[0]: STOP_REST_FAIL
    #  plug_in_parm_names[1]: STOP_COMMAND
    #  plug_in_parm_names[2]: STOP_ESEL_STOP_FILE_PATH

    # Initialize unset plug-in vars.
    for var_name in plug_in_parm_names:
        # If there is a global variable with the same name as the environment
        # variable, use its value as a default.
        default_value = gm.get_mod_global(var_name, "")
        os.environ[var_name] = os.environ.get(var_name, default_value)
        if os.environ[var_name] == "":
            os.environ[var_name] = default_value

    plug_var_dict = \
        collections.OrderedDict(sorted({k: v for (k, v) in
                                        os.environ.items()
                                        if re.match(regex, k)}.items()))

    # Register password values to prevent printing them out.  Any plug var
    # whose name ends in PASSWORD will be registered.
    password_vals = {k: v for (k, v) in plug_var_dict.items()
                     if re.match(r".*_PASSWORD$", k)}.values()
    map(gp.register_passwords, password_vals)

    return plug_var_dict