def _exec_cmd_nb(self, cmd, **kwargs):
        """Executes adb commands in a new shell, non blocking.

        Args:
            cmds: A string that is the adb command to execute.

        """
        return job.run_async(cmd, **kwargs)
Exemplo n.º 2
0
    def setup_master_ssh(self, timeout_seconds=5):
        """Sets up the master ssh connection.

        Sets up the initial master ssh connection if it has not already been
        started.

        Args:
            timeout_seconds: The time to wait for the master ssh connection to
            be made.

        Raises:
            Error: When setting up the master ssh connection fails.
        """
        with self._lock:
            if self._master_ssh_proc is not None:
                socket_path = self.socket_path
                if (not os.path.exists(socket_path)
                        or self._master_ssh_proc.poll() is not None):
                    self.log.debug('Master ssh connection to %s is down.',
                                   self._settings.hostname)
                    self._cleanup_master_ssh()

            if self._master_ssh_proc is None:
                # Create a shared socket in a temp location.
                self._master_ssh_tempdir = tempfile.mkdtemp(
                    prefix='ssh-master')

                # Setup flags and options for running the master ssh
                # -N: Do not execute a remote command.
                # ControlMaster: Spawn a master connection.
                # ControlPath: The master connection socket path.
                extra_flags = {'-N': None}
                extra_options = {
                    'ControlMaster': True,
                    'ControlPath': self.socket_path,
                    'BatchMode': True
                }

                # Construct the command and start it.
                master_cmd = self._formatter.format_ssh_local_command(
                    self._settings,
                    extra_flags=extra_flags,
                    extra_options=extra_options)
                self.log.info('Starting master ssh connection.')
                self._master_ssh_proc = job.run_async(master_cmd)

                end_time = time.time() + timeout_seconds

                while time.time() < end_time:
                    if os.path.exists(self.socket_path):
                        break
                    time.sleep(.2)
                else:
                    self._cleanup_master_ssh()
                    raise Error('Master ssh connection timed out.')
Exemplo n.º 3
0
    def create_ssh_tunnel(self, port, local_port=None):
        """Create an ssh tunnel from local_port to port.

        This securely forwards traffic from local_port on this machine to the
        remote SSH host at port.

        Args:
            port: remote port on the host.
            local_port: local forwarding port, or None to pick an available
                        port.

        Returns:
            the created tunnel process.
        """
        if local_port is None:
            local_port = host_utils.get_available_host_port()
        else:
            for tunnel in self._tunnels:
                if tunnel.remote_port == port:
                    return tunnel.local_port

        extra_flags = {
            '-n': None,  # Read from /dev/null for stdin
            '-N': None,  # Do not execute a remote command
            '-q': None,  # Suppress warnings and diagnostic commands
            '-L': '%d:localhost:%d' % (local_port, port),
        }
        extra_options = dict()
        if self._master_ssh_proc:
            extra_options['ControlPath'] = self.socket_path
        tunnel_cmd = self._formatter.format_ssh_local_command(
            self._settings,
            extra_flags=extra_flags,
            extra_options=extra_options)
        self.log.debug('Full tunnel command: %s', tunnel_cmd)
        # Exec the ssh process directly so that when we deliver signals, we
        # deliver them straight to the child process.
        tunnel_proc = job.run_async(tunnel_cmd)
        self.log.debug(
            'Started ssh tunnel, local = %d'
            ' remote = %d, pid = %d', local_port, port, tunnel_proc.pid)
        self._tunnels.append(_Tunnel(local_port, port, tunnel_proc))
        return local_port