diff --git a/lib/ansible/executor/task_queue_manager.py b/lib/ansible/executor/task_queue_manager.py index 1189e35f914..59f48142b19 100644 --- a/lib/ansible/executor/task_queue_manager.py +++ b/lib/ansible/executor/task_queue_manager.py @@ -23,7 +23,6 @@ import multiprocessing import os import socket import sys -import tempfile from ansible import constants as C from ansible.errors import AnsibleError @@ -79,10 +78,6 @@ class TaskQueueManager: self._failed_hosts = dict() self._unreachable_hosts = dict() - # A temporary file (opened pre-fork) used by connection plugins for - # inter-process locking. - self._options.connection_lockfile = tempfile.TemporaryFile() - self._final_q = multiprocessing.Queue() # create the pool of worker threads, based on the number of forks specified diff --git a/lib/ansible/playbook/play_context.py b/lib/ansible/playbook/play_context.py index d4a184fa61c..5b56d2515be 100644 --- a/lib/ansible/playbook/play_context.py +++ b/lib/ansible/playbook/play_context.py @@ -24,6 +24,7 @@ __metaclass__ = type import pipes import random import re +import tempfile from ansible import constants as C from ansible.errors import AnsibleError @@ -161,7 +162,6 @@ class PlayContext(Base): _private_key_file = FieldAttribute(isa='string', default=C.DEFAULT_PRIVATE_KEY_FILE) _timeout = FieldAttribute(isa='int', default=C.DEFAULT_TIMEOUT) _shell = FieldAttribute(isa='string') - _connection_lockfd= FieldAttribute(isa='int', default=None) # privilege escalation fields _become = FieldAttribute(isa='bool') @@ -200,6 +200,10 @@ class PlayContext(Base): self.password = passwords.get('conn_pass','') self.become_pass = passwords.get('become_pass','') + # A temporary file (opened pre-fork) used by connection + # plugins for inter-process locking. + self.connection_lockf = tempfile.TemporaryFile() + # set options before play to allow play to override them if options: self.set_options(options) @@ -245,11 +249,6 @@ class PlayContext(Base): if options.connection: self.connection = options.connection - # The lock file is opened in the parent process, and the workers will - # inherit the open file, so we just need to help them find it. - if options.connection_lockfile: - self.connection_lockfd = options.connection_lockfile.fileno() - self.remote_user = options.remote_user self.private_key_file = options.private_key_file @@ -328,6 +327,11 @@ class PlayContext(Base): return new_info + def copy(self, exclude_block=False): + new_me = super(PlayContext, self).copy() + new_me.connection_lockf = self.connection_lockf + return new_me + def make_become_cmd(self, cmd, executable=None): """ helper function to create privilege escalation commands """ diff --git a/lib/ansible/plugins/connections/__init__.py b/lib/ansible/plugins/connections/__init__.py index 5dfcf4c344b..0e4b3466e51 100644 --- a/lib/ansible/plugins/connections/__init__.py +++ b/lib/ansible/plugins/connections/__init__.py @@ -156,12 +156,12 @@ class ConnectionBase(with_metaclass(ABCMeta, object)): raise AnsibleError('Incorrect %s password' % self._play_context.become_method) def lock_connection(self): - f = self._play_context.connection_lockfd - self._display.vvvv('CONNECTION: pid %d waiting for lock on %d' % (os.getpid(), f)) - fcntl.lockf(f, fcntl.LOCK_EX) - self._display.vvvv('CONNECTION: pid %d acquired lock on %d' % (os.getpid(), f)) + f = self._play_context.connection_lockf + self._display.vvvv('CONNECTION: pid %d waiting for lock on %d' % (os.getpid(), f.fileno())) + fcntl.lockf(f.fileno(), fcntl.LOCK_EX) + self._display.vvvv('CONNECTION: pid %d acquired lock on %d' % (os.getpid(), f.fileno())) def unlock_connection(self): - f = self._play_context.connection_lockfd - fcntl.lockf(f, fcntl.LOCK_UN) - self._display.vvvv('CONNECTION: pid %d released lock on %d' % (os.getpid(), f)) + f = self._play_context.connection_lockf + fcntl.lockf(f.fileno(), fcntl.LOCK_UN) + self._display.vvvv('CONNECTION: pid %d released lock on %d' % (os.getpid(), f.fileno()))