From 3c7cac00f9db625d70044eee76edcb1e447688ac Mon Sep 17 00:00:00 2001 From: Chris Church Date: Sun, 31 Mar 2013 19:24:53 -0400 Subject: [PATCH] Working version of callback module to log to database. --- lib/main/tests/tasks.py | 12 +++- lib/plugins/callback/acom_callback.py | 89 +++++++++++++++++++++------ 2 files changed, 79 insertions(+), 22 deletions(-) diff --git a/lib/main/tests/tasks.py b/lib/main/tests/tasks.py index ce65ba47e0..542b51ecbf 100644 --- a/lib/main/tests/tasks.py +++ b/lib/main/tests/tasks.py @@ -78,10 +78,16 @@ class RunLaunchJobTest(BaseCeleryTest): launch_job_status = self.launch_job.start() self.assertEqual(launch_job_status.status, 'pending') launch_job_status = LaunchJobStatus.objects.get(pk=launch_job_status.pk) - self.assertEqual(launch_job_status.status, 'successful') - self.assertTrue(launch_job_status.result_stdout) #print 'stdout:', launch_job_status.result_stdout #print 'stderr:', launch_job_status.result_stderr + self.assertEqual(launch_job_status.status, 'successful') + self.assertTrue(launch_job_status.result_stdout) + launch_job_status_events = launch_job_status.launch_job_status_events.all() + #for ev in launch_job_status_events: + # print ev.event, ev.event_data + self.assertEqual(launch_job_status_events.filter(event='playbook_on_start').count(), 1) + self.assertEqual(launch_job_status_events.filter(event='playbook_on_play_start').count(), 1) + self.assertEqual(launch_job_status_events.filter(event='playbook_on_task_start').count(), 1) + self.assertEqual(launch_job_status_events.filter(event='playbook_on_stats').count(), 1) # FIXME: Test with a task that fails. - # FIXME: Get callback working. diff --git a/lib/plugins/callback/acom_callback.py b/lib/plugins/callback/acom_callback.py index c25e600cea..a6c7bf6e00 100644 --- a/lib/plugins/callback/acom_callback.py +++ b/lib/plugins/callback/acom_callback.py @@ -16,44 +16,87 @@ # along with Ansible Commander. If not, see . +import os +import sys + class CallbackModule(object): ''' - Stub callback module for logging ansible-playbook events. + Callback module for logging ansible-playbook events to the database. ''' - def _log_event(self, event, *args, **kwargs): - # FIXME: Push these events back to the server. - pass#print '====', event, args, kwargs + def __init__(self): + # he DJANGO_SETTINGS_MODULE environment variable *should* already + # be set if this callback is called when executing a playbook via a + # celery task, otherwise just bail out. + settings_module_name = os.environ.get('DJANGO_SETTINGS_MODULE', None) + if not settings_module_name: + return + # FIXME: Not particularly fond of this sys.path hack, but it is needed + # when a celery task calls ansible-playbook and needs to execute this + # script directly. + try: + settings_parent_module = __import__(settings_module_name) + except ImportError: + top_dir = os.path.join(os.path.dirname(__file__), '..', '..', '..') + sys.path.insert(0, os.path.abspath(top_dir)) + settings_parent_module = __import__(settings_module_name) + settings_module = getattr(settings_parent_module, settings_module_name.split('.')[-1]) + # Use the ACOM_TEST_DATABASE_NAME environment variable to specify the test + # database name when called from unit tests. + if os.environ.get('ACOM_TEST_DATABASE_NAME', None): + settings_module.DATABASES['default']['NAME'] = os.environ['ACOM_TEST_DATABASE_NAME'] + # Try to get the launch job status ID from the environment, otherwise + # just bail out now. + try: + launch_job_status_pk = int(os.environ.get('ACOM_LAUNCH_JOB_STATUS_ID', '')) + except ValueError: + return + from lib.main.models import LaunchJobStatus + try: + self.launch_job_status = LaunchJobStatus.objects.get(pk=launch_job_status_pk) + except LaunchJobStatus.DoesNotExist: + pass + + def _log_event(self, event, **event_data): + #print '====', event, args, kwargs + if hasattr(self, 'launch_job_status'): + kwargs = { + 'event': event, + 'event_data': event_data, + } + self.launch_job_status.launch_job_status_events.create(**kwargs) def on_any(self, *args, **kwargs): pass def runner_on_failed(self, host, res, ignore_errors=False): - self._log_event('runner_on_failed', host, res, ignore_errors) + self._log_event('runner_on_failed', host=host, res=res, + ignore_errors=ignore_errors) def runner_on_ok(self, host, res): - self._log_event('runner_on_ok', host, res) + self._log_event('runner_on_ok', host=host, res=res) def runner_on_error(self, host, msg): - self._log_event('runner_on_error', host, msg) + self._log_event('runner_on_error', host=host, msg=msg) def runner_on_skipped(self, host, item=None): - self._log_event('runner_on_skipped', host, item) + self._log_event('runner_on_skipped', host=host, item=item) def runner_on_unreachable(self, host, res): - self._log_event('runner_on_unreachable', host, res) + self._log_event('runner_on_unreachable', host=host, res=res) def runner_on_no_hosts(self): self._log_event('runner_on_no_hosts') def runner_on_async_poll(self, host, res, jid, clock): - self._log_event('runner_on_async_poll', host, res, jid, clock) + self._log_event('runner_on_async_poll', host=host, res=res, jid=jid, + clock=clock) def runner_on_async_ok(self, host, res, jid): - self._log_event('runner_on_async_ok', host, res, jid) + self._log_event('runner_on_async_ok', host=host, res=res, jid=jid) def runner_on_async_failed(self, host, res, jid): - self._log_event('runner_on_async_failed', host, res, jid) + self._log_event('runner_on_async_failed', host=host, res=res, jid=jid) def playbook_on_start(self): self._log_event('playbook_on_start') @@ -62,25 +105,33 @@ class CallbackModule(object): self._log_event('playbook_on_notify') def playbook_on_task_start(self, name, is_conditional): - self._log_event('playbook_on_task_start', name, is_conditional) + self._log_event('playbook_on_task_start', name=name, + is_conditional=is_conditional) - def playbook_on_vars_prompt(self, varname, private=True, prompt=None, encrypt=None, confirm=False, salt_size=None, salt=None, default=None): - self._log_event('playbook_on_vars_prompt', varname, private, prompt, encrypt, confirm, salt_size, salt, default) + def playbook_on_vars_prompt(self, varname, private=True, prompt=None, + encrypt=None, confirm=False, salt_size=None, + salt=None, default=None): + self._log_event('playbook_on_vars_prompt', varname=varname, + private=private, prompt=prompt, encrypt=encrypt, + confirm=confirm, salt_size=salt_size, salt=salf, + default=default) def playbook_on_setup(self): self._log_event('playbook_on_setup') def playbook_on_import_for_host(self, host, imported_file): - self._log_event('playbook_on_import_for_host', host, imported_file) + self._log_event('playbook_on_import_for_host', host=host, + imported_file=imported_file) def playbook_on_not_import_for_host(self, host, missing_file): - self._log_event('playbook_on_not_import_for_host', host, missing_file) + self._log_event('playbook_on_not_import_for_host', host=host, + missing_file=missing_file) def playbook_on_play_start(self, pattern): - self._log_event('playbook_on_play_start', pattern) + self._log_event('playbook_on_play_start', pattern=pattern) def playbook_on_stats(self, stats): d = {} for attr in ('changed', 'dark', 'failures', 'ok', 'processed', 'skipped'): d[attr] = getattr(stats, attr) - self._log_event('playbook_on_stats', d) + self._log_event('playbook_on_stats', **d)