1#!/usr/bin/env python
2
3r"""
4This file contains functions which are useful for processing BMC dumps.
5"""
6
7import gen_print as gp
8import gen_misc as gm
9import gen_robot_keyword as grk
10import bmc_ssh_utils as bsu
11import var_funcs as vf
12import os
13from robot.libraries.BuiltIn import BuiltIn
14import sys
15import os
16import imp
17base_path = os.path.dirname(os.path.dirname(
18                            imp.find_module("gen_robot_print")[1])) + os.sep
19sys.path.append(base_path + "data/")
20import variables as var
21
22
23def get_dump_dict(quiet=None):
24    r"""
25    Get dump information and return as an ordered dictionary where the keys
26    are the dump IDs and the values are the full path names of the dumps.
27
28    Example robot program call:
29
30    ${dump_dict}=  Get Dump Dict
31    Rpvars                          1  dump_dict
32
33    Example output:
34
35    dump_dict:
36      [1]: /var/lib/phosphor-debug-collector/dumps/1/obmcdump_1_1508255216.tar.xz
37      [2]: /var/lib/phosphor-debug-collector/dumps/2/obmcdump_2_1508255245.tar.xz
38      [3]: /var/lib/phosphor-debug-collector/dumps/3/obmcdump_3_1508255267.tar.xz
39      [4]: /var/lib/phosphor-debug-collector/dumps/4/obmcdump_4_1508255283.tar.xz
40
41    Description of argument(s):
42    quiet                           If quiet is set to 1, this function will
43                                    NOT write status messages to stdout.
44    """
45
46    quiet = int(gp.get_var_value(quiet, 1))
47    cmd_buf = "dump_dir_path=" + var.DUMP_DIR_PATH + " ; " \
48              + "for dump_id in $(ls ${dump_dir_path} | sort -n) ; " \
49              + "do echo -n $dump_id: ; ls ${dump_dir_path}${dump_id}/* ; done"
50    output, stderr, rc = bsu.bmc_execute_command(cmd_buf, quiet=quiet)
51
52    return vf.key_value_outbuf_to_dict(output)
53
54
55def valid_dump(dump_id,
56               dump_dict=None,
57               quiet=None):
58    r"""
59    Verify that dump_id is a valid.  If it is not valid, issue robot failure
60    message.
61
62    A dump is valid if the indicated dump_id refers to an existing dump with a
63    valid associated dump file.
64
65    Description of argument(s):
66    dump_id                         A dump ID (e.g. "1", "2", etc.)
67    dump_dict                       A dump dictionary such as the one returned
68                                    by get_dump_dict.  If this value is None,
69                                    this function will call get_dump_dict on
70                                    the caller's behalf.
71    quiet                           If quiet is set to 1, this function will
72                                    NOT write status messages to stdout.
73    """
74
75    if dump_dict is None:
76        dump_dict = get_dump_dict(quiet=quiet)
77
78    if dump_id not in dump_dict:
79        message = "The specified dump ID was not found among the existing" \
80            + " dumps:\n"
81        message += gp.sprint_var(dump_id)
82        message += gp.sprint_var(dump_dict)
83        BuiltIn().fail(gp.sprint_error(message))
84
85    if not dump_dict[dump_id].endswith("tar.xz"):
86        message = "There is no \"tar.xz\" file associated with the given" \
87            + " dump_id:\n"
88        message += gp.sprint_var(dump_id)
89        dump_file_path = dump_dict[dump_id]
90        message += gp.sprint_var(dump_file_path)
91        BuiltIn().fail(gp.sprint_error(message))
92
93
94def scp_dumps(targ_dir_path,
95              targ_file_prefix="",
96              dump_dict=None,
97              quiet=None):
98    r"""
99    SCP all dumps from the BMC to the indicated directory on the local system
100    and return a list of the new files.
101
102    Description of argument(s):
103    targ_dir_path                   The path of the directory to receive the
104                                    dump files.
105    targ_file_prefix                Prefix which will be pre-pended to each
106                                    target file's name.
107    dump_dict                       A dump dictionary such as the one returned
108                                    by get_dump_dict.  If this value is None,
109                                    this function will call get_dump_dict on
110                                    the caller's behalf.
111    quiet                           If quiet is set to 1, this function will
112                                    NOT write status messages to stdout.
113    """
114
115    targ_dir_path = gm.add_trailing_slash(targ_dir_path)
116
117    if dump_dict is None:
118        dump_dict = get_dump_dict(quiet=quiet)
119
120    status, ret_values = grk.run_key("Open Connection for SCP", quiet=quiet)
121
122    dump_file_list = []
123    for dump_id, source_file_path in dump_dict.iteritems():
124        targ_file_path = targ_dir_path + targ_file_prefix \
125            + os.path.basename(source_file_path)
126        status, ret_values = grk.run_key("scp.Get File  " + source_file_path +
127                                         "  " + targ_file_path, quiet=quiet)
128        dump_file_list.append(targ_file_path)
129
130    return dump_file_list
131