Browse Source

Refactor Ansible runner

Ilya Shakhat 3 years ago
parent
commit
40faea0f35

+ 80
- 78
performa/engine/ansible_runner.py View File

@@ -14,12 +14,13 @@
14 14
 # limitations under the License.
15 15
 
16 16
 from collections import namedtuple
17
+import copy
17 18
 
18 19
 from ansible.executor import task_queue_manager
19 20
 from ansible import inventory
20 21
 from ansible.parsing import dataloader
21 22
 from ansible.playbook import play
22
-from ansible.plugins import callback
23
+from ansible.plugins import callback as callback_pkg
23 24
 from ansible.vars import VariableManager
24 25
 from oslo_log import log as logging
25 26
 
@@ -28,7 +29,22 @@ from performa.engine import utils
28 29
 LOG = logging.getLogger(__name__)
29 30
 
30 31
 
31
-class MyCallback(callback.CallbackBase):
32
+def _light_rec(result):
33
+    for r in result:
34
+        c = copy.deepcopy(r)
35
+        if 'records' in c:
36
+            del c['records']
37
+        if 'series' in c:
38
+            del c['series']
39
+        yield c
40
+
41
+
42
+def _log_result(result):
43
+    # todo check current log level before doing heavy things
44
+    LOG.debug('Execution result (filtered): %s', list(_light_rec(result)))
45
+
46
+
47
+class MyCallback(callback_pkg.CallbackBase):
32 48
 
33 49
     CALLBACK_VERSION = 2.0
34 50
     CALLBACK_TYPE = 'stdout'
@@ -70,79 +86,65 @@ Options = namedtuple('Options',
70 86
                       'become_method', 'become_user', 'verbosity', 'check'])
71 87
 
72 88
 
73
-def _run(play_source, host_list):
74
-
75
-    LOG.debug('Running play: %s on hosts: %s', play_source, host_list)
76
-
77
-    variable_manager = VariableManager()
78
-    loader = dataloader.DataLoader()
79
-    module_path = utils.resolve_relative_path('performa/modules')
80
-
81
-    options = Options(connection='smart', password='swordfish',
82
-                      module_path=module_path,
83
-                      forks=100, remote_user='developer',
84
-                      private_key_file=None,
85
-                      ssh_common_args=None, ssh_extra_args=None,
86
-                      sftp_extra_args=None, scp_extra_args=None, become=None,
87
-                      become_method=None, become_user=None, verbosity=100,
88
-                      check=False)
89
-    passwords = dict(vault_pass='secret')
90
-
91
-    # create inventory and pass to var manager
92
-    inventory_inst = inventory.Inventory(loader=loader,
93
-                                         variable_manager=variable_manager,
94
-                                         host_list=host_list)
95
-    variable_manager.set_inventory(inventory_inst)
96
-
97
-    # create play
98
-    play_inst = play.Play().load(play_source,
99
-                                 variable_manager=variable_manager,
100
-                                 loader=loader)
101
-
102
-    storage = []
103
-    callback = MyCallback(storage)
104
-
105
-    # actually run it
106
-    tqm = None
107
-    try:
108
-        tqm = task_queue_manager.TaskQueueManager(
109
-            inventory=inventory_inst,
110
-            variable_manager=variable_manager,
111
-            loader=loader,
112
-            options=options,
113
-            passwords=passwords,
114
-            stdout_callback=callback,
115
-        )
116
-        tqm.run(play_inst)
117
-    finally:
118
-        if tqm is not None:
119
-            tqm.cleanup()
120
-
121
-    LOG.debug('Execution result: %s', storage)
122
-    return storage
123
-
124
-
125
-def run_command(command, host_list):
126
-    hosts = ','.join(host_list) + ','
127
-    # tasks = [dict(action=dict(module='shell', args=command))]
128
-    tasks = [{'command': command}]
129
-
130
-    play_source = dict(
131
-        hosts=host_list,
132
-        gather_facts='no',
133
-        tasks=tasks,
134
-    )
135
-
136
-    return _run(play_source, hosts)
137
-
138
-
139
-def run_playbook(playbook):
140
-    result = []
141
-
142
-    for play_source in playbook:
143
-        hosts = play_source['hosts']
144
-        play_source['gather_facts'] = 'no'
145
-
146
-        result += (_run(play_source, hosts))
147
-
148
-    return result
89
+class AnsibleRunner(object):
90
+    def __init__(self, remote_user='developer', forks=100):
91
+        super(AnsibleRunner, self).__init__()
92
+
93
+        module_path = utils.resolve_relative_path('performa/modules')
94
+        self.options = Options(
95
+            connection='smart', password='swordfish', module_path=module_path,
96
+            forks=forks, remote_user=remote_user, private_key_file=None,
97
+            ssh_common_args=None, ssh_extra_args=None, sftp_extra_args=None,
98
+            scp_extra_args=None, become=None, become_method='sudo',
99
+            become_user='root', verbosity=100, check=False)
100
+
101
+    def _run_play(self, play_source):
102
+        LOG.debug('Running play: %s', play_source)
103
+
104
+        host_list = play_source['hosts']
105
+
106
+        loader = dataloader.DataLoader()
107
+        variable_manager = VariableManager()
108
+        inventory_inst = inventory.Inventory(loader=loader,
109
+                                             variable_manager=variable_manager,
110
+                                             host_list=host_list)
111
+        variable_manager.set_inventory(inventory_inst)
112
+        passwords = dict(vault_pass='secret')
113
+
114
+        # create play
115
+        play_inst = play.Play().load(play_source,
116
+                                     variable_manager=variable_manager,
117
+                                     loader=loader)
118
+
119
+        storage = []
120
+        callback = MyCallback(storage)
121
+
122
+        # actually run it
123
+        tqm = None
124
+        try:
125
+            tqm = task_queue_manager.TaskQueueManager(
126
+                inventory=inventory_inst,
127
+                variable_manager=variable_manager,
128
+                loader=loader,
129
+                options=self.options,
130
+                passwords=passwords,
131
+                stdout_callback=callback,
132
+            )
133
+            tqm.run(play_inst)
134
+        finally:
135
+            if tqm is not None:
136
+                tqm.cleanup()
137
+
138
+        _log_result(storage)
139
+
140
+        return storage
141
+
142
+    def run(self, playbook):
143
+        result = []
144
+
145
+        for play_source in playbook:
146
+            play_source['gather_facts'] = 'no'
147
+
148
+            result += self._run_play(play_source)
149
+
150
+        return result

