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): ''' 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: 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