mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Notifable handlers only run when something is changed. Awesome.
This commit is contained in:
parent
de80166b6d
commit
79fdc1b6f4
3 changed files with 46 additions and 65 deletions
36
TODO.md
36
TODO.md
|
@ -1,36 +0,0 @@
|
||||||
TODO list and plans
|
|
||||||
===================
|
|
||||||
|
|
||||||
Playbook TODO:
|
|
||||||
|
|
||||||
* error codes and failure summaries
|
|
||||||
* handle 'changed' attributes
|
|
||||||
* fail nodes on errors, i.e. remove from host list, rather than continuing to pound them
|
|
||||||
* further improve output
|
|
||||||
* more conditional capability (if statement) (?)
|
|
||||||
* very good logging
|
|
||||||
|
|
||||||
Command module:
|
|
||||||
* magic to pull async & timeout options off of the command line and not feed them
|
|
||||||
to the app we're executing
|
|
||||||
|
|
||||||
General:
|
|
||||||
|
|
||||||
* better logging
|
|
||||||
* async options
|
|
||||||
* modules for users, groups, and files, using puppet style ensure mechanics
|
|
||||||
* think about how to build idempotency (aka Puppet-style 'creates') around command module?
|
|
||||||
|
|
||||||
Bonus utilities:
|
|
||||||
|
|
||||||
* ansible-inventory - gathering fact/hw info, storing in git, adding RSS
|
|
||||||
* ansible-slurp - recursively rsync file trees for each host
|
|
||||||
* maybe it's own fact engine, not required, that also feeds from facter
|
|
||||||
|
|
||||||
Not so interested really, but maybe:
|
|
||||||
|
|
||||||
* list available modules from command line
|
|
||||||
* add/remove/list hosts from the command line
|
|
||||||
* filter exclusion (run this only if fact is true/false)
|
|
||||||
-- should be doable with playbooks (i.e. not neccessary)
|
|
||||||
|
|
|
@ -6,17 +6,18 @@
|
||||||
- do:
|
- do:
|
||||||
- copy a file
|
- copy a file
|
||||||
- copy /srv/a /srv/b
|
- copy /srv/a /srv/b
|
||||||
|
notify:
|
||||||
|
- restart apache
|
||||||
- do:
|
- do:
|
||||||
- template from local file template.j2 to remote location /srv/file.out
|
- template from local file template.j2 to remote location /srv/file.out
|
||||||
- template /srv/template.j2 /srv/file.out
|
- template /srv/template.j2 /srv/file.out
|
||||||
- do:
|
notify:
|
||||||
- update apache
|
- restart apache
|
||||||
- command /usr/bin/yum update apache
|
- quack like a duck
|
||||||
onchange:
|
handlers:
|
||||||
- do:
|
- do:
|
||||||
- restart apache
|
- restart apache
|
||||||
- command /sbin/service apache restart
|
- command /sbin/service httpd restart
|
||||||
- do:
|
- do:
|
||||||
- run bin false
|
- quack like a duck
|
||||||
- command /bin/false
|
- command /bin/true
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,7 @@ class PlayBook(object):
|
||||||
timeout=self.timeout
|
timeout=self.timeout
|
||||||
)
|
)
|
||||||
|
|
||||||
def _run_task(self, pattern, task, host_list=None, conditional=False):
|
def _run_task(self, pattern=None, task=None, host_list=None, handlers=None, conditional=False):
|
||||||
'''
|
'''
|
||||||
run a single task in the playbook and
|
run a single task in the playbook and
|
||||||
recursively run any subtasks.
|
recursively run any subtasks.
|
||||||
|
@ -118,7 +118,7 @@ class PlayBook(object):
|
||||||
|
|
||||||
namestr = "%s/%s" % (pattern, comment)
|
namestr = "%s/%s" % (pattern, comment)
|
||||||
if conditional:
|
if conditional:
|
||||||
namestr = "subset/%s" % namestr
|
namestr = "notified/%s" % namestr
|
||||||
print "TASK [%s]" % namestr
|
print "TASK [%s]" % namestr
|
||||||
|
|
||||||
runner = self._get_task_runner(
|
runner = self._get_task_runner(
|
||||||
|
@ -130,15 +130,7 @@ class PlayBook(object):
|
||||||
results = runner.run()
|
results = runner.run()
|
||||||
|
|
||||||
dark = results.get("dark", [])
|
dark = results.get("dark", [])
|
||||||
|
|
||||||
contacted = results.get("contacted", [])
|
contacted = results.get("contacted", [])
|
||||||
|
|
||||||
# TODO: filter based on values that indicate
|
|
||||||
# they have changed events to emulate Puppet
|
|
||||||
# 'notify' behavior, super easy -- just
|
|
||||||
# a list comprehension -- but we need complaint
|
|
||||||
# modules first
|
|
||||||
|
|
||||||
ok_hosts = contacted.keys()
|
ok_hosts = contacted.keys()
|
||||||
|
|
||||||
for host, msg in dark.items():
|
for host, msg in dark.items():
|
||||||
|
@ -152,16 +144,30 @@ class PlayBook(object):
|
||||||
print "FAIL: [%s/%s]" % (host, comment, results)
|
print "FAIL: [%s/%s]" % (host, comment, results)
|
||||||
|
|
||||||
|
|
||||||
subtasks = task.get('onchange', [])
|
# flag which notify handlers need to be run
|
||||||
|
subtasks = task.get('notify', [])
|
||||||
if len(subtasks) > 0:
|
if len(subtasks) > 0:
|
||||||
|
for host, results in contacted.items():
|
||||||
|
if results.get('changed', False):
|
||||||
for subtask in subtasks:
|
for subtask in subtasks:
|
||||||
self._run_task(pattern, subtask, ok_hosts, conditional=True)
|
self._flag_handler(handlers, subtask, host)
|
||||||
|
|
||||||
# TODO: if a host fails in task 1, add it to an excludes
|
# TODO: if a host fails in any task, remove it from
|
||||||
# list such that no other tasks in the list ever execute
|
# the host list immediately
|
||||||
# unlike Puppet, do not allow partial failure of the tree
|
|
||||||
# and continuing as far as possible. Fail fast.
|
|
||||||
|
|
||||||
|
def _flag_handler(self, handlers, match_name, host):
|
||||||
|
'''
|
||||||
|
if a task has any notify elements, flag handlers for run
|
||||||
|
at end of execution cycle for hosts that have indicated
|
||||||
|
changes have been made
|
||||||
|
'''
|
||||||
|
for x in handlers:
|
||||||
|
attribs = x["do"]
|
||||||
|
name = attribs[0]
|
||||||
|
if match_name == name:
|
||||||
|
if not x.has_key("run"):
|
||||||
|
x['run'] = []
|
||||||
|
x['run'].append(host)
|
||||||
|
|
||||||
def _run_pattern(self, pg):
|
def _run_pattern(self, pg):
|
||||||
'''
|
'''
|
||||||
|
@ -170,9 +176,19 @@ class PlayBook(object):
|
||||||
|
|
||||||
pattern = pg['pattern']
|
pattern = pg['pattern']
|
||||||
tasks = pg['tasks']
|
tasks = pg['tasks']
|
||||||
|
handlers = pg['handlers']
|
||||||
|
|
||||||
for task in tasks:
|
for task in tasks:
|
||||||
self._run_task(pattern, task)
|
self._run_task(pattern=pattern, task=task, handlers=handlers)
|
||||||
|
for task in handlers:
|
||||||
|
if type(task.get("run", None)) == list:
|
||||||
|
self._run_task(
|
||||||
|
pattern=pattern,
|
||||||
|
task=task,
|
||||||
|
handlers=handlers,
|
||||||
|
host_list=task.get('run',[]),
|
||||||
|
conditional=True
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue