Пример #1
0
    def _ssh_connect(self):
        """Connect via SSH."""
        if self._ssh_client:
            return self._ssh_client

        if not self.ssh_ip or not self.ssh_port:
            raise ValueError

        client = paramiko.SSHClient()
        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        private_key = paramiko.RSAKey.from_private_key_file(self.ssh_key_file)

        retries = 30
        while retries:
            try:
                client.connect(username=self.ssh_username,
                               hostname=self.ssh_ip, port=self.ssh_port,
                               pkey=private_key, banner_timeout=30)
                self._ssh_client = client
                return client
            except (ConnectionRefusedError, AuthenticationException,
                    BadHostKeyException, ConnectionResetError, SSHException,
                    OSError) as e:
                retries -= 1
                time.sleep(10)

        ssh_cmd = 'Failed ssh connection to %s@%s:%s after 300 seconds' % (
            self.ssh_username, self.ssh_ip, self.ssh_port
        )
        raise util.InTargetExecuteError(b'', b'', 1, ssh_cmd, 'ssh')
Пример #2
0
    def _ssh_connect(self,
                     hostname='localhost',
                     username='******',
                     banner_timeout=120,
                     retry_attempts=30):
        """Connect via SSH."""
        if self._ssh_client:
            return self._ssh_client

        private_key = paramiko.RSAKey.from_private_key_file(self.ssh_key_file)
        client = paramiko.SSHClient()
        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        while retry_attempts:
            try:
                client.connect(hostname=hostname,
                               username=username,
                               port=self.ssh_port,
                               pkey=private_key,
                               banner_timeout=banner_timeout)
                self._ssh_client = client
                return client
            except (paramiko.SSHException, TypeError):
                time.sleep(1)
                retry_attempts = retry_attempts - 1

        error_desc = 'Failed command to: %s@%s:%s' % (username, hostname,
                                                      self.ssh_port)
        raise util.InTargetExecuteError('', '', -1, 'ssh connect', self.name,
                                        error_desc)
Пример #3
0
    def execute(self,
                command,
                stdout=None,
                stderr=None,
                env=None,
                rcs=None,
                description=None):
        """Execute command in instance, recording output, error and exit code.

        Assumes functional networking and execution as root with the
        target filesystem being available at /.

        @param command: the command to execute as root inside the image
            if command is a string, then it will be executed as:
            ['sh', '-c', command]
        @param stdout: file handler to write output
        @param stderr: file handler to write error
        @param env: environment variables
        @param rcs: allowed return codes from command
        @param description: purpose of command
        @return_value: tuple containing stdout data, stderr data, exit code
        """
        if env is None:
            env = {}

        if isinstance(command, str):
            command = ['sh', '-c', command]

        # ensure instance is running and execute the command
        self.start()
        res = self.pylxd_container.execute(command, environment=env)

        # get out, exit and err from pylxd return
        if hasattr(res, 'exit_code'):
            # pylxd 2.2 returns ContainerExecuteResult, named tuple of
            # (exit_code, out, err)
            (exit, out, err) = res
        else:
            # pylxd 2.1.3 and earlier only return out and err, no exit
            # LOG.warning('using pylxd version < 2.2')
            (out, err) = res
            exit = 0

        # write data to file descriptors if needed
        if stdout:
            stdout.write(out)
        if stderr:
            stderr.write(err)

        # if the command exited with a code not allowed in rcs, then fail
        if exit not in (rcs if rcs else (0, )):
            error_desc = ('Failed command to: {}'.format(description)
                          if description else None)
            raise util.InTargetExecuteError(out, err, exit, command, self.name,
                                            error_desc)

        return (out, err, exit)
Пример #4
0
    def ssh(self, command):
        """Run a command via SSH."""
        client = self._ssh_connect()

        try:
            _, out, err = client.exec_command(util.shell_pack(command))
        except paramiko.SSHException:
            raise util.InTargetExecuteError('', '', -1, command, self.name)

        exit = out.channel.recv_exit_status()
        out = ''.join(out.readlines())
        err = ''.join(err.readlines())
        client.close()

        return out, err, exit
Пример #5
0
    def ssh(self, command, stdin=None):
        """Run a command via SSH."""
        client = self._ssh_connect()

        cmd = util.shell_pack(command)
        try:
            fp_in, fp_out, fp_err = client.exec_command(cmd)
            channel = fp_in.channel
            if stdin is not None:
                fp_in.write(stdin)
                fp_in.close()

            channel.shutdown_write()
            rc = channel.recv_exit_status()
            return (fp_out.read(), fp_err.read(), rc)
        except paramiko.SSHException as e:
            raise util.InTargetExecuteError(b'',
                                            b'',
                                            -1,
                                            command,
                                            self.name,
                                            reason=e)
Пример #6
0
    def _ssh_connect(self):
        """Connect via SSH.

        Attempt to SSH to the client on the specific IP and port. If it
        fails in some manner, then retry 2 more times for a total of 3
        attempts; sleeping a few seconds between attempts.
        """
        if self._ssh_client:
            return self._ssh_client

        if not self.ssh_ip or not self.ssh_port:
            raise ValueError("Cannot ssh_connect, ssh_ip=%s ssh_port=%s" %
                             (self.ssh_ip, self.ssh_port))

        client = paramiko.SSHClient()
        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        private_key = paramiko.RSAKey.from_private_key_file(self.ssh_key_file)

        retries = 3
        while retries:
            try:
                client.connect(username=self.ssh_username,
                               hostname=self.ssh_ip,
                               port=self.ssh_port,
                               pkey=private_key)
                self._ssh_client = client
                return client
            except (ConnectionRefusedError, AuthenticationException,
                    BadHostKeyException, ConnectionResetError, SSHException,
                    OSError):
                retries -= 1
                LOG.debug('Retrying ssh connection on connect failure')
                time.sleep(3)

        ssh_cmd = 'Failed ssh connection to %s@%s:%s after 3 retries' % (
            self.ssh_username, self.ssh_ip, self.ssh_port)
        raise util.InTargetExecuteError(b'', b'', 1, ssh_cmd, 'ssh')