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...")
256 logger.debug("Executing command: %s" % cmd)
257 p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
259 while p.poll() is None:
260 line = p.stdout.readline().rstrip()
263 raise Exception("Problem while running '{}'.".format(cmd))
270 if pod_arch and pod_arch in arch_filter:
271 logger.info("Apply aarch64 specific to rally config...")
272 with open(RALLY_AARCH64_PATCH_PATH, "r") as f:
273 rally_patch_conf = f.read()
275 for line in fileinput.input(RALLY_CONF_PATH, inplace=1):
277 if "cirros|testvm" in line:
278 print rally_patch_conf
280 logger.info("Creating Rally environment...")
282 cmd = "rally deployment destroy opnfv-rally"
283 ft_utils.execute_command(cmd, error_msg=(
284 "Deployment %s does not exist."
285 % CONST.__getattribute__('rally_deployment_name')),
288 rally_conf = os_utils.get_credentials_for_rally()
289 with open('rally_conf.json', 'w') as fp:
290 json.dump(rally_conf, fp)
291 cmd = ("rally deployment create "
292 "--file=rally_conf.json --name={0}"
293 .format(CONST.__getattribute__('rally_deployment_name')))
294 error_msg = "Problem while creating Rally deployment"
295 ft_utils.execute_command_raise(cmd, error_msg=error_msg)
297 cmd = "rally deployment check"
298 error_msg = "OpenStack not responding or faulty Rally deployment."
299 ft_utils.execute_command_raise(cmd, error_msg=error_msg)
301 cmd = "rally deployment list"
302 ft_utils.execute_command(cmd,
303 error_msg=("Problem while listing "
304 "Rally deployment."))
306 cmd = "rally plugin list | head -5"
307 ft_utils.execute_command(cmd,
308 error_msg=("Problem while showing "
312 def install_tempest():
313 logger.info("Installing tempest from existing repo...")
314 cmd = ("rally verify list-verifiers | "
315 "grep '{0}' | wc -l".format(
316 CONST.__getattribute__('tempest_deployment_name')))
317 p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
318 while p.poll() is None:
319 line = p.stdout.readline().rstrip()
321 logger.debug("Tempest %s does not exist" %
322 CONST.__getattribute__('tempest_deployment_name'))
323 cmd = ("rally verify create-verifier --source {0} "
324 "--name {1} --type tempest --system-wide"
325 .format(CONST.__getattribute__('dir_repo_tempest'),
326 CONST.__getattribute__('tempest_deployment_name')))
327 error_msg = "Problem while installing Tempest."
328 ft_utils.execute_command_raise(cmd, error_msg=error_msg)
332 _, flavor_id = os_utils.get_or_create_flavor('m1.tiny',
337 if flavor_id is None:
338 raise Exception('Failed to create flavor')
341 def check_environment():
342 msg_not_active = "The Functest environment is not installed."
343 if not os.path.isfile(CONST.__getattribute__('env_active')):
344 raise Exception(msg_not_active)
346 with open(CONST.__getattribute__('env_active'), "r") as env_file:
348 if not re.search("1", s):
349 raise Exception(msg_not_active)
351 logger.info("Functest environment is installed.")
354 def print_deployment_info():
356 logger.info('\n\nDeployment information:\n%s' %
357 handler.get_deployment_info())
360 def prepare_env(**kwargs):
362 if not (kwargs['action'] in actions):
363 logger.error('Argument not valid.')
365 elif kwargs['action'] == "start":
366 logger.info("######### Preparing Functest environment #########\n")
367 check_env_variables()
375 with open(CONST.__getattribute__('env_active'), "w") as env_file:
378 elif kwargs['action'] == "check":
380 except Exception as e:
387 logging.config.fileConfig(pkg_resources.resource_filename(
388 'functest', 'ci/logging.ini'))
389 parser = PrepareEnvParser()
390 args = parser.parse_args(sys.argv[1:])
391 return prepare_env(**args)
394 if __name__ == '__main__':