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