blob: 013e4ab255a9c3a6b8fcd1ba857a2f2920e2ef2d [file] [log] [blame]
Peter D Phan5e56f522021-12-20 13:19:41 -06001#!/usr/bin/env python3
2
3import os
4import sys
5
6
7sys.path.append(__file__.split(__file__.split("/")[-1])[0] + "../ffdc")
8from ffdc_collector import ffdc_collector
Peter D Phan5ab239a2022-08-10 07:53:32 -05009from ssh_utility import SSHRemoteclient
Peter D Phan5e56f522021-12-20 13:19:41 -060010
11from robot.libraries.BuiltIn import BuiltIn as robotBuildIn
12
13# (Sub) String constants used for input dictionary key search
14HOST = "HOST"
15USER = "USERNAME"
16PASSWD = "PASSWORD"
17CONFIG = "CONFIG"
18TYPE = "TYPE"
19LOC = "LOCATION"
20PROTOCOL = "PROTOCOL"
21ENV_VARS = "ENV_VARS"
22ECONFIG = "ECONFIG"
23LOGLEVEL = "LOG"
24
25
26def ffdc_robot_script_cli(**kwargs):
27 r"""
28
29 For the specified host, this method provide automation testcases the interface to
30 the new ffdc collector ../ffdc/ffdc_collector.py via robot variable FFDC_DEFAULT
31
32 variable FFDC_DEFAULT:1, by default use the existing ffdc collection method.
33 variable FFDC_DEFAULT:0 use the new ffdc method
34
35 Command examples:
36 (1) Legacy ffdc collection
37 python3 -m robot -v OPENBMC_HOST:<> -v OPENBMC_USERNAME:<> \
38 -v OPENBMC_PASSWORD:<> ./tools/myffdc.robot
39 (2) New ffdc collection
40 python3 -m robot -v OPENBMC_HOST:<> -v OPENBMC_USERNAME:<> \
41 -v OPENBMC_PASSWORD:<> -v FFDC_DEFAULT:0 ./tools/myffdc.robot
42
43 Description of argument(s)in dictionary: xx can be anything appropriate
44
45 xx_HOST:hostname name/ip of the targeted (remote) system
46 xx_USERNAME:username user on the targeted system with access to FFDC files
47 xx_PASSWORD:password password for user on targeted system
48 xx_CONFIG:ffdc_config configuration file listing commands and files for FFDC
49 xx_LOCATION:location where to store collected FFDC. Default: <current dir>/logs/
50 xx_TYPE:remote_type os type of the remote host.
51 xx_PROTOCOL:remote_protocol Protocol to use to collect data. Default: 'ALL'
52 ENV_VAR:env_vars User define CLI env vars '{"key : "value"}'. Default: ""
53 ECONFIG:econfig User define env vars YAML file. Default: ""
54 LOG_LEVEL:log_level CRITICAL, ERROR, WARNING, INFO, DEBUG. Default: INFO
55
56 Code examples:
57 (1) openbmc_ffdc.robot activate this method with no parm
58 Run Keyword If ${FFDC_DEFAULT} == ${1} FFDC
59 ... ELSE ffdc_robot_script_cli
60
61 (2) Method invocation with parms
62 ffdc_from = {'OS_HOST' : 'os host name or ip',
63 'OS_USERNAME' : 'os username',
64 'OS_PASSWORD' : 'password for os_username',
65 'OS_TYPE' : 'os_type, ubuntu, rhel, aix, etc',
66 }
67 ffdc_robot_script_cli(ffdc_from)
68
69 """
70
71 robotBuildIn().log_to_console("Collecting FFDC - CLI log collector script")
72
73 if not kwargs:
74 dict_of_parms = {}
75 # When method is invoked with no parm,
76 # use robot variables
77 # OPENBMC_HOST, OPENBMC_USERNAME, OPENBMC_PASSWORD, OPENBMC (type)
78 dict_of_parms["OPENBMC_HOST"] = \
79 robotBuildIn().get_variable_value("${OPENBMC_HOST}", default=None)
80 dict_of_parms["OPENBMC_USERNAME"] = \
81 robotBuildIn().get_variable_value("${OPENBMC_USERNAME}", default=None)
82 dict_of_parms["OPENBMC_PASSWORD"] = \
83 robotBuildIn().get_variable_value("${OPENBMC_PASSWORD}", default=None)
84 dict_of_parms["REMOTE_TYPE"] = "OPENBMC"
85
86 run_ffdc_collector(dict_of_parms)
87
88 else:
89 if isinstance(kwargs, dict):
90 # When method is invoked with user defined dictionary,
91 # dictionary keys has the following format
92 # xx_HOST; xx_USERNAME, xx_PASSWORD, xx_TYPE
93 # where xx is one of OPENBMC, OS, or os_type LINUX/UBUNTU/AIX
94 run_ffdc_collector(**kwargs)
95
96
97def run_ffdc_collector(dict_of_parm):
98 r"""
99
100 Process input parameters and collect information
101
102 Description of argument(s)in dictionary: xx can be anything appropriate
103
104 xx_HOST:hostname name/ip of the targeted (remote) system
105 xx_USERNAME:username user on the targeted system with access to FFDC files
106 xx_PASSWORD:password password for user on targeted system
107 xx_CONFIG:ffdc_config configuration file listing commands and files for FFDC
108 xx_LOCATION:location where to store collected FFDC. Default: <current dir>/logs/
109 xx_TYPE:remote_type os type of the remote host.
110 xx_PROTOCOL:remote_protocol Protocol to use to collect data. Default: 'ALL'
111 ENV_VAR:env_vars User define CLI env vars '{"key : "value"}'. Default: ""
112 ECONFIG:econfig User define env vars YAML file. Default: ""
113 LOG_LEVEL:log_level CRITICAL, ERROR, WARNING, INFO, DEBUG. Default: INFO
114
115 """
116
117 # Clear local variables
118 remote = None
119 username = None
120 password = None
121 config = None
122 location = None
123 remote_type = None
124 protocol = None
125 env_vars = None
126 econfig = None
127 log_level = None
128
129 # Process input key/value pairs
130 for key in dict_of_parm.keys():
131 if HOST in key:
132 remote = dict_of_parm[key]
133 elif USER in key:
134 username = dict_of_parm[key]
135 elif PASSWD in key:
136 password = dict_of_parm[key]
137 elif CONFIG in key:
138 config = dict_of_parm[key]
139 elif LOC in key:
140 location = dict_of_parm[key]
141 elif TYPE in key:
142 remote_type = dict_of_parm[key]
143 elif PROTOCOL in key:
144 protocol = dict_of_parm[key]
145 elif ENV_VARS in key:
146 env_vars = dict_of_parm[key]
147 elif ECONFIG in key:
148 econfig = dict_of_parm[key]
149 elif LOGLEVEL in key:
150 log_level = dict_of_parm[key]
151
152 # Set defaults values for parms
153 # that are not specified with input and have acceptable defaults.
154 if not location:
155 # Default FFDC store location
156 location = robotBuildIn().get_variable_value("${EXECDIR}", default=None) + "/logs"
157 ffdc_collector.validate_local_store(location)
158
159 if not config:
160 # Default FFDC configuration
161 script_path = os.path.dirname(os.path.abspath(__file__))
162 config = script_path + "/../ffdc/ffdc_config.yaml"
163
164 if not protocol:
165 protocol = "ALL"
166
167 if not env_vars:
168 env_vars = ""
169
170 if not econfig:
171 econfig = ""
172
173 if not log_level:
174 log_level = "INFO"
175
176 # If minimum required inputs are met, go collect.
177 if (remote and username and password and remote_type):
178 # Execute data collection
179 this_ffdc = ffdc_collector(remote,
180 username,
181 password,
182 config,
183 location,
184 remote_type,
185 protocol,
186 env_vars,
187 econfig,
188 log_level)
189 this_ffdc.collect_ffdc()
Peter D Phan5ab239a2022-08-10 07:53:32 -0500190
191 # If original ffdc request is for BMC,
192 # attempt to also collect ffdc for HOST_OS if possible.
193 if remote_type.upper() == 'OPENBMC':
194 os_host = \
195 robotBuildIn().get_variable_value("${OS_HOST}", default=None)
196 os_username = \
197 robotBuildIn().get_variable_value("${OS_USERNAME}", default=None)
198 os_password = \
199 robotBuildIn().get_variable_value("${OS_PASSWORD}", default=None)
200
201 if os_host and os_username and os_password:
202 os_type = get_os_type(os_host, os_username, os_password)
203 if os_type:
204 os_ffdc = ffdc_collector(os_host,
205 os_username,
206 os_password,
207 config,
208 location,
209 os_type,
210 protocol,
211 env_vars,
212 econfig,
213 log_level)
214 os_ffdc.collect_ffdc()
215
216
217def get_os_type(os_host, os_username, os_password):
218
219 os_type = None
220
221 # If HOST_OS is pingable
222 if os.system("ping -c 1 " + os_host) == 0:
223 r"""
224 Open a ssh connection to targeted system.
225 """
226 ssh_remoteclient = SSHRemoteclient(os_host,
227 os_username,
228 os_password)
229
230 if ssh_remoteclient.ssh_remoteclient_login():
231
232 # Find OS_TYPE
233 cmd_exit_code, err, response = \
234 ssh_remoteclient.execute_command('uname')
235 os_type = response.strip()
236
237 # If HOST_OS is linux, expands os_type to one of
238 # the 2 linux distros that have more details in ffdc_config.yaml
239 if os_type.upper() == 'LINUX':
240 cmd_exit_code, err, response = \
241 ssh_remoteclient.execute_command('cat /etc/os-release')
242 linux_distro = response
243 if 'redhat' in linux_distro:
244 os_type = 'RHEL'
245 elif 'ubuntu' in linux_distro:
246 os_type = 'UBUNTU'
247
248 if ssh_remoteclient:
249 ssh_remoteclient.ssh_remoteclient_disconnect()
250
251 return os_type