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