summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarragh Bailey <dbailey@hpe.com>2016-01-19 12:06:46 +0000
committerDarragh Bailey <dbailey@hpe.com>2016-01-19 12:44:23 +0000
commit1200a7087972219e1adf8dc46b4c44c08d5a13f1 (patch)
treecf1231afaa2443803f88b0266cbeb99420d576ea
parent3d4dc206a1e7ede5aead9198dbd8633214194e2b (diff)
downloadansible-1200a7087972219e1adf8dc46b4c44c08d5a13f1.tar.gz
Fix race in daemon initialize using delegate_to
Ensure only one thread can start up an accelerate daemon on a target host where multiple hosts may be specified in the play, gather facts is disabled and the first task delegates to the same target host. This will slow down the initial connection to only allowing a single thread setup a connection at a time, however this should be of a negligible impact overall.
-rw-r--r--lib/ansible/runner/connection_plugins/accelerate.py14
1 files changed, 13 insertions, 1 deletions
diff --git a/lib/ansible/runner/connection_plugins/accelerate.py b/lib/ansible/runner/connection_plugins/accelerate.py
index 0627267c16..8b3d961854 100644
--- a/lib/ansible/runner/connection_plugins/accelerate.py
+++ b/lib/ansible/runner/connection_plugins/accelerate.py
@@ -21,6 +21,7 @@ import base64
import socket
import struct
import time
+import threading
from ansible.callbacks import vvv, vvvv
from ansible.errors import AnsibleError, AnsibleFileNotFound
from ansible.runner.connection_plugins.ssh import Connection as SSHConnection
@@ -35,6 +36,8 @@ from ansible import constants
# multiple of the value to speed up file reads.
CHUNK_SIZE=1044*20
+_LOCK = threading.Lock()
+
class Connection(object):
''' raw socket accelerated connection '''
@@ -111,6 +114,15 @@ class Connection(object):
def connect(self, allow_ssh=True):
''' activates the connection object '''
+ # ensure only one fork tries to setup the connection, in case the
+ # first task for multiple hosts is delegated to the same host.
+ if not self.is_connected:
+ with(_LOCK):
+ return self._connect(allow_ssh)
+
+ return self
+
+ def _connect(self, allow_ssh=True):
try:
if not self.is_connected:
wrong_user = False
@@ -150,7 +162,7 @@ class Connection(object):
res = self._execute_accelerate_module()
if not res.is_successful():
raise AnsibleError("Failed to launch the accelerated daemon on %s (reason: %s)" % (self.host,res.result.get('msg')))
- return self.connect(allow_ssh=False)
+ return self._connect(allow_ssh=False)
else:
raise AnsibleError("Failed to connect to %s:%s" % (self.host,self.accport))
self.is_connected = True