Merge pull request #1202 from dagwieers/abort-play-abort-playbook

Abort a play at the start when no hosts matches, or no hosts are remaining
This commit is contained in:
Michael DeHaan 2012-10-02 19:02:27 -07:00
commit cef73d1545
3 changed files with 29 additions and 6 deletions

View file

@ -63,6 +63,12 @@ class CallbackModule(object):
def playbook_on_notify(self, host, handler): def playbook_on_notify(self, host, handler):
pass pass
def on_no_hosts_matched(self):
pass
def on_no_hosts_remaining(self):
pass
def playbook_on_task_start(self, name, is_conditional): def playbook_on_task_start(self, name, is_conditional):
pass pass

View file

@ -414,6 +414,14 @@ class PlaybookCallbacks(object):
def on_notify(self, host, handler): def on_notify(self, host, handler):
call_callback_module('playbook_on_notify', host, handler) call_callback_module('playbook_on_notify', host, handler)
def on_no_hosts_matched(self):
print stringc("no hosts matched", 'red')
call_callback_module('playbook_on_no_hosts_matched')
def on_no_hosts_remaining(self):
print stringc("\nFATAL: all hosts have already failed -- aborting", 'red')
call_callback_module('playbook_on_no_hosts_remaining')
def on_task_start(self, name, is_conditional): def on_task_start(self, name, is_conditional):
msg = "TASK: [%s]" % name msg = "TASK: [%s]" % name
if is_conditional: if is_conditional:

View file

@ -115,9 +115,6 @@ class PlayBook(object):
(self.playbook, self.play_basedirs) = self._load_playbook_from_file(playbook) (self.playbook, self.play_basedirs) = self._load_playbook_from_file(playbook)
self.module_path = self.module_path + os.pathsep + os.path.join(self.basedir, "library") self.module_path = self.module_path + os.pathsep + os.path.join(self.basedir, "library")
# which task we are currently executing
self.task_counter = 0
# ***************************************************** # *****************************************************
def _load_playbook_from_file(self, path): def _load_playbook_from_file(self, path):
@ -239,8 +236,6 @@ class PlayBook(object):
# if not polling, playbook requested fire and forget, so don't poll # if not polling, playbook requested fire and forget, so don't poll
results = self._async_poll(poller, task.async_seconds, task.async_poll_interval) results = self._async_poll(poller, task.async_seconds, task.async_poll_interval)
self.task_counter = self.task_counter + 1
contacted = results.get('contacted',{}) contacted = results.get('contacted',{})
dark = results.get('dark', {}) dark = results.get('dark', {})
@ -350,6 +345,11 @@ class PlayBook(object):
self.callbacks.on_play_start(play.name) self.callbacks.on_play_start(play.name)
# if no hosts matches this play, drop out
if not self.inventory.list_hosts(play.hosts):
self.callbacks.on_no_hosts_matched()
return True
# get facts from system # get facts from system
self._do_setup_step(play) self._do_setup_step(play)
@ -388,7 +388,15 @@ class PlayBook(object):
# whether no hosts matched is fatal or not depends if it was on the initial step. # whether no hosts matched is fatal or not depends if it was on the initial step.
# if we got exactly no hosts on the first step (setup!) then the host group # if we got exactly no hosts on the first step (setup!) then the host group
# just didn't match anything and that's ok # just didn't match anything and that's ok
return (self.task_counter <= 1) return False
host_list = [ h for h in self.inventory.list_hosts(play.hosts)
if not (h in self.stats.failures or h in self.stats.dark) ]
# if no hosts remain, drop out
if not host_list:
self.callbacks.on_no_hosts_remaining()
return False
# run notify actions # run notify actions
for handler in play.handlers(): for handler in play.handlers():
@ -398,5 +406,6 @@ class PlayBook(object):
self.inventory.lift_restriction() self.inventory.lift_restriction()
self.inventory.lift_also_restriction() self.inventory.lift_also_restriction()
return True return True