diff --git a/callback_plugins/fedmsg_callback.py b/callback_plugins/fedmsg_callback.py new file mode 100644 index 0000000000..3a892fe769 --- /dev/null +++ b/callback_plugins/fedmsg_callback.py @@ -0,0 +1,79 @@ +# (C) 2012, Michael DeHaan, +# based on the log_plays example +# skvidal@fedoraproject.org +# rbean@redhat.com + +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +import os +import pwd + +import fedmsg +import fedmsg.config + + +def getlogin(): + try: + user = os.getlogin() + except OSError, e: + user = pwd.getpwuid(os.geteuid())[0] + return user + + +class CallbackModule(object): + """ Publish playbook starts and stops to fedmsg. """ + + playbook = None + + def __init__(self): + config = fedmsg.config.load_config() + config.update(dict( + name='relay_inbound', + cert_prefix='shell', + active=True, + )) + fedmsg.init(**config) + + def playbook_on_play_start(self, pattern): + # This gets called once for each play.. but we just issue a message once + # for the first one. One per "playbook" + play = getattr(self, 'play', None) + if play: + # figure out where the playbook FILE is + path = os.path.abspath(play.playbook.filename) + + if not self.playbook: + fedmsg.publish( + modname="ansible", topic="playbook.start", + msg=dict( + playbook=path, + userid=getlogin(), + extra_vars=play.playbook.extra_vars, + inventory=play.playbook.inventory.host_list, + playbook_checksum=play.playbook.check, + check=play.playbook.check, + ), + ) + self.playbook = path + + def playbook_on_stats(self, stats): + results = dict([(h, stats.summarize(h)) for h in stats.processed]) + fedmsg.publish( + modname="ansible", topic="playbook.complete", + msg=dict( + playbook=self.playbook, + userid=getlogin(), + results=results, + ), + ) diff --git a/callback_plugins/logdetail.py b/callback_plugins/logdetail.py index 1c24f51ca8..45b3b6e345 100644 --- a/callback_plugins/logdetail.py +++ b/callback_plugins/logdetail.py @@ -50,24 +50,24 @@ class LogMech(object): raise # checksum of full playbook? - + @property def playbook_id(self): if self._pb_fn: return os.path.basename(self._pb_fn).replace('.yml', '').replace('.yaml', '') else: return "ansible-cmd" - + @playbook_id.setter def playbook_id(self, value): self._pb_fn = value - + @property def logpath_play(self): # this is all to get our path to look nice ish tstamp = time.strftime('%Y/%m/%d/%H.%M.%S', time.localtime(self.started)) path = os.path.normpath(self.logpath + '/' + self.playbook_id + '/' + tstamp + '/') - + if not os.path.exists(path): try: os.makedirs(path) @@ -76,13 +76,13 @@ class LogMech(object): raise return path - + def play_log(self, content): # record out playbook.log # include path to playbook, checksums, user running playbook # any args we can get back from the invocation fd = open(self.logpath_play + '/' + 'playbook-' + self.pid + '.info', 'a') - fd.write('%s\n' % content) + fd.write('%s\n' % content) fd.close() def task_to_json(self, task): @@ -92,25 +92,25 @@ class LogMech(object): res['task_args'] = task.module_args if self.playbook_id == 'ansible-cmd': res['task_userid'] = getlogin() - for k in ("delegate_to", "environment", "first_available_file", - "local_action", "notified_by", "notify", "only_if", - "register", "sudo", "sudo_user", "tags", + for k in ("delegate_to", "environment", "first_available_file", + "local_action", "notified_by", "notify", "only_if", + "register", "sudo", "sudo_user", "tags", "transport", "when"): v = getattr(task, k, None) if v: res['task_' + k] = v - + return res - + def log(self, host, category, data, task=None, count=0): if not host: host = 'HOSTMISSING' - + if type(data) == dict: name = data.get('module_name',None) else: name = "unknown" - + # we're in setup - move the invocation info up one level if 'invocation' in data: @@ -126,21 +126,21 @@ class LogMech(object): data['task_start'] = self._last_task_start data['task_end'] = time.time() data.update(self.task_to_json(task)) - + if 'task_userid' not in data: data['task_userid'] = getlogin() - + if category == 'OK' and data.get('changed', False): category = 'CHANGED' - + if self.play_info.get('check', False): category = 'CHECK:' + category - + fd = open(self.logpath_play + '/' + host + '.log', 'a') now = time.strftime(TIME_FORMAT, time.localtime()) fd.write(MSG_FORMAT % dict(now=now, name=name, count=count, category=category, data=json.dumps(data))) fd.close() - + logmech = LogMech() @@ -238,7 +238,7 @@ class CallbackModule(object): def playbook_on_play_start(self, pattern): self._task_count = 0 - + play = getattr(self, 'play', None) if play: # figure out where the playbook FILE is @@ -259,9 +259,9 @@ class CallbackModule(object): pb_info['playbook_checksum'] = utils.md5(path) pb_info['check'] = play.playbook.check logmech.play_log(json.dumps(pb_info, indent=4)) - - self._play_count += 1 - # then write per-play info that doesn't duplcate the playbook info + + self._play_count += 1 + # then write per-play info that doesn't duplcate the playbook info info = {} info['play'] = play.name info['hosts'] = play.hosts @@ -273,12 +273,12 @@ class CallbackModule(object): def playbook_on_stats(self, stats): - results = {} + results = {} for host in stats.processed.keys(): results[host] = stats.summarize(host) logmech.log(host, 'STATS', results[host]) logmech.play_log(json.dumps({'stats': results}, indent=4)) logmech.play_log(json.dumps({'playbook_end': time.time()}, indent=4)) print 'logs written to: %s' % logmech.logpath_play - + diff --git a/library/fedmsg b/library/fedmsg deleted file mode 100644 index 6247d42bd3..0000000000 --- a/library/fedmsg +++ /dev/null @@ -1,81 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# (c) 2013, Ralph Bean -# LGPLv2+ -# -# You can pass this action an arbitrary number of kw arguments which will be -# used to make up the main message body (json). -# -# Dedicated to Seth Vidal. This was his idea. - -DOCUMENTATION = ''' ---- -module: fedmsg -short_description: Publish a message to fedmsg. -description: - - Send a message to a fedmsg-relay daemon. -options: - topic: - description: - - The short portion of the message topic. - required: false - default: log - modname: - description: - - The modname portion of the message topic. - required: false - default: ansible - -requirements: [ fedmsg ] -author: Ralph Bean -''' - -EXAMPLES = ''' -- fedmsg: msg="Testing this out" - -- local_action: fedmsg - topic="run.complete" - msg="{{ ansible_date_time.iso8601 }}" -''' - -import fedmsg -import fedmsg.config - - -def main(): - - module = AnsibleModule( - argument_spec=dict( - topic=dict(default="log"), - modname=dict(default="ansible"), - cert_prefix=dict(default="ansible"), - ), - check_invalid_arguments=False, - supports_check_mode=True - ) - - topic = module.params.pop('topic') - modname = module.params.pop('modname') - cert_prefix = module.params.pop('cert_prefix') - - try: - config = fedmsg.config.load_config() - config.update(dict( - name='relay_inbound', - cert_prefix=cert_prefix, - active=True, - )) - fedmsg.init(**config) - except Exception, e: - module.fail_json(msg="unable to initialize fedmsg: %s" % e) - - try: - fedmsg.publish(modname=modname, topic=topic, msg=module.params) - except Exception, e: - module.fail_json(msg="unable to send to fedmsg: %s" % e) - - module.exit_json(changed=False, **module.params) - -# this is magic, see lib/ansible/module_common.py -#<> -main() diff --git a/playbooks/groups/badges-web.yml b/playbooks/groups/badges-web.yml index 5c3c044e49..c93eb85da4 100644 --- a/playbooks/groups/badges-web.yml +++ b/playbooks/groups/badges-web.yml @@ -3,16 +3,6 @@ # NOTE: make sure there is room/space for this server on the vmhost # NOTE: most of these vars come from group_vars/badges-web* or from hostvars -- name: emit a fedmsg message that we are done - hosts: badges-web;badges-web-stg - user: root - gather_facts: False - tasks: - - local_action: fedmsg - cert_prefix="shell" - topic="playbook.start" - msg="just a test that we are starting" - - name: make badges-web server hosts: badges-web;badges-web-stg user: root @@ -61,13 +51,3 @@ handlers: - include: $handlers/restart_services.yml - -- name: emit a fedmsg message that we are done - hosts: badges-web;badges-web-stg - user: root - gather_facts: False - tasks: - - local_action: fedmsg - cert_prefix="shell" - topic="playbook.complete" - msg="just a test that we are completing"