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