summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Coca <brian.coca+git@gmail.com>2016-02-10 09:48:05 -0500
committerBrian Coca <brian.coca+git@gmail.com>2016-02-11 12:42:12 -0500
commit43bbd4b6dc4f61621bd82a4ff96ee877d8be614d (patch)
treec37e92383da8d1573ec2019f097557459a186d20
parent517eec8c4971462fe524735e4f4e60fad67e6dd5 (diff)
downloadansible-43bbd4b6dc4f61621bd82a4ff96ee877d8be614d.tar.gz
termination handling
- moved to base cli class to handle centrally and duplicate less code - now avoids duplication and reiteration of signal handler by reassigning it - left note on how to do non-graceful in case we add in future as I won't remember everything i did here and don't want to 'relearn' it.
-rw-r--r--lib/ansible/cli/__init__.py20
-rw-r--r--lib/ansible/cli/adhoc.py9
-rw-r--r--lib/ansible/executor/playbook_executor.py12
3 files changed, 19 insertions, 22 deletions
diff --git a/lib/ansible/cli/__init__.py b/lib/ansible/cli/__init__.py
index 1f7e9b9b43..506f43ab27 100644
--- a/lib/ansible/cli/__init__.py
+++ b/lib/ansible/cli/__init__.py
@@ -27,6 +27,7 @@ import time
import yaml
import re
import getpass
+import signal
import subprocess
from ansible import __version__
@@ -44,7 +45,7 @@ except ImportError:
class SortedOptParser(optparse.OptionParser):
'''Optparser which sorts the options by opt before outputting --help'''
- # TODO: epilog parsing: OptionParser.format_epilog = lambda self, formatter: self.epilog
+ #FIXME: epilog parsing: OptionParser.format_epilog = lambda self, formatter: self.epilog
def format_help(self, formatter=None, epilog=None):
self.option_list.sort(key=operator.methodcaller('get_opt_string'))
@@ -77,6 +78,20 @@ class CLI(object):
self.action = None
self.callback = callback
+ def _terminate(self, signum=None, framenum=None):
+ if signum == signal.SIGTERM:
+ if hasattr(os, 'getppid'):
+ display.debug("Termination requested in parent, shutting down gracefully")
+ signal.signal(signal.SIGTERM, signal.SIG_DFL)
+ else:
+ display.debug("Term signal in child, harakiri!")
+ signal.signal(signal.SIGTERM, signal.SIG_IGN)
+
+ raise SystemExit
+
+ #NOTE: if ever want to make this immediately kill children use on parent:
+ #os.killpg(os.getpgid(0), signal.SIGTERM)
+
def set_action(self):
"""
Get the action the user wants to execute from the sys argv list.
@@ -109,6 +124,9 @@ class CLI(object):
else:
display.display(u"No config file found; using defaults")
+ # Manage user interruptions
+ signal.signal(signal.SIGTERM, self._terminate)
+
@staticmethod
def ask_vault_passwords(ask_new_vault_pass=False, rekey=False):
''' prompt for vault password and/or password change '''
diff --git a/lib/ansible/cli/adhoc.py b/lib/ansible/cli/adhoc.py
index 4cba2be16c..7a3e208f36 100644
--- a/lib/ansible/cli/adhoc.py
+++ b/lib/ansible/cli/adhoc.py
@@ -21,7 +21,6 @@ __metaclass__ = type
########################################################
import os
-import signal
from ansible import constants as C
from ansible.cli import CLI
@@ -89,11 +88,6 @@ class AdHocCLI(CLI):
tasks = [ dict(action=dict(module=self.options.module_name, args=parse_kv(self.options.module_args)), async=async, poll=poll) ]
)
- def _terminate(self, signum=None, framenum=None):
- if signum is not None:
- display.debug("Termination signal detected, shutting down gracefully")
- raise SystemExit
-
def run(self):
''' use Runner lib to do SSH things '''
@@ -176,9 +170,6 @@ class AdHocCLI(CLI):
# now create a task queue manager to execute the play
self._tqm = None
try:
- # Manage user interruptions
- signal.signal(signal.SIGTERM, self._terminate)
-
self._tqm = TaskQueueManager(
inventory=inventory,
variable_manager=variable_manager,
diff --git a/lib/ansible/executor/playbook_executor.py b/lib/ansible/executor/playbook_executor.py
index 83449f1435..ce91b7f602 100644
--- a/lib/ansible/executor/playbook_executor.py
+++ b/lib/ansible/executor/playbook_executor.py
@@ -19,11 +19,7 @@
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
-import getpass
-import locale
import os
-import signal
-import sys
from ansible.compat.six import string_types
@@ -32,8 +28,6 @@ from ansible.executor.task_queue_manager import TaskQueueManager
from ansible.playbook import Playbook
from ansible.template import Templar
-from ansible.utils.unicode import to_unicode
-
try:
from __main__ import display
except ImportError:
@@ -69,8 +63,6 @@ class PlaybookExecutor:
may limit the runs to serialized groups, etc.
'''
- signal.signal(signal.SIGTERM, self._terminate)
-
result = 0
entrylist = []
entry = {}
@@ -207,10 +199,6 @@ class PlaybookExecutor:
return result
- def _terminate(self, signum=None, framenum=None):
- display.debug("Termination signal detected, shutting down gracefully")
- raise SystemExit
-
def _get_serialized_batches(self, play):
'''
Returns a list of hosts, subdivided into batches based on