+ 5
- 0
performa/engine/config.py View File

@@ -67,6 +67,11 @@ MAIN_OPTS = [
67 67
                default=utils.env('PERFORMA_MONGO_DB'),
68 68
                required=True,
69 69
                help='Mongo DB, defaults to env[PERFORMA_MONGO_DB].'),
70
+    cfg.StrOpt('remote-user',
71
+               default=utils.env('PERFORMA_REMOTE_USER'),
72
+               required=True,
73
+               help='User for connecting to remote systems, '
74
+                    'defaults to env[PERFORMA_REMOTE_USER].'),
70 75
     cfg.Opt('hosts',
71 76
             type=Yaml(),
72 77
             default=utils.env('PERFORMA_HOSTS'),

+ 4
- 1
performa/engine/main.py View File

@@ -19,6 +19,7 @@ from oslo_config import cfg
19 19
 from oslo_log import log as logging
20 20
 import yaml
21 21
 
22
+from performa.engine import ansible_runner
22 23
 from performa.engine import config
23 24
 from performa.engine import player
24 25
 from performa.engine import report
@@ -53,7 +54,9 @@ def main():
53 54
         tag = utils.random_string()
54 55
         LOG.info('Using auto-generated tag "%s"', tag)
55 56
 
56
-    records, series = player.play_scenario(scenario, tag)
57
+    runner = ansible_runner.AnsibleRunner(remote_user=cfg.CONF.remote_user)
58
+
59
+    records, series = player.play_scenario(runner, scenario, tag)
57 60
 
58 61
     storage.store_data(cfg.CONF.mongo_url, cfg.CONF.mongo_db, records, series)
59 62
 

+ 7
- 13
performa/engine/player.py View File

@@ -15,19 +15,13 @@
15 15
 
16 16
 import copy
17 17
 
18
-from oslo_config import cfg
19 18
 from oslo_log import log as logging
20 19
 
21
-from performa.engine import ansible_runner
22 20
 from performa.engine import utils
23 21
 
24 22
 LOG = logging.getLogger(__name__)
25 23
 
26 24
 
27
-def run_command(command):
28
-    return ansible_runner.run_command(command, cfg.CONF.hosts)
29
-
30
-
31 25
 def _pick_tasks(tasks, matrix):
32 26
     matrix = matrix or {}
33 27
 
@@ -42,11 +36,11 @@ def _pick_tasks(tasks, matrix):
42 36
             yield parametrized_task
43 37
 
44 38
 
45
-def play_setup(setup):
46
-    ansible_runner.run_playbook(setup)
39
+def play_setup(runner, setup_playbook):
40
+    runner.run(setup_playbook)
47 41
 
48 42
 
49
-def play_execution(execution_playbook):
43
+def play_execution(runner, execution_playbook):
50 44
     records = []
51 45
     series = []
52 46
 
@@ -59,7 +53,7 @@ def play_execution(execution_playbook):
59 53
                 'hosts': play['hosts'],
60 54
                 'tasks': [task],
61 55
             }
62
-            command_results = ansible_runner.run_playbook([task_play])
56
+            command_results = runner.run([task_play])
63 57
 
64 58
             for command_result in command_results:
65 59
                 if command_result.get('status') == 'OK':
@@ -91,17 +85,17 @@ def add_tag(records, tag):
91 85
         r['tag'] = tag
92 86
 
93 87
 
94
-def play_scenario(scenario, tag):
88
+def play_scenario(runner, scenario, tag):
95 89
     records = []
96 90
     series = []
97 91
 
98 92
     if 'setup' in scenario:
99
-        play_setup(scenario['setup'])
93
+        play_setup(runner, scenario['setup'])
100 94
 
101 95
     if 'execution' in scenario:
102 96
         execution = scenario['execution']
103 97
 
104
-        records, series = play_execution(execution)
98
+        records, series = play_execution(runner, execution)
105 99
         add_tag(records, tag)
106 100
         add_tag(series, tag)
107 101
 

+ 0
- 4
performa/scenarios/db/sysbench.yaml View File

@@ -10,14 +10,10 @@ setup:
10 10
     - name: installing sysbench
11 11
       apt: name=sysbench
12 12
       become: yes
13
-      become_user: root
14
-      become_method: sudo
15 13
     - name: installing atop
16 14
       apt:
17 15
         name: atop, daemon
18 16
       become: yes
19
-      become_user: root
20
-      become_method: sudo
21 17
   -
22 18
     hosts: $target
23 19
     tasks:

Loading…
Cancel
Save