diff --git a/performa/engine/ansible_runner.py b/performa/engine/ansible_runner.py index e6c90ae..ac61c25 100644 --- a/performa/engine/ansible_runner.py +++ b/performa/engine/ansible_runner.py @@ -14,12 +14,13 @@ # limitations under the License. from collections import namedtuple +import copy from ansible.executor import task_queue_manager from ansible import inventory from ansible.parsing import dataloader from ansible.playbook import play -from ansible.plugins import callback +from ansible.plugins import callback as callback_pkg from ansible.vars import VariableManager from oslo_log import log as logging @@ -28,7 +29,22 @@ from performa.engine import utils LOG = logging.getLogger(__name__) -class MyCallback(callback.CallbackBase): +def _light_rec(result): + for r in result: + c = copy.deepcopy(r) + if 'records' in c: + del c['records'] + if 'series' in c: + del c['series'] + yield c + + +def _log_result(result): + # todo check current log level before doing heavy things + LOG.debug('Execution result (filtered): %s', list(_light_rec(result))) + + +class MyCallback(callback_pkg.CallbackBase): CALLBACK_VERSION = 2.0 CALLBACK_TYPE = 'stdout' @@ -70,79 +86,65 @@ Options = namedtuple('Options', 'become_method', 'become_user', 'verbosity', 'check']) -def _run(play_source, host_list): +class AnsibleRunner(object): + def __init__(self, remote_user='developer', forks=100): + super(AnsibleRunner, self).__init__() - LOG.debug('Running play: %s on hosts: %s', play_source, host_list) + module_path = utils.resolve_relative_path('performa/modules') + self.options = Options( + connection='smart', password='swordfish', module_path=module_path, + forks=forks, remote_user=remote_user, private_key_file=None, + ssh_common_args=None, ssh_extra_args=None, sftp_extra_args=None, + scp_extra_args=None, become=None, become_method='sudo', + become_user='root', verbosity=100, check=False) - variable_manager = VariableManager() - loader = dataloader.DataLoader() - module_path = utils.resolve_relative_path('performa/modules') + def _run_play(self, play_source): + LOG.debug('Running play: %s', play_source) - options = Options(connection='smart', password='swordfish', - module_path=module_path, - forks=100, remote_user='developer', - private_key_file=None, - ssh_common_args=None, ssh_extra_args=None, - sftp_extra_args=None, scp_extra_args=None, become=None, - become_method=None, become_user=None, verbosity=100, - check=False) - passwords = dict(vault_pass='secret') + host_list = play_source['hosts'] - # create inventory and pass to var manager - inventory_inst = inventory.Inventory(loader=loader, - variable_manager=variable_manager, - host_list=host_list) - variable_manager.set_inventory(inventory_inst) + loader = dataloader.DataLoader() + variable_manager = VariableManager() + inventory_inst = inventory.Inventory(loader=loader, + variable_manager=variable_manager, + host_list=host_list) + variable_manager.set_inventory(inventory_inst) + passwords = dict(vault_pass='secret') - # create play - play_inst = play.Play().load(play_source, - variable_manager=variable_manager, - loader=loader) + # create play + play_inst = play.Play().load(play_source, + variable_manager=variable_manager, + loader=loader) - storage = [] - callback = MyCallback(storage) + storage = [] + callback = MyCallback(storage) - # actually run it - tqm = None - try: - tqm = task_queue_manager.TaskQueueManager( - inventory=inventory_inst, - variable_manager=variable_manager, - loader=loader, - options=options, - passwords=passwords, - stdout_callback=callback, - ) - tqm.run(play_inst) - finally: - if tqm is not None: - tqm.cleanup() + # actually run it + tqm = None + try: + tqm = task_queue_manager.TaskQueueManager( + inventory=inventory_inst, + variable_manager=variable_manager, + loader=loader, + options=self.options, + passwords=passwords, + stdout_callback=callback, + ) + tqm.run(play_inst) + finally: + if tqm is not None: + tqm.cleanup() - LOG.debug('Execution result: %s', storage) - return storage + _log_result(storage) + return storage -def run_command(command, host_list): - hosts = ','.join(host_list) + ',' - # tasks = [dict(action=dict(module='shell', args=command))] - tasks = [{'command': command}] + def run(self, playbook): + result = [] - play_source = dict( - hosts=host_list, - gather_facts='no', - tasks=tasks, - ) + for play_source in playbook: + play_source['gather_facts'] = 'no' - return _run(play_source, hosts) + result += self._run_play(play_source) - -def run_playbook(playbook): - result = [] - - for play_source in playbook: - hosts = play_source['hosts'] - play_source['gather_facts'] = 'no' - - result += (_run(play_source, hosts)) - - return result + return result diff --git a/performa/engine/config.py b/performa/engine/config.py index c5752c0..ac5b04a 100644 --- a/performa/engine/config.py +++ b/performa/engine/config.py @@ -67,6 +67,11 @@ MAIN_OPTS = [ default=utils.env('PERFORMA_MONGO_DB'), required=True, help='Mongo DB, defaults to env[PERFORMA_MONGO_DB].'), + cfg.StrOpt('remote-user', + default=utils.env('PERFORMA_REMOTE_USER'), + required=True, + help='User for connecting to remote systems, ' + 'defaults to env[PERFORMA_REMOTE_USER].'), cfg.Opt('hosts', type=Yaml(), default=utils.env('PERFORMA_HOSTS'), diff --git a/performa/engine/main.py b/performa/engine/main.py index 296557e..5392620 100644 --- a/performa/engine/main.py +++ b/performa/engine/main.py @@ -19,6 +19,7 @@ from oslo_config import cfg from oslo_log import log as logging import yaml +from performa.engine import ansible_runner from performa.engine import config from performa.engine import player from performa.engine import report @@ -53,7 +54,9 @@ def main(): tag = utils.random_string() LOG.info('Using auto-generated tag "%s"', tag) - records, series = player.play_scenario(scenario, tag) + runner = ansible_runner.AnsibleRunner(remote_user=cfg.CONF.remote_user) + + records, series = player.play_scenario(runner, scenario, tag) storage.store_data(cfg.CONF.mongo_url, cfg.CONF.mongo_db, records, series) diff --git a/performa/engine/player.py b/performa/engine/player.py index cb7a1d7..3efe372 100644 --- a/performa/engine/player.py +++ b/performa/engine/player.py @@ -15,19 +15,13 @@ import copy -from oslo_config import cfg from oslo_log import log as logging -from performa.engine import ansible_runner from performa.engine import utils LOG = logging.getLogger(__name__) -def run_command(command): - return ansible_runner.run_command(command, cfg.CONF.hosts) - - def _pick_tasks(tasks, matrix): matrix = matrix or {} @@ -42,11 +36,11 @@ def _pick_tasks(tasks, matrix): yield parametrized_task -def play_setup(setup): - ansible_runner.run_playbook(setup) +def play_setup(runner, setup_playbook): + runner.run(setup_playbook) -def play_execution(execution_playbook): +def play_execution(runner, execution_playbook): records = [] series = [] @@ -59,7 +53,7 @@ def play_execution(execution_playbook): 'hosts': play['hosts'], 'tasks': [task], } - command_results = ansible_runner.run_playbook([task_play]) + command_results = runner.run([task_play]) for command_result in command_results: if command_result.get('status') == 'OK': @@ -91,17 +85,17 @@ def add_tag(records, tag): r['tag'] = tag -def play_scenario(scenario, tag): +def play_scenario(runner, scenario, tag): records = [] series = [] if 'setup' in scenario: - play_setup(scenario['setup']) + play_setup(runner, scenario['setup']) if 'execution' in scenario: execution = scenario['execution'] - records, series = play_execution(execution) + records, series = play_execution(runner, execution) add_tag(records, tag) add_tag(series, tag) diff --git a/performa/scenarios/db/sysbench.yaml b/performa/scenarios/db/sysbench.yaml index a37509b..a0c3e33 100644 --- a/performa/scenarios/db/sysbench.yaml +++ b/performa/scenarios/db/sysbench.yaml @@ -10,14 +10,10 @@ setup: - name: installing sysbench apt: name=sysbench become: yes - become_user: root - become_method: sudo - name: installing atop apt: name: atop, daemon become: yes - become_user: root - become_method: sudo - hosts: $target tasks: