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