3 # All rights reserved. This program and the accompanying materials
4 # are made available under the terms of the Apache License, Version 2.0
5 # which accompanies this distribution, and is available at
6 # http://www.apache.org/licenses/LICENSE-2.0
22 import functest.utils.functest_utils as ft_utils
23 import functest.utils.openstack_utils as os_utils
24 from functest.utils.constants import CONST
26 from opnfv.utils import constants as opnfv_constants
27 from opnfv.deployment import factory
29 actions = ['start', 'check']
31 """ logging configuration """
32 logger = logging.getLogger('functest.ci.prepare_env')
34 # set the architecture to default
36 arch_filter = ['aarch64']
38 CONFIG_FUNCTEST_PATH = pkg_resources.resource_filename(
39 'functest', 'ci/config_functest.yaml')
40 CONFIG_PATCH_PATH = pkg_resources.resource_filename(
41 'functest', 'ci/config_patch.yaml')
42 CONFIG_AARCH64_PATCH_PATH = pkg_resources.resource_filename(
43 'functest', 'ci/config_aarch64_patch.yaml')
44 RALLY_CONF_PATH = "/etc/rally/rally.conf"
45 RALLY_AARCH64_PATCH_PATH = pkg_resources.resource_filename(
46 'functest', 'ci/rally_aarch64_patch.conf')
49 class PrepareEnvParser(object):
52 self.parser = argparse.ArgumentParser()
53 self.parser.add_argument("action", help="Possible actions are: "
54 "'{d[0]}|{d[1]}' ".format(d=actions),
56 self.parser.add_argument("-d", "--debug", help="Debug mode",
59 def parse_args(self, argv=[]):
60 return vars(self.parser.parse_args(argv))
63 def print_separator():
64 logger.info("==============================================")
67 def check_env_variables():
69 logger.info("Checking environment variables...")
71 if CONST.__getattribute__('INSTALLER_TYPE') is None:
72 logger.warning("The env variable 'INSTALLER_TYPE' is not defined.")
73 CONST.__setattr__('INSTALLER_TYPE', 'undefined')
75 if (CONST.__getattribute__('INSTALLER_TYPE') not in
76 opnfv_constants.INSTALLERS):
77 logger.warning("INSTALLER_TYPE=%s is not a valid OPNFV installer. "
78 "Available OPNFV Installers are : %s. "
79 "Setting INSTALLER_TYPE=undefined."
80 % (CONST.__getattribute__('INSTALLER_TYPE'),
81 opnfv_constants.INSTALLERS))
82 CONST.__setattr__('INSTALLER_TYPE', 'undefined')
84 logger.info(" INSTALLER_TYPE=%s"
85 % CONST.__getattribute__('INSTALLER_TYPE'))
87 if CONST.__getattribute__('INSTALLER_IP') is None:
89 "The env variable 'INSTALLER_IP' is not defined. It is recommended"
90 " to extract some information from the deployment")
92 logger.info(" INSTALLER_IP=%s" %
93 CONST.__getattribute__('INSTALLER_IP'))
95 if CONST.__getattribute__('DEPLOY_SCENARIO') is None:
96 logger.warning("The env variable 'DEPLOY_SCENARIO' is not defined. "
97 "Setting CI_SCENARIO=undefined.")
98 CONST.__setattr__('DEPLOY_SCENARIO', 'undefined')
100 logger.info(" DEPLOY_SCENARIO=%s"
101 % CONST.__getattribute__('DEPLOY_SCENARIO'))
102 if CONST.__getattribute__('CI_DEBUG'):
103 logger.info(" CI_DEBUG=%s" % CONST.__getattribute__('CI_DEBUG'))
105 if CONST.__getattribute__('NODE_NAME'):
106 logger.info(" NODE_NAME=%s" % CONST.__getattribute__('NODE_NAME'))
108 if CONST.__getattribute__('BUILD_TAG'):
109 logger.info(" BUILD_TAG=%s" % CONST.__getattribute__('BUILD_TAG'))
111 if CONST.__getattribute__('IS_CI_RUN'):
112 logger.info(" IS_CI_RUN=%s" % CONST.__getattribute__('IS_CI_RUN'))
115 def get_deployment_handler():
119 installer_params_yaml = pkg_resources.resource_filename(
120 'functest', 'ci/installer_params.yaml')
121 if (CONST.__getattribute__('INSTALLER_IP') and
122 CONST.__getattribute__('INSTALLER_TYPE') and
123 CONST.__getattribute__('INSTALLER_TYPE') in
124 opnfv_constants.INSTALLERS):
126 installer_params = ft_utils.get_parameter_from_yaml(
127 CONST.__getattribute__('INSTALLER_TYPE'),
128 installer_params_yaml)
129 except ValueError as e:
130 logger.debug('Printing deployment info is not supported for %s' %
131 CONST.__getattribute__('INSTALLER_TYPE'))
134 user = installer_params.get('user', None)
135 password = installer_params.get('password', None)
136 pkey = installer_params.get('pkey', None)
138 handler = factory.Factory.get_handler(
139 installer=CONST.__getattribute__('INSTALLER_TYPE'),
140 installer_ip=CONST.__getattribute__('INSTALLER_IP'),
142 installer_pwd=password,
145 pod_arch = handler.get_arch()
146 except Exception as e:
147 logger.debug("Cannot get deployment information. %s" % e)
150 def create_directories():
152 logger.info("Creating needed directories...")
153 if not os.path.exists(CONST.__getattribute__('dir_functest_conf')):
154 os.makedirs(CONST.__getattribute__('dir_functest_conf'))
155 logger.info(" %s created." %
156 CONST.__getattribute__('dir_functest_conf'))
158 logger.debug(" %s already exists." %
159 CONST.__getattribute__('dir_functest_conf'))
161 if not os.path.exists(CONST.__getattribute__('dir_functest_data')):
162 os.makedirs(CONST.__getattribute__('dir_functest_data'))
163 logger.info(" %s created." %
164 CONST.__getattribute__('dir_functest_data'))
166 logger.debug(" %s already exists." %
167 CONST.__getattribute__('dir_functest_data'))
168 if not os.path.exists(CONST.__getattribute__('dir_functest_images')):
169 os.makedirs(CONST.__getattribute__('dir_functest_images'))
170 logger.info(" %s created." %
171 CONST.__getattribute__('dir_functest_images'))
173 logger.debug(" %s already exists." %
174 CONST.__getattribute__('dir_functest_images'))
177 def source_rc_file():
180 if CONST.__getattribute__('openstack_creds') is None:
181 logger.warning("The environment variable 'creds' must be set and"
182 "pointing to the local RC file. Using default: "
183 "/home/opnfv/functest/conf/openstack.creds ...")
185 CONST.__getattribute__('dir_functest_conf'), 'openstack.creds')
187 if not os.path.isfile(CONST.__getattribute__('openstack_creds')):
189 "OpenStack credentials file not provided. "
190 "The OpenStack credentials must be in {}"
191 .format(CONST.__getattribute__('openstack_creds')))
193 logger.info("RC file provided in %s."
194 % CONST.__getattribute__('openstack_creds'))
195 if os.path.getsize(CONST.__getattribute__('openstack_creds')) == 0:
197 "The OpenStack RC file {} is empty."
198 .format(CONST.__getattribute__('openstack_creds')))
200 logger.info("Sourcing the OpenStack RC file...")
201 os_utils.source_credentials(CONST.__getattribute__('openstack_creds'))
202 for key, value in os.environ.iteritems():
203 if re.search("OS_", key):
204 if key == 'OS_AUTH_URL':
205 CONST.__setattr__('OS_AUTH_URL', value)
206 elif key == 'OS_USERNAME':
207 CONST.__setattr__('OS_USERNAME', value)
208 elif key == 'OS_TENANT_NAME':
209 CONST.__setattr__('OS_TENANT_NAME', value)
210 elif key == 'OS_PASSWORD':
211 CONST.__setattr__('OS_PASSWORD', value)
214 def update_config_file():
215 patch_file(CONFIG_PATCH_PATH)
217 if pod_arch and pod_arch in arch_filter:
218 patch_file(CONFIG_AARCH64_PATCH_PATH)
220 if "TEST_DB_URL" in os.environ:
224 def patch_file(patch_file_path):
225 logger.debug('Updating file: %s', patch_file_path)
226 with open(patch_file_path) as f:
227 patch_file = yaml.safe_load(f)
230 for key in patch_file:
231 if key in CONST.__getattribute__('DEPLOY_SCENARIO'):
232 new_functest_yaml = dict(ft_utils.merge_dicts(
233 ft_utils.get_functest_yaml(), patch_file[key]))
237 os.remove(CONFIG_FUNCTEST_PATH)
238 with open(CONFIG_FUNCTEST_PATH, "w") as f:
239 f.write(yaml.dump(new_functest_yaml, default_style='"'))
243 with open(CONFIG_FUNCTEST_PATH) as f:
244 functest_yaml = yaml.safe_load(f)
246 with open(CONFIG_FUNCTEST_PATH, "w") as f:
247 functest_yaml["results"]["test_db_url"] = os.environ.get('TEST_DB_URL')
248 f.write(yaml.dump(functest_yaml, default_style='"'))
251 def verify_deployment():
253 logger.info("Verifying OpenStack services...")
254 cmd = ("sh %s" % pkg_resources.resource_filename(
255 'functest', 'ci/check_os.sh'))
257 logger.debug("Executing command: %s" % cmd)
258 p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
260 while p.poll() is None:
261 line = p.stdout.readline().rstrip()
264 raise Exception("Problem while running 'check_os.sh'.")
271 if pod_arch and pod_arch in arch_filter:
272 logger.info("Apply aarch64 specific to rally config...")
273 with open(RALLY_AARCH64_PATCH_PATH, "r") as f:
274 rally_patch_conf = f.read()
276 for line in fileinput.input(RALLY_CONF_PATH, inplace=1):
278 if "cirros|testvm" in line:
279 print rally_patch_conf
281 logger.info("Creating Rally environment...")
283 cmd = "rally deployment destroy opnfv-rally"
284 ft_utils.execute_command(cmd, error_msg=(
285 "Deployment %s does not exist."
286 % CONST.__getattribute__('rally_deployment_name')),
289 rally_conf = os_utils.get_credentials_for_rally()
290 with open('rally_conf.json', 'w') as fp:
291 json.dump(rally_conf, fp)
292 cmd = ("rally deployment create "
293 "--file=rally_conf.json --name={0}"
294 .format(CONST.__getattribute__('rally_deployment_name')))
295 error_msg = "Problem while creating Rally deployment"
296 ft_utils.execute_command_raise(cmd, error_msg=error_msg)
298 cmd = "rally deployment check"
299 error_msg = "OpenStack not responding or faulty Rally deployment."
300 ft_utils.execute_command_raise(cmd, error_msg=error_msg)
302 cmd = "rally deployment list"
303 ft_utils.execute_command(cmd,
304 error_msg=("Problem while listing "
305 "Rally deployment."))
307 cmd = "rally plugin list | head -5"
308 ft_utils.execute_command(cmd,
309 error_msg=("Problem while showing "
313 def install_tempest():
314 logger.info("Installing tempest from existing repo...")
315 cmd = ("rally verify list-verifiers | "
316 "grep '{0}' | wc -l".format(
317 CONST.__getattribute__('tempest_deployment_name')))
318 p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
319 while p.poll() is None:
320 line = p.stdout.readline().rstrip()
322 logger.debug("Tempest %s does not exist" %
323 CONST.__getattribute__('tempest_deployment_name'))
324 cmd = ("rally verify create-verifier --source {0} "
325 "--name {1} --type tempest --system-wide"
326 .format(CONST.__getattribute__('dir_repo_tempest'),
327 CONST.__getattribute__('tempest_deployment_name')))
328 error_msg = "Problem while installing Tempest."
329 ft_utils.execute_command_raise(cmd, error_msg=error_msg)
333 _, flavor_id = os_utils.get_or_create_flavor('m1.tiny',
338 if flavor_id is None:
339 raise Exception('Failed to create flavor')
342 def check_environment():
343 msg_not_active = "The Functest environment is not installed."
344 if not os.path.isfile(CONST.__getattribute__('env_active')):
345 raise Exception(msg_not_active)
347 with open(CONST.__getattribute__('env_active'), "r") as env_file:
349 if not re.search("1", s):
350 raise Exception(msg_not_active)
352 logger.info("Functest environment is installed.")
355 def print_deployment_info():
357 logger.info('\n\nDeployment information:\n%s' %
358 handler.get_deployment_info())
363 if not (kwargs['action'] in actions):
364 logger.error('Argument not valid.')
366 elif kwargs['action'] == "start":
367 logger.info("######### Preparing Functest environment #########\n")
368 check_env_variables()
369 get_deployment_handler()
377 with open(CONST.__getattribute__('env_active'), "w") as env_file:
380 print_deployment_info()
381 elif kwargs['action'] == "check":
383 except Exception as e:
389 if __name__ == '__main__':
390 logging.config.fileConfig(pkg_resources.resource_filename(
391 'functest', 'ci/logging.ini'))
392 parser = PrepareEnvParser()
393 args = parser.parse_args(sys.argv[1:])
394 sys.exit(main(**args))