def __init__(self, runner, host, port, user, password, private_key_file, *args, **kwargs): self.runner = runner self.host = host self.context = None self.conn = None self.user = user self.key = utils.key_for_hostname(host) self.port = port[0] self.fbport = port[1] self.is_connected = False if self.runner.original_transport == "paramiko": self.ssh = ParamikoConnection(runner=self.runner, host=self.host, port=self.port, user=self.user, password=password, private_key_file=private_key_file) else: self.ssh = SSHConnection(runner=self.runner, host=self.host, port=self.port, user=self.user, password=password, private_key_file=private_key_file) # attempt to work around shared-memory funness if getattr(self.runner, 'aes_keys', None): utils.AES_KEYS = self.runner.aes_keys
def __init__(self, runner, host, port, user, password, private_key_file, *args, **kwargs): self.runner = runner self.host = host self.context = None self.conn = None self.user = user self.key = utils.key_for_hostname(host) self.port = port[0] self.accport = port[1] self.is_connected = False self.has_pipelining = False self.become_methods_supported=['sudo'] if not self.port: self.port = constants.DEFAULT_REMOTE_PORT elif not isinstance(self.port, int): self.port = int(self.port) if not self.accport: self.accport = constants.ACCELERATE_PORT elif not isinstance(self.accport, int): self.accport = int(self.accport) if self.runner.original_transport == "paramiko": self.ssh = ParamikoConnection( runner=self.runner, host=self.host, port=self.port, user=self.user, password=password, private_key_file=private_key_file ) else: self.ssh = SSHConnection( runner=self.runner, host=self.host, port=self.port, user=self.user, password=password, private_key_file=private_key_file ) if not getattr(self.ssh, 'shell', None): self.ssh.shell = utils.plugins.shell_loader.get('sh') # attempt to work around shared-memory funness if getattr(self.runner, 'aes_keys', None): utils.AES_KEYS = self.runner.aes_keys
def __init__(self, runner, host, port, user, password, private_key_file, *args, **kwargs): self.runner = runner self.host = host self.context = None self.conn = None self.user = user self.key = utils.key_for_hostname(host) self.port = port[0] self.accport = port[1] self.is_connected = False self.has_pipelining = False if not self.port: self.port = constants.DEFAULT_REMOTE_PORT elif not isinstance(self.port, int): self.port = int(self.port) if not self.accport: self.accport = constants.ACCELERATE_PORT elif not isinstance(self.accport, int): self.accport = int(self.accport) if self.runner.original_transport == "paramiko": self.ssh = ParamikoConnection( runner=self.runner, host=self.host, port=self.port, user=self.user, password=password, private_key_file=private_key_file ) else: self.ssh = SSHConnection( runner=self.runner, host=self.host, port=self.port, user=self.user, password=password, private_key_file=private_key_file ) if not getattr(self.ssh, 'shell', None): self.ssh.shell = utils.plugins.shell_loader.get('sh') # attempt to work around shared-memory funness if getattr(self.runner, 'aes_keys', None): utils.AES_KEYS = self.runner.aes_keys
def __init__(self, runner, host, port, user, password, private_key_file, *args, **kwargs): self.runner = runner self.host = host self.context = None self.conn = None self.user = user self.key = utils.key_for_hostname(host) self.port = port[0] self.accport = port[1] self.is_connected = False if not self.port: self.port = constants.DEFAULT_REMOTE_PORT elif not isinstance(self.port, int): self.port = int(self.port) if not self.accport: self.accport = constants.ACCELERATE_PORT elif not isinstance(self.accport, int): self.accport = int(self.accport) self.ssh = SSHConnection(runner=self.runner, host=self.host, port=self.port, user=self.user, password=password, private_key_file=private_key_file) # attempt to work around shared-memory funness if getattr(self.runner, 'aes_keys', None): utils.AES_KEYS = self.runner.aes_keys
def __init__(self, runner, host, port, user, password, private_key_file, *args, **kwargs): self.runner = runner self.host = host self.context = None self.conn = None self.user = user self.key = utils.key_for_hostname(host) self.port = port[0] self.accport = port[1] self.is_connected = False if not self.port: self.port = constants.DEFAULT_REMOTE_PORT elif not isinstance(self.port, int): self.port = int(self.port) if not self.accport: self.accport = constants.ACCELERATE_PORT elif not isinstance(self.accport, int): self.accport = int(self.accport) self.ssh = SSHConnection( runner=self.runner, host=self.host, port=self.port, user=self.user, password=password, private_key_file=private_key_file ) # attempt to work around shared-memory funness if getattr(self.runner, 'aes_keys', None): utils.AES_KEYS = self.runner.aes_keys
def __init__(self, runner, host, port, user, password, private_key_file, *args, **kwargs): self.host = host jaildef, self.jailhost = host.split('@',1) self.jname = re.sub(r'\W','_',jaildef) self.runner = runner self.has_pipelining = False self.ssh = SSHConn(runner, self.jailhost, port, user, password, private_key_file, *args) self.jid = None self.path = None self.juser = None self.matched = False
def __init__(self, runner, host, port, user, password, private_key_file, *args, **kwargs): self.host = host jaildef, self.jailhost = host.split('@', 1) self.jname = re.sub(r'\W', '_', jaildef) self.runner = runner self.has_pipelining = False self.ssh = SSHConn(runner, self.jailhost, port, user, password, private_key_file, *args) self.jid = None self.path = None self.juser = None self.matched = False
def test_exec_command_allOutput(self): """ ssh.Connection.exec_command should capture all output. """ tmpdir = tempfile.mkdtemp() script_guts = (''' import sys import os sys.stdout.write('a') sys.stdout.flush() os.write(2, 'b') os.close(2) sys.stdout.write('End') ''') script_name = os.path.join(tmpdir, 'script.py') fh = open(script_name, 'w') fh.write(script_guts) fh.close() runner = FakeRunner() runner.process_lockfile = open(os.path.join(tmpdir, 'process'), 'w') runner.output_lockfile = open(os.path.join(tmpdir, 'output'), 'w') conn = Connection(runner, '', '', '', '', '') conn._password_cmd = lambda: [sys.executable, script_name] conn._send_password = lambda: None conn.common_args = [] tmpdir2 = tempfile.mkdtemp() rc, x, out, err = conn.exec_command('ignored', tmpdir2, 'root') self.assertEqual(out, 'aEnd', "All stdout should be read") self.assertEqual(err, 'b', "All stderr should be read") self.assertEqual(rc, 0, "Process should exit with success")
def __init__(self, runner, host, port, user, password, private_key_file, *args, **kwargs): # [email protected] => my-jail is jail name/hostname, my.jailhost is jailhost hostname self.host = host self.jailspec, self.jailhost = host.split('@',1) # piggyback off of the standard SSH connection self.runner = runner self.has_pipelining = False self.ssh = SSHConn(runner, self.jailhost, port, user, password, private_key_file, *args) # jail information loaded on first use by match_jail self.jid = None self.jname = None self.jhost = None self.jpath = None
def __init__(self, runner, host, port, user, password, private_key_file, *args, **kwargs): # [email protected] => my-jail is jail name/hostname, my.jailhost is jailhost hostname self.host = host self.jailspec, self.jailhost = host.split('@', 1) # piggyback off of the standard SSH connection self.runner = runner self.has_pipelining = False self.ssh = SSHConn(runner, self.jailhost, port, user, password, private_key_file, *args) # jail information loaded on first use by match_jail self.jid = None self.jname = None self.jhost = None self.jpath = None
class Connection(object): ''' jail-over-ssh based connections ''' def match_jail(self): if self.jid == None: code, _, stdout, stderr = self._exec_command( "jls -q jid name host.hostname path") if code != 0: vvv("JLS stdout: %s" % stdout) raise errors.AnsibleError("jls returned non-zero!") lines = stdout.strip().split('\n') found = False for line in lines: if line.strip() == '': break jid, name, hostname, path = line.strip().split() if name == self.jailspec or hostname == self.jailspec: self.jid = jid self.jname = name self.jhost = hostname self.jpath = path found = True break if not found: raise errors.AnsibleError( "failed to find a jail with name or hostname of '%s'" % self.jailspec) def get_jail_path(self): self.match_jail() return self.jpath def get_jail_id(self): self.match_jail() return self.jid def get_tmp_file(self): code, _, stdout, stderr = self._exec_command('mktemp', '', None) return stdout.strip().split('\n')[-1] def __init__(self, runner, host, port, user, password, private_key_file, *args, **kwargs): # [email protected] => my-jail is jail name/hostname, my.jailhost is jailhost hostname self.host = host self.jailspec, self.jailhost = host.split('@', 1) # piggyback off of the standard SSH connection self.runner = runner self.has_pipelining = False self.ssh = SSHConn(runner, self.jailhost, port, user, password, private_key_file, *args) # jail information loaded on first use by match_jail self.jid = None self.jname = None self.jhost = None self.jpath = None def connect(self, port=None): self.ssh.connect() return self # runs a command on the jailhost, rather than inside the jail def _exec_command(self, cmd, tmp_path='', become_user=None, sudoable=False, executable='/bin/sh', in_data=None): return self.ssh.exec_command(cmd, tmp_path, become_user, sudoable, executable, in_data) def exec_command(self, cmd, tmp_path, become_user=None, sudoable=False, executable='/bin/sh', in_data=None): ''' run a command in the jail ''' if executable: cmd = ' '.join([executable, '-c', '"%s"' % cmd]) local_cmd = 'which -s jailme && jailme %s %s || jexec %s %s' % ( self.get_jail_id(), cmd, self.get_jail_id(), cmd) vvv("JAIL (%s) %s" % (become_user, local_cmd), host=self.host) return self._exec_command(local_cmd, tmp_path, become_user, True, executable, in_data) def _normalize_path(self, path, prefix): if not path.startswith(os.path.sep): path = os.path.join(os.path.sep, path) normpath = os.path.normpath(path) return os.path.join(prefix, normpath[1:]) def put_file(self, in_path, out_path): ''' transfer a file from local to remote jail ''' tmp = self.get_tmp_file() self.ssh.put_file(in_path, tmp) out_path = self._normalize_path(out_path, self.get_jail_path()) code, _, stdout, stderr = self._exec_command(' '.join( ['chmod 0644', tmp])) if code != 0: raise errors.AnsibleError( "failed to make temp file %s world readable:\n%s\n%s" % (tmp, stdout, stderr)) code, _, stdout, stderr = self._exec_command( ' '.join(['cp', tmp, out_path]), '', self.runner.become_user, True) if code != 0: raise errors.AnsibleError( "failed to move file from %s to %s:\n%s\n%s" % (tmp, out_path, stdout, stderr)) code, _, stdout, stderr = self._exec_command(' '.join(['rm', tmp])) if code != 0: raise errors.AnsibleError( "failed to remove temp file %s:\n%s\n%s" % (tmp, stdout, stderr)) def fetch_file(self, in_path, out_path): ''' fetch a file from remote jail to local ''' tmp = self.get_tmp_file() in_path = self._normalize_path(in_path, self.get_jail_path()) self._exec_command(' '.join(['mv', in_path, tmp]), '', self.juser, True) self.ssh.fetch_file(tmp, out_path) def close(self): ''' terminate the connection; nothing to do here ''' pass
class Connection(object): ''' raw socket accelerated connection ''' def __init__(self, runner, host, port, user, password, private_key_file, *args, **kwargs): self.runner = runner self.host = host self.context = None self.conn = None self.user = user self.key = utils.key_for_hostname(host) self.port = port[0] self.accport = port[1] self.is_connected = False if not self.port: self.port = constants.DEFAULT_REMOTE_PORT elif not isinstance(self.port, int): self.port = int(self.port) if not self.accport: self.accport = constants.ACCELERATE_PORT elif not isinstance(self.accport, int): self.accport = int(self.accport) self.ssh = SSHConnection( runner=self.runner, host=self.host, port=self.port, user=self.user, password=password, private_key_file=private_key_file ) # attempt to work around shared-memory funness if getattr(self.runner, 'aes_keys', None): utils.AES_KEYS = self.runner.aes_keys def _execute_accelerate_module(self): args = "password=%s port=%s debug=%d" % (base64.b64encode(self.key.__str__()), str(self.accport), int(utils.VERBOSITY)) inject = dict(password=self.key) if self.runner.accelerate_inventory_host: inject = utils.combine_vars(inject, self.runner.inventory.get_variables(self.runner.accelerate_inventory_host)) else: inject = utils.combine_vars(inject, self.runner.inventory.get_variables(self.host)) vvvv("attempting to start up the accelerate daemon...") self.ssh.connect() tmp_path = self.runner._make_tmp_path(self.ssh) return self.runner._execute_module(self.ssh, tmp_path, 'accelerate', args, inject=inject) def connect(self, allow_ssh=True): ''' activates the connection object ''' try: if not self.is_connected: tries = 3 self.conn = socket.socket() self.conn.settimeout(constants.ACCELERATE_CONNECT_TIMEOUT) vvvv("attempting connection to %s via the accelerated port %d" % (self.host,self.accport)) while tries > 0: try: self.conn.connect((self.host,self.accport)) break except: vvvv("failed, retrying...") time.sleep(0.1) tries -= 1 if tries == 0: vvv("Could not connect via the accelerated connection, exceeded # of tries") raise errors.AnsibleError("Failed to connect") self.conn.settimeout(constants.ACCELERATE_TIMEOUT) except: if allow_ssh: vvv("Falling back to ssh to startup accelerated mode") res = self._execute_accelerate_module() if not res.is_successful(): raise errors.AnsibleError("Failed to launch the accelerated daemon on %s (reason: %s)" % (self.host,res.result.get('msg'))) return self.connect(allow_ssh=False) else: raise errors.AnsibleError("Failed to connect to %s:%s" % (self.host,self.accport)) self.is_connected = True return self def send_data(self, data): packed_len = struct.pack('Q',len(data)) return self.conn.sendall(packed_len + data) def recv_data(self): header_len = 8 # size of a packed unsigned long long data = b"" try: vvvv("%s: in recv_data(), waiting for the header" % self.host) while len(data) < header_len: d = self.conn.recv(header_len - len(data)) if not d: vvvv("%s: received nothing, bailing out" % self.host) return None data += d vvvv("%s: got the header, unpacking" % self.host) data_len = struct.unpack('Q',data[:header_len])[0] data = data[header_len:] vvvv("%s: data received so far (expecting %d): %d" % (self.host,data_len,len(data))) while len(data) < data_len: d = self.conn.recv(data_len - len(data)) if not d: vvvv("%s: received nothing, bailing out" % self.host) return None data += d vvvv("%s: received all of the data, returning" % self.host) return data except socket.timeout: raise errors.AnsibleError("timed out while waiting to receive data") def exec_command(self, cmd, tmp_path, sudo_user, sudoable=False, executable='/bin/sh'): ''' run a command on the remote host ''' if executable == "": executable = constants.DEFAULT_EXECUTABLE if self.runner.sudo and sudoable and sudo_user: cmd, prompt = utils.make_sudo_cmd(sudo_user, executable, cmd) vvv("EXEC COMMAND %s" % cmd) data = dict( mode='command', cmd=cmd, tmp_path=tmp_path, executable=executable, ) data = utils.jsonify(data) data = utils.encrypt(self.key, data) if self.send_data(data): raise errors.AnsibleError("Failed to send command to %s" % self.host) while True: # we loop here while waiting for the response, because a # long running command may cause us to receive keepalive packets # ({"pong":"true"}) rather than the response we want. response = self.recv_data() if not response: raise errors.AnsibleError("Failed to get a response from %s" % self.host) response = utils.decrypt(self.key, response) response = utils.parse_json(response) if "pong" in response: # it's a keepalive, go back to waiting vvvv("%s: received a keepalive packet" % self.host) continue else: vvvv("%s: received the response" % self.host) break return (response.get('rc',None), '', response.get('stdout',''), response.get('stderr','')) def put_file(self, in_path, out_path): ''' transfer a file from local to remote ''' vvv("PUT %s TO %s" % (in_path, out_path), host=self.host) if not os.path.exists(in_path): raise errors.AnsibleFileNotFound("file or module does not exist: %s" % in_path) fd = file(in_path, 'rb') fstat = os.stat(in_path) try: vvv("PUT file is %d bytes" % fstat.st_size) while fd.tell() < fstat.st_size: data = fd.read(CHUNK_SIZE) last = False if fd.tell() >= fstat.st_size: last = True data = dict(mode='put', data=base64.b64encode(data), out_path=out_path, last=last) if self.runner.sudo: data['user'] = self.runner.sudo_user data = utils.jsonify(data) data = utils.encrypt(self.key, data) if self.send_data(data): raise errors.AnsibleError("failed to send the file to %s" % self.host) response = self.recv_data() if not response: raise errors.AnsibleError("Failed to get a response from %s" % self.host) response = utils.decrypt(self.key, response) response = utils.parse_json(response) if response.get('failed',False): raise errors.AnsibleError("failed to put the file in the requested location") finally: fd.close() response = self.recv_data() if not response: raise errors.AnsibleError("Failed to get a response from %s" % self.host) response = utils.decrypt(self.key, response) response = utils.parse_json(response) if response.get('failed',False): raise errors.AnsibleError("failed to put the file in the requested location") def fetch_file(self, in_path, out_path): ''' save a remote file to the specified path ''' vvv("FETCH %s TO %s" % (in_path, out_path), host=self.host) data = dict(mode='fetch', in_path=in_path) data = utils.jsonify(data) data = utils.encrypt(self.key, data) if self.send_data(data): raise errors.AnsibleError("failed to initiate the file fetch with %s" % self.host) fh = open(out_path, "w") try: bytes = 0 while True: response = self.recv_data() if not response: raise errors.AnsibleError("Failed to get a response from %s" % self.host) response = utils.decrypt(self.key, response) response = utils.parse_json(response) if response.get('failed', False): raise errors.AnsibleError("Error during file fetch, aborting") out = base64.b64decode(response['data']) fh.write(out) bytes += len(out) # send an empty response back to signify we # received the last chunk without errors data = utils.jsonify(dict()) data = utils.encrypt(self.key, data) if self.send_data(data): raise errors.AnsibleError("failed to send ack during file fetch") if response.get('last', False): break finally: # we don't currently care about this final response, # we just receive it and drop it. It may be used at some # point in the future or we may just have the put/fetch # operations not send back a final response at all response = self.recv_data() vvv("FETCH wrote %d bytes to %s" % (bytes, out_path)) fh.close() def close(self): ''' terminate the connection ''' # Be a good citizen try: self.conn.close() except: pass
class Connection(object): ''' raw socket accelerated connection ''' def __init__(self, runner, host, port, user, password, private_key_file, *args, **kwargs): self.runner = runner self.host = host self.context = None self.conn = None self.user = user self.key = utils.key_for_hostname(host) self.port = port[0] self.accport = port[1] self.is_connected = False if not self.port: self.port = constants.DEFAULT_REMOTE_PORT elif not isinstance(self.port, int): self.port = int(self.port) if not self.accport: self.accport = constants.ACCELERATE_PORT elif not isinstance(self.accport, int): self.accport = int(self.accport) if self.runner.original_transport == "paramiko": self.ssh = ParamikoConnection( runner=self.runner, host=self.host, port=self.port, user=self.user, password=password, private_key_file=private_key_file ) else: self.ssh = SSHConnection( runner=self.runner, host=self.host, port=self.port, user=self.user, password=password, private_key_file=private_key_file ) # attempt to work around shared-memory funness if getattr(self.runner, 'aes_keys', None): utils.AES_KEYS = self.runner.aes_keys def _execute_accelerate_module(self): args = "password=%s port=%s debug=%d ipv6=%s" % (base64.b64encode(self.key.__str__()), str(self.accport), int(utils.VERBOSITY), self.runner.accelerate_ipv6) inject = dict(password=self.key) if getattr(self.runner, 'accelerate_inventory_host', False): inject = utils.combine_vars(inject, self.runner.inventory.get_variables(self.runner.accelerate_inventory_host)) else: inject = utils.combine_vars(inject, self.runner.inventory.get_variables(self.host)) vvvv("attempting to start up the accelerate daemon...") self.ssh.connect() tmp_path = self.runner._make_tmp_path(self.ssh) return self.runner._execute_module(self.ssh, tmp_path, 'accelerate', args, inject=inject) def connect(self, allow_ssh=True): ''' activates the connection object ''' try: if not self.is_connected: tries = 3 self.conn = socket.socket() self.conn.settimeout(constants.ACCELERATE_CONNECT_TIMEOUT) vvvv("attempting connection to %s via the accelerated port %d" % (self.host,self.accport)) while tries > 0: try: self.conn.connect((self.host,self.accport)) break except: vvvv("failed, retrying...") time.sleep(0.1) tries -= 1 if tries == 0: vvv("Could not connect via the accelerated connection, exceeded # of tries") raise errors.AnsibleError("Failed to connect") self.conn.settimeout(constants.ACCELERATE_TIMEOUT) except: if allow_ssh: vvv("Falling back to ssh to startup accelerated mode") res = self._execute_accelerate_module() if not res.is_successful(): raise errors.AnsibleError("Failed to launch the accelerated daemon on %s (reason: %s)" % (self.host,res.result.get('msg'))) return self.connect(allow_ssh=False) else: raise errors.AnsibleError("Failed to connect to %s:%s" % (self.host,self.accport)) self.is_connected = True return self def send_data(self, data): packed_len = struct.pack('!Q',len(data)) return self.conn.sendall(packed_len + data) def recv_data(self): header_len = 8 # size of a packed unsigned long long data = b"" try: vvvv("%s: in recv_data(), waiting for the header" % self.host) while len(data) < header_len: d = self.conn.recv(header_len - len(data)) if not d: vvvv("%s: received nothing, bailing out" % self.host) return None data += d vvvv("%s: got the header, unpacking" % self.host) data_len = struct.unpack('!Q',data[:header_len])[0] data = data[header_len:] vvvv("%s: data received so far (expecting %d): %d" % (self.host,data_len,len(data))) while len(data) < data_len: d = self.conn.recv(data_len - len(data)) if not d: vvvv("%s: received nothing, bailing out" % self.host) return None data += d vvvv("%s: received all of the data, returning" % self.host) return data except socket.timeout: raise errors.AnsibleError("timed out while waiting to receive data") def exec_command(self, cmd, tmp_path, sudo_user, sudoable=False, executable='/bin/sh'): ''' run a command on the remote host ''' if executable == "": executable = constants.DEFAULT_EXECUTABLE if self.runner.sudo and sudoable and sudo_user: cmd, prompt, success_key = utils.make_sudo_cmd(sudo_user, executable, cmd) vvv("EXEC COMMAND %s" % cmd) data = dict( mode='command', cmd=cmd, tmp_path=tmp_path, executable=executable, ) data = utils.jsonify(data) data = utils.encrypt(self.key, data) if self.send_data(data): raise errors.AnsibleError("Failed to send command to %s" % self.host) while True: # we loop here while waiting for the response, because a # long running command may cause us to receive keepalive packets # ({"pong":"true"}) rather than the response we want. response = self.recv_data() if not response: raise errors.AnsibleError("Failed to get a response from %s" % self.host) response = utils.decrypt(self.key, response) response = utils.parse_json(response) if "pong" in response: # it's a keepalive, go back to waiting vvvv("%s: received a keepalive packet" % self.host) continue else: vvvv("%s: received the response" % self.host) break return (response.get('rc',None), '', response.get('stdout',''), response.get('stderr','')) def put_file(self, in_path, out_path): ''' transfer a file from local to remote ''' vvv("PUT %s TO %s" % (in_path, out_path), host=self.host) if not os.path.exists(in_path): raise errors.AnsibleFileNotFound("file or module does not exist: %s" % in_path) fd = file(in_path, 'rb') fstat = os.stat(in_path) try: vvv("PUT file is %d bytes" % fstat.st_size) last = False while fd.tell() <= fstat.st_size and not last: vvvv("file position currently %ld, file size is %ld" % (fd.tell(), fstat.st_size)) data = fd.read(CHUNK_SIZE) if fd.tell() >= fstat.st_size: last = True data = dict(mode='put', data=base64.b64encode(data), out_path=out_path, last=last) if self.runner.sudo: data['user'] = self.runner.sudo_user data = utils.jsonify(data) data = utils.encrypt(self.key, data) if self.send_data(data): raise errors.AnsibleError("failed to send the file to %s" % self.host) response = self.recv_data() if not response: raise errors.AnsibleError("Failed to get a response from %s" % self.host) response = utils.decrypt(self.key, response) response = utils.parse_json(response) if response.get('failed',False): raise errors.AnsibleError("failed to put the file in the requested location") finally: fd.close() vvvv("waiting for final response after PUT") response = self.recv_data() if not response: raise errors.AnsibleError("Failed to get a response from %s" % self.host) response = utils.decrypt(self.key, response) response = utils.parse_json(response) if response.get('failed',False): raise errors.AnsibleError("failed to put the file in the requested location") def fetch_file(self, in_path, out_path): ''' save a remote file to the specified path ''' vvv("FETCH %s TO %s" % (in_path, out_path), host=self.host) data = dict(mode='fetch', in_path=in_path) data = utils.jsonify(data) data = utils.encrypt(self.key, data) if self.send_data(data): raise errors.AnsibleError("failed to initiate the file fetch with %s" % self.host) fh = open(out_path, "w") try: bytes = 0 while True: response = self.recv_data() if not response: raise errors.AnsibleError("Failed to get a response from %s" % self.host) response = utils.decrypt(self.key, response) response = utils.parse_json(response) if response.get('failed', False): raise errors.AnsibleError("Error during file fetch, aborting") out = base64.b64decode(response['data']) fh.write(out) bytes += len(out) # send an empty response back to signify we # received the last chunk without errors data = utils.jsonify(dict()) data = utils.encrypt(self.key, data) if self.send_data(data): raise errors.AnsibleError("failed to send ack during file fetch") if response.get('last', False): break finally: # we don't currently care about this final response, # we just receive it and drop it. It may be used at some # point in the future or we may just have the put/fetch # operations not send back a final response at all response = self.recv_data() vvv("FETCH wrote %d bytes to %s" % (bytes, out_path)) fh.close() def close(self): ''' terminate the connection ''' # Be a good citizen try: self.conn.close() except: pass
class Connection(object): ''' raw socket accelerated connection ''' def __init__(self, runner, host, port, user, password, private_key_file, *args, **kwargs): self.runner = runner self.host = host self.context = None self.conn = None self.user = user self.key = utils.key_for_hostname(host) self.port = port[0] self.accport = port[1] self.is_connected = False self.has_pipelining = False self.become_methods_supported = ['sudo'] if not self.port: self.port = constants.DEFAULT_REMOTE_PORT elif not isinstance(self.port, int): self.port = int(self.port) if not self.accport: self.accport = constants.ACCELERATE_PORT elif not isinstance(self.accport, int): self.accport = int(self.accport) if self.runner.original_transport == "paramiko": self.ssh = ParamikoConnection(runner=self.runner, host=self.host, port=self.port, user=self.user, password=password, private_key_file=private_key_file) else: self.ssh = SSHConnection(runner=self.runner, host=self.host, port=self.port, user=self.user, password=password, private_key_file=private_key_file) if not getattr(self.ssh, 'shell', None): self.ssh.shell = utils.plugins.shell_loader.get('sh') # attempt to work around shared-memory funness if getattr(self.runner, 'aes_keys', None): utils.AES_KEYS = self.runner.aes_keys def _execute_accelerate_module(self): args = "password=%s port=%s minutes=%d debug=%d ipv6=%s" % ( base64.b64encode(self.key.__str__()), str(self.accport), constants.ACCELERATE_DAEMON_TIMEOUT, int(utils.VERBOSITY), self.runner.accelerate_ipv6, ) if constants.ACCELERATE_MULTI_KEY: args += " multi_key=yes" inject = dict(password=self.key) if getattr(self.runner, 'accelerate_inventory_host', False): inject = utils.combine_vars( inject, self.runner.inventory.get_variables( self.runner.accelerate_inventory_host)) else: inject = utils.combine_vars( inject, self.runner.inventory.get_variables(self.host)) vvvv("attempting to start up the accelerate daemon...") self.ssh.connect() tmp_path = self.runner._make_tmp_path(self.ssh) return self.runner._execute_module(self.ssh, tmp_path, 'accelerate', args, inject=inject) def connect(self, allow_ssh=True): ''' activates the connection object ''' try: if not self.is_connected: wrong_user = False tries = 3 self.conn = socket.socket() self.conn.settimeout(constants.ACCELERATE_CONNECT_TIMEOUT) vvvv( "attempting connection to %s via the accelerated port %d" % (self.host, self.accport)) while tries > 0: try: self.conn.connect((self.host, self.accport)) break except socket.error: vvvv("connection to %s failed, retrying..." % self.host) time.sleep(0.1) tries -= 1 if tries == 0: vvv("Could not connect via the accelerated connection, exceeded # of tries" ) raise AnsibleError("FAILED") elif wrong_user: vvv("Restarting daemon with a different remote_user") raise AnsibleError("WRONG_USER") self.conn.settimeout(constants.ACCELERATE_TIMEOUT) if not self.validate_user(): # the accelerated daemon was started with a # different remote_user. The above command # should have caused the accelerate daemon to # shutdown, so we'll reconnect. wrong_user = True except AnsibleError, e: if allow_ssh: if "WRONG_USER" in e: vvv("Switching users, waiting for the daemon on %s to shutdown completely..." % self.host) time.sleep(5) vvv("Falling back to ssh to startup accelerated mode") 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) else: raise AnsibleError("Failed to connect to %s:%s" % (self.host, self.accport)) self.is_connected = True return self
class Connection(object): ''' jail-over-ssh based connections ''' def get_jail_path(self): return self.path def get_jail_id(self): return self.jid def match_jail(self): code, _, stdout, stderr = self._exec_command(' '.join(['jls', 'name', 'jid', 'path'])) lines = stdout.strip().split('\n') lines = [ line.split() for line in lines ] names = dict( (re.sub(r'\W', '_', name), { 'name': name.strip(), 'jid': jid.strip(), 'path': path.strip(), }) for name, jid, path in lines ) if len(names) != len(lines): vvv("WARNING: This host's jail names are not unique after underscore-substitution!") # remove \n jail = names.get(self.jname) if jail: self.jid = jail['jid'] self.path = jail['path'] self.jname = jail['name'] vvv('Matched jail: %s' % self.jname) else: vvv('No jail found with name: %s' % self.jname) def get_tmp_file(self): code, _, stdout, stderr = self._exec_command('mktemp', '', None) return stdout.strip().split('\n')[-1] def __init__(self, runner, host, port, user, password, private_key_file, *args, **kwargs): self.host = host jaildef, self.jailhost = host.split('@',1) self.jname = re.sub(r'\W','_',jaildef) self.runner = runner self.has_pipelining = False self.ssh = SSHConn(runner, self.jailhost, port, user, password, private_key_file, *args) self.jid = None self.path = None self.juser = None self.matched = False def connect(self, port=None): self.ssh.connect() if not self.matched: self.match_jail() self.matched = True return self def _exec_command(self, cmd, tmp_path='', become_user=None, sudoable=False, executable='/bin/sh', in_data=None): # oh lordy I hate this approach, but we need to note what user we use to access the jail so put/fetch works if become_user != None: self.juser = become_user return self.ssh.exec_command(cmd, tmp_path, become_user, sudoable, executable, in_data) def exec_command(self, cmd, tmp_path, become_user=None, sudoable=False, executable='/bin/sh', in_data=None): ''' run a command in the jail ''' if SSHJAIL_USE_JAILME: jcmd = ['jailme', self.jid] else: jcmd = ['jexec', self.jname] if executable: local_cmd = ' '.join([jcmd[0], jcmd[1], executable, '-c', '"%s"' % cmd]) else: local_cmd = '%s "%s" "%s"' % (jcmd[0], jcmd[1], cmd) vvv("JAIL (%s) %s" % (become_user, local_cmd), host=self.host) return self._exec_command(local_cmd, tmp_path, become_user, True, executable, in_data) def _normalize_path(self, path, prefix): if not path.startswith(os.path.sep): path = os.path.join(os.path.sep, path) normpath = os.path.normpath(path) return os.path.join(prefix, normpath[1:]) def put_file(self, in_path, out_path): ''' transfer a file from local to remote jail ''' tmp = self.get_tmp_file() self.ssh.put_file(in_path, tmp) out_path = self._normalize_path(out_path, self.get_jail_path()) code, _, stdout, stderr = self._exec_command(' '.join(['chmod 0777',tmp])) if code != 0: raise errors.AnsibleError("failed to make temp file %s world writable:\n%s\n%s" % (tmp, stdout, stderr)) code, _, stdout, stderr = self._exec_command(' '.join(['cp',tmp,out_path]), '', self.juser, True) if code != 0: raise errors.AnsibleError("failed to move file from %s to %s:\n%s\n%s" % (tmp, out_path, stdout, stderr)) def fetch_file(self, in_path, out_path): ''' fetch a file from remote jail to local ''' tmp = self.get_tmp_file() in_path = self._normalize_path(in_path, self.get_jail_path()) self._exec_command(' '.join(['mv',in_path,tmp]), '', self.juser, True) self.ssh.fetch_file(tmp, out_path) def close(self): ''' terminate the connection; nothing to do here ''' pass
class Connection(object): ''' jail-over-ssh based connections ''' def match_jail(self): if self.jid == None: code, _, stdout, stderr = self._exec_command("jls -q jid name host.hostname path") if code != 0: vvv("JLS stdout: %s" % stdout) raise errors.AnsibleError("jls returned non-zero!") lines = stdout.strip().split('\n') found = False for line in lines: jid, name, hostname, path = line.strip().split() if name == self.jailspec or hostname == self.jailspec: self.jid = jid self.jname = name self.jhost = hostname self.jpath = path found = True break if not found: raise errors.AnsibleError("failed to find a jail with name or hostname of '%s'" % self.jailspec) def get_jail_path(self): self.match_jail() return self.jpath def get_jail_id(self): self.match_jail() return self.jid def get_tmp_file(self): code, _, stdout, stderr = self._exec_command('mktemp', '', None) return stdout.strip().split('\n')[-1] def __init__(self, runner, host, port, user, password, private_key_file, *args, **kwargs): # [email protected] => my-jail is jail name/hostname, my.jailhost is jailhost hostname self.host = host self.jailspec, self.jailhost = host.split('@',1) # piggyback off of the standard SSH connection self.runner = runner self.has_pipelining = False self.ssh = SSHConn(runner, self.jailhost, port, user, password, private_key_file, *args) # jail information loaded on first use by match_jail self.jid = None self.jname = None self.jhost = None self.jpath = None # loaded after first exec_command self.juser = None def connect(self, port=None): self.ssh.connect(); return self # runs a command on the jailhost, rather than inside the jail def _exec_command(self, cmd, tmp_path='', become_user=None, sudoable=False, executable='/bin/sh', in_data=None): # oh lordy I hate this approach, but we need to note what user we use to access the jail so put/fetch works if become_user != None: self.juser = become_user return self.ssh.exec_command(cmd, tmp_path, become_user, sudoable, executable, in_data) def exec_command(self, cmd, tmp_path, become_user=None, sudoable=False, executable='/bin/sh', in_data=None): ''' run a command in the jail ''' if SSHJAIL_USE_JAILME: jcmd = ['jailme', self.get_jail_id()] else: jcmd = ['jexec', self.get_jail_id()] if executable: local_cmd = ' '.join([jcmd[0], jcmd[1], executable, '-c', '"%s"' % cmd]) else: local_cmd = '%s "%s" "%s"' % (jcmd[0], jcmd[1], cmd) vvv("JAIL (%s) %s" % (become_user, local_cmd), host=self.host) return self._exec_command(local_cmd, tmp_path, become_user, True, executable, in_data) def _normalize_path(self, path, prefix): if not path.startswith(os.path.sep): path = os.path.join(os.path.sep, path) normpath = os.path.normpath(path) return os.path.join(prefix, normpath[1:]) def put_file(self, in_path, out_path): ''' transfer a file from local to remote jail ''' tmp = self.get_tmp_file() self.ssh.put_file(in_path, tmp) out_path = self._normalize_path(out_path, self.get_jail_path()) code, _, stdout, stderr = self._exec_command(' '.join(['chmod 0777',tmp])) if code != 0: raise errors.AnsibleError("failed to make temp file %s world writable:\n%s\n%s" % (tmp, stdout, stderr)) code, _, stdout, stderr = self._exec_command(' '.join(['cp',tmp,out_path]), '', self.juser, True) if code != 0: raise errors.AnsibleError("failed to move file from %s to %s:\n%s\n%s" % (tmp, out_path, stdout, stderr)) def fetch_file(self, in_path, out_path): ''' fetch a file from remote jail to local ''' tmp = self.get_tmp_file() in_path = self._normalize_path(in_path, self.get_jail_path()) self._exec_command(' '.join(['mv',in_path,tmp]), '', self.juser, True) self.ssh.fetch_file(tmp, out_path) def close(self): ''' terminate the connection; nothing to do here ''' pass
class Connection(object): ''' jail-over-ssh based connections ''' def get_jail_path(self): return self.path def get_jail_id(self): return self.jid def match_jail(self): code, _, stdout, stderr = self._exec_command(' '.join( ['jls', 'name', 'jid', 'path'])) lines = stdout.strip().split('\n') lines = [line.split() for line in lines] names = dict((re.sub(r'\W', '_', name), { 'name': name.strip(), 'jid': jid.strip(), 'path': path.strip(), }) for name, jid, path in lines) if len(names) != len(lines): vvv("WARNING: This host's jail names are not unique after underscore-substitution!" ) # remove \n jail = names.get(self.jname) if jail: self.jid = jail['jid'] self.path = jail['path'] self.jname = jail['name'] vvv('Matched jail: %s' % self.jname) else: vvv('No jail found with name: %s' % self.jname) def get_tmp_file(self): code, _, stdout, stderr = self._exec_command('mktemp', '', None) return stdout.strip().split('\n')[-1] def __init__(self, runner, host, port, user, password, private_key_file, *args, **kwargs): self.host = host jaildef, self.jailhost = host.split('@', 1) self.jname = re.sub(r'\W', '_', jaildef) self.runner = runner self.has_pipelining = False self.ssh = SSHConn(runner, self.jailhost, port, user, password, private_key_file, *args) self.jid = None self.path = None self.juser = None self.matched = False def connect(self, port=None): self.ssh.connect() if not self.matched: self.match_jail() self.matched = True return self def _exec_command(self, cmd, tmp_path='', become_user=None, sudoable=False, executable='/bin/sh', in_data=None): # oh lordy I hate this approach, but we need to note what user we use to access the jail so put/fetch works if become_user != None: self.juser = become_user return self.ssh.exec_command(cmd, tmp_path, become_user, sudoable, executable, in_data) def exec_command(self, cmd, tmp_path, become_user=None, sudoable=False, executable='/bin/sh', in_data=None): ''' run a command in the jail ''' if SSHJAIL_USE_JAILME: jcmd = ['jailme', self.jid] else: jcmd = ['jexec', self.jname] if executable: local_cmd = ' '.join( [jcmd[0], jcmd[1], executable, '-c', '"%s"' % cmd]) else: local_cmd = '%s "%s" "%s"' % (jcmd[0], jcmd[1], cmd) vvv("JAIL (%s) %s" % (become_user, local_cmd), host=self.host) return self._exec_command(local_cmd, tmp_path, become_user, True, executable, in_data) def _normalize_path(self, path, prefix): if not path.startswith(os.path.sep): path = os.path.join(os.path.sep, path) normpath = os.path.normpath(path) return os.path.join(prefix, normpath[1:]) def put_file(self, in_path, out_path): ''' transfer a file from local to remote jail ''' tmp = self.get_tmp_file() self.ssh.put_file(in_path, tmp) out_path = self._normalize_path(out_path, self.get_jail_path()) code, _, stdout, stderr = self._exec_command(' '.join( ['chmod 0777', tmp])) if code != 0: raise errors.AnsibleError( "failed to make temp file %s world writable:\n%s\n%s" % (tmp, stdout, stderr)) code, _, stdout, stderr = self._exec_command( ' '.join(['cp', tmp, out_path]), '', self.juser, True) if code != 0: raise errors.AnsibleError( "failed to move file from %s to %s:\n%s\n%s" % (tmp, out_path, stdout, stderr)) def fetch_file(self, in_path, out_path): ''' fetch a file from remote jail to local ''' tmp = self.get_tmp_file() in_path = self._normalize_path(in_path, self.get_jail_path()) self._exec_command(' '.join(['mv', in_path, tmp]), '', self.juser, True) self.ssh.fetch_file(tmp, out_path) def close(self): ''' terminate the connection; nothing to do here ''' pass
class Connection(object): ''' raw socket accelerated connection ''' def __init__(self, runner, host, port, user, password, private_key_file, *args, **kwargs): self.runner = runner self.host = host self.context = None self.conn = None self.user = user self.key = utils.key_for_hostname(host) self.port = port[0] self.fbport = port[1] self.is_connected = False self.ssh = SSHConnection(runner=self.runner, host=self.host, port=self.port, user=self.user, password=password, private_key_file=private_key_file) # attempt to work around shared-memory funness if getattr(self.runner, 'aes_keys', None): utils.AES_KEYS = self.runner.aes_keys def _execute_fb_module(self): args = "password=%s port=%s" % (base64.b64encode( self.key.__str__()), str(self.fbport)) self.ssh.connect() tmp_path = self.runner._make_tmp_path(self.ssh) return self.runner._execute_module(self.ssh, tmp_path, 'accelerate', args, inject={"password": self.key}) def connect(self, allow_ssh=True): ''' activates the connection object ''' try: if not self.is_connected: # TODO: make the timeout and retries configurable? tries = 3 self.conn = socket.socket() self.conn.settimeout(300.0) while tries > 0: try: self.conn.connect((self.host, self.fbport)) break except: time.sleep(0.1) tries -= 1 if tries == 0: vvv("Could not connect via the accelerated connection, exceeded # of tries" ) raise errors.AnsibleError("Failed to connect") except: if allow_ssh: vvv("Falling back to ssh to startup accelerated mode") res = self._execute_fb_module() if not res.is_successful(): raise errors.AnsibleError( "Failed to launch the accelerated daemon on %s (reason: %s)" % (self.host, res.result.get('msg'))) return self.connect(allow_ssh=False) else: raise errors.AnsibleError("Failed to connect to %s:%s" % (self.host, self.fbport)) self.is_connected = True return self def send_data(self, data): packed_len = struct.pack('Q', len(data)) return self.conn.sendall(packed_len + data) def recv_data(self): header_len = 8 # size of a packed unsigned long long data = b"" try: while len(data) < header_len: d = self.conn.recv(1024) if not d: return None data += d data_len = struct.unpack('Q', data[:header_len])[0] data = data[header_len:] while len(data) < data_len: d = self.conn.recv(1024) if not d: return None data += d return data except socket.timeout: raise errors.AnsibleError( "timed out while waiting to receive data") def exec_command(self, cmd, tmp_path, sudo_user, sudoable=False, executable='/bin/sh'): ''' run a command on the remote host ''' if self.runner.sudo or sudoable and sudo_user: cmd, prompt = utils.make_sudo_cmd(sudo_user, executable, cmd) vvv("EXEC COMMAND %s" % cmd) data = dict( mode='command', cmd=cmd, tmp_path=tmp_path, executable=executable, ) data = utils.jsonify(data) data = utils.encrypt(self.key, data) if self.send_data(data): raise errors.AnisbleError("Failed to send command to %s" % self.host) response = self.recv_data() if not response: raise errors.AnsibleError("Failed to get a response from %s" % self.host) response = utils.decrypt(self.key, response) response = utils.parse_json(response) return (response.get('rc', None), '', response.get('stdout', ''), response.get('stderr', '')) def put_file(self, in_path, out_path): ''' transfer a file from local to remote ''' vvv("PUT %s TO %s" % (in_path, out_path), host=self.host) if not os.path.exists(in_path): raise errors.AnsibleFileNotFound( "file or module does not exist: %s" % in_path) fd = file(in_path, 'rb') fstat = os.stat(in_path) try: vvv("PUT file is %d bytes" % fstat.st_size) while fd.tell() < fstat.st_size: data = fd.read(CHUNK_SIZE) last = False if fd.tell() >= fstat.st_size: last = True data = dict(mode='put', data=base64.b64encode(data), out_path=out_path, last=last) if self.runner.sudo: data['user'] = self.runner.sudo_user data = utils.jsonify(data) data = utils.encrypt(self.key, data) if self.send_data(data): raise errors.AnsibleError("failed to send the file to %s" % self.host) response = self.recv_data() if not response: raise errors.AnsibleError( "Failed to get a response from %s" % self.host) response = utils.decrypt(self.key, response) response = utils.parse_json(response) if response.get('failed', False): raise errors.AnsibleError( "failed to put the file in the requested location") finally: fd.close() response = self.recv_data() if not response: raise errors.AnsibleError("Failed to get a response from %s" % self.host) response = utils.decrypt(self.key, response) response = utils.parse_json(response) if response.get('failed', False): raise errors.AnsibleError( "failed to put the file in the requested location") def fetch_file(self, in_path, out_path): ''' save a remote file to the specified path ''' vvv("FETCH %s TO %s" % (in_path, out_path), host=self.host) data = dict(mode='fetch', in_path=in_path) data = utils.jsonify(data) data = utils.encrypt(self.key, data) if self.send_data(data): raise errors.AnsibleError( "failed to initiate the file fetch with %s" % self.host) fh = open(out_path, "w") try: bytes = 0 while True: response = self.recv_data() if not response: raise errors.AnsibleError( "Failed to get a response from %s" % self.host) response = utils.decrypt(self.key, response) response = utils.parse_json(response) if response.get('failed', False): raise errors.AnsibleError( "Error during file fetch, aborting") out = base64.b64decode(response['data']) fh.write(out) bytes += len(out) # send an empty response back to signify we # received the last chunk without errors data = utils.jsonify(dict()) data = utils.encrypt(self.key, data) if self.send_data(data): raise errors.AnsibleError( "failed to send ack during file fetch") if response.get('last', False): break finally: # we don't currently care about this final response, # we just receive it and drop it. It may be used at some # point in the future or we may just have the put/fetch # operations not send back a final response at all response = self.recv_data() vvv("FETCH wrote %d bytes to %s" % (bytes, out_path)) fh.close() def close(self): ''' terminate the connection ''' # Be a good citizen try: self.conn.close() except: pass
class Connection(object): ''' raw socket accelerated connection ''' def __init__(self, runner, host, port, user, password, private_key_file, *args, **kwargs): self.runner = runner self.host = host self.context = None self.conn = None self.user = user self.key = utils.key_for_hostname(host) self.port = port[0] self.accport = port[1] self.is_connected = False self.has_pipelining = False self.become_methods_supported=['sudo'] if not self.port: self.port = constants.DEFAULT_REMOTE_PORT elif not isinstance(self.port, int): self.port = int(self.port) if not self.accport: self.accport = constants.ACCELERATE_PORT elif not isinstance(self.accport, int): self.accport = int(self.accport) if self.runner.original_transport == "paramiko": self.ssh = ParamikoConnection( runner=self.runner, host=self.host, port=self.port, user=self.user, password=password, private_key_file=private_key_file ) else: self.ssh = SSHConnection( runner=self.runner, host=self.host, port=self.port, user=self.user, password=password, private_key_file=private_key_file ) if not getattr(self.ssh, 'shell', None): self.ssh.shell = utils.plugins.shell_loader.get('sh') # attempt to work around shared-memory funness if getattr(self.runner, 'aes_keys', None): utils.AES_KEYS = self.runner.aes_keys def _execute_accelerate_module(self): args = "password=%s port=%s minutes=%d debug=%d ipv6=%s" % ( base64.b64encode(self.key.__str__()), str(self.accport), constants.ACCELERATE_DAEMON_TIMEOUT, int(utils.VERBOSITY), self.runner.accelerate_ipv6, ) if constants.ACCELERATE_MULTI_KEY: args += " multi_key=yes" inject = dict(password=self.key) if getattr(self.runner, 'accelerate_inventory_host', False): inject = utils.combine_vars(inject, self.runner.inventory.get_variables(self.runner.accelerate_inventory_host)) else: inject = utils.combine_vars(inject, self.runner.inventory.get_variables(self.host)) vvvv("attempting to start up the accelerate daemon...") self.ssh.connect() tmp_path = self.runner._make_tmp_path(self.ssh) return self.runner._execute_module(self.ssh, tmp_path, 'accelerate', args, inject=inject) 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 tries = 3 self.conn = socket.socket() self.conn.settimeout(constants.ACCELERATE_CONNECT_TIMEOUT) vvvv("attempting connection to %s via the accelerated port %d" % (self.host,self.accport)) while tries > 0: try: self.conn.connect((self.host,self.accport)) break except socket.error: vvvv("connection to %s failed, retrying..." % self.host) time.sleep(0.1) tries -= 1 if tries == 0: vvv("Could not connect via the accelerated connection, exceeded # of tries") raise AnsibleError("FAILED") elif wrong_user: vvv("Restarting daemon with a different remote_user") raise AnsibleError("WRONG_USER") self.conn.settimeout(constants.ACCELERATE_TIMEOUT) if not self.validate_user(): # the accelerated daemon was started with a # different remote_user. The above command # should have caused the accelerate daemon to # shutdown, so we'll reconnect. wrong_user = True except AnsibleError, e: if allow_ssh: if "WRONG_USER" in e: vvv("Switching users, waiting for the daemon on %s to shutdown completely..." % self.host) time.sleep(5) vvv("Falling back to ssh to startup accelerated mode") 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) else: raise AnsibleError("Failed to connect to %s:%s" % (self.host,self.accport)) self.is_connected = True return self