summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwu.zhihui <wu.zhihui1@zte.com.cn>2017-03-04 20:33:22 +0800
committerwu.zhihui <wu.zhihui1@zte.com.cn>2017-03-08 18:03:15 +0800
commitb8b2d5e8de33f314a76e7a2ff2385befeafd4cc3 (patch)
tree64c44ff820ff6b02cbb76804ec5f9204704a2e87
parentde5c51ecba1e74a4c9c201155b0a4f129e38efad (diff)
Implement ansible driver
- According to inputs parameters, setup test environment. If failed during setupping, qtip will exited. If successful, execute metric tests. - Parameters(optional): * keypair: the keypair to login/execute commands to the remote hosts. They can be automatically generated. * hostfile: a inventory file. If not give, it can be automatically generated via installer. * args: the parameters passed to playbook - Use ansible python api to trigger ansible-playbook. Unit test will be in a new patch. Change-Id: I7470d348308f7cb6cb669bcc49063cf0f4da2111 Signed-off-by: wu.zhihui <wu.zhihui1@zte.com.cn>
-rw-r--r--qtip/driver/ansible.py14
-rw-r--r--qtip/driver/ansible_api.py58
-rw-r--r--qtip/driver/ansible_driver.py85
3 files changed, 143 insertions, 14 deletions
diff --git a/qtip/driver/ansible.py b/qtip/driver/ansible.py
deleted file mode 100644
index cd17625d..00000000
--- a/qtip/driver/ansible.py
+++ /dev/null
@@ -1,14 +0,0 @@
-##############################################################################
-# Copyright (c) 2016 ZTE Corp and others.
-#
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-# http://www.apache.org/licenses/LICENSE-2.0
-##############################################################################
-
-from qtip.driver.base import BaseDriver
-
-
-class AnsibleDriver(BaseDriver):
- """driver for running performance tests with Ansible"""
diff --git a/qtip/driver/ansible_api.py b/qtip/driver/ansible_api.py
new file mode 100644
index 00000000..5c5baffc
--- /dev/null
+++ b/qtip/driver/ansible_api.py
@@ -0,0 +1,58 @@
+##############################################################################
+# Copyright (c) 2017 ZTE Corp and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+from collections import namedtuple
+
+from ansible.executor.playbook_executor import PlaybookExecutor
+from ansible.inventory import Inventory
+from ansible.parsing.dataloader import DataLoader
+from ansible.vars import VariableManager
+
+
+class AnsibleApi(object):
+
+ def __init__(self):
+ self.variable_manager = VariableManager()
+ self.loader = DataLoader()
+ self.passwords = {}
+ self.playbook_executor = None
+
+ def execute_playbook(self, playbook_path, hosts_file=None,
+ key_file=None, extra_vars=None):
+ inventory = Inventory(loader=self.loader,
+ variable_manager=self.variable_manager,
+ host_list=hosts_file)
+ Options = namedtuple('Options',
+ ['listtags', 'listtasks', 'listhosts', 'syntax',
+ 'connection', 'module_path', 'forks', 'remote_user',
+ 'private_key_file', 'ssh_common_args', 'ssh_extra_args',
+ 'sftp_extra_args', 'scp_extra_args', 'become',
+ 'become_method', 'become_user', 'verbosity', 'check'])
+ options = Options(listtags=False, listtasks=False, listhosts=False,
+ syntax=False, connection='ssh', module_path=None,
+ forks=100, remote_user='root', private_key_file=key_file,
+ ssh_common_args=None, ssh_extra_args=None, sftp_extra_args=None,
+ scp_extra_args=None, become=None, become_method=None,
+ become_user='root', verbosity=None, check=False)
+ self.variable_manager.extra_vars = extra_vars
+
+ self.playbook_executor = PlaybookExecutor(playbooks=[playbook_path],
+ inventory=inventory,
+ variable_manager=self.variable_manager,
+ loader=self.loader,
+ options=options,
+ passwords=self.passwords)
+ return self.playbook_executor.run()
+
+ def get_detail_playbook_stats(self):
+ if self.playbook_executor:
+ stats = self.playbook_executor._tqm._stats
+ return map(lambda x: (x, stats.summarize(x)), stats.processed.keys())
+ else:
+ return None
diff --git a/qtip/driver/ansible_driver.py b/qtip/driver/ansible_driver.py
new file mode 100644
index 00000000..1cd7918d
--- /dev/null
+++ b/qtip/driver/ansible_driver.py
@@ -0,0 +1,85 @@
+##############################################################################
+# Copyright (c) 2017 ZTE Corp and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+from collections import defaultdict
+from os import path
+
+from qtip.driver.ansible_api import AnsibleApi
+from qtip.util.env import AnsibleEnvSetup
+from qtip.util.logger import QtipLogger
+
+logger = QtipLogger('ansible_driver').get
+PLAYBOOK_DIR = path.join(path.dirname(__file__), 'playbook')
+
+
+class AnsibleDriver(object):
+ """driver for running performance tests with Ansible"""
+
+ def __init__(self, config={}):
+ self.config = config
+ self.env = AnsibleEnvSetup()
+ self.env_setup_flag = False
+
+ @staticmethod
+ def merge_two_dicts(x, y):
+ '''
+ It is from http://stackoverflow.com/questions/38987/
+ how-can-i-merge-two-python-dictionaries-in-a-single-expression
+ '''
+ z = x.copy()
+ z.update(y)
+ return z
+
+ def pre_run(self):
+ if self.env_setup_flag:
+ logger.info("Already setup environment......")
+ else:
+ logger.info("Starting to setup test environment...")
+ self.env.setup(self.config)
+ self.env_setup_flag = True
+ logger("Done!")
+
+ def run(self, metric_list, **kwargs):
+ if 'args' in self.config:
+ extra_vars = self.merge_two_dicts(kwargs, self.config['args'])
+ else:
+ extra_vars = kwargs
+ logger.info("extra_var: {0}".format(extra_vars))
+
+ # TODO zhihui: will add a new property named "tool" for metrics, hardcode it now.
+ tool_to_metrics = defaultdict(list)
+ for metric in metric_list:
+ if metric in ['dhrystone', 'whetstone']:
+ tool_to_metrics['unixbench'].append(metric)
+ extra_vars[metric] = True
+ elif metric == 'ssl':
+ tool_to_metrics['openssl'].append(metric)
+ else:
+ tool_to_metrics[metric].append(metric)
+
+ ansible_api = AnsibleApi()
+ map(lambda tool: self._run_metric(ansible_api, tool,
+ tool_to_metrics[tool], extra_vars),
+ tool_to_metrics)
+
+ def _run_metric(self, ansible_api, tool, metrics, extra_vars):
+ logger.info('Using {0} to measure metrics {1}'.format(tool, metrics))
+
+ for metric in metrics:
+ extra_vars[metric] = True
+
+ logger.debug("extra_vars: {0}".format(extra_vars))
+
+ for item in ['setup', 'run', 'clean']:
+ pbook = "{0}/{1}/{2}.yaml".format(PLAYBOOK_DIR, tool, item)
+ logger.debug("Start to run {0}".format(pbook))
+ ansible_api.execute_playbook(pbook, self.env.hostfile,
+ self.env.keypair['private'], extra_vars)
+ playbook_stat = ansible_api.get_detail_playbook_stats()
+ logger.debug("playbook_stat: {0}".format(playbook_stat))