Exemplo n.º 1
0
    def is_pingable(self):
        """Attempts to ping the access point.

        Returns:
            True if ping is successful, else False
        """
        return utils.is_pingable(self.ssh_settings.hostname)
def create_ssh_connection(ip_address,
                          ssh_username,
                          ssh_config,
                          connect_timeout=10,
                          auth_timeout=10,
                          banner_timeout=10):
    """Creates and ssh connection to a Fuchsia device

    Args:
        ip_address: IP address of ssh server.
        ssh_username: Username for ssh server.
        ssh_config: ssh_config location for the ssh server.
        connect_timeout: Timeout value for connecting to ssh_server.
        auth_timeout: Timeout value to wait for authentication.
        banner_timeout: Timeout to wait for ssh banner.

    Returns:
        A paramiko ssh object
    """
    if not utils.is_pingable(ip_address):
        raise DeviceOffline("Device %s is not reachable via "
                            "the network." % ip_address)
    ssh_key = get_private_key(ip_address=ip_address, ssh_config=ssh_config)
    ssh_client = paramiko.SSHClient()
    ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh_client.connect(hostname=ip_address,
                       username=ssh_username,
                       allow_agent=False,
                       pkey=ssh_key,
                       timeout=connect_timeout,
                       auth_timeout=auth_timeout,
                       banner_timeout=banner_timeout)
    ssh_client.get_transport().set_keepalive(1)
    return ssh_client
Exemplo n.º 3
0
    def send_command(self, test_id, test_cmd, test_args, response_timeout=30):
        """Builds and sends a JSON command to SL4F server.

        Args:
            test_id: string, unique identifier of test command.
            test_cmd: string, sl4f method name of command.
            test_args: dictionary, arguments required to execute test_cmd.
            response_timeout: int, seconds to wait for a response before
                throwing an exception. Defaults to no timeout.

        Returns:
            Dictionary, Result of sl4f command executed.
        """
        if not utils.is_pingable(urlparse(self.address).hostname):
            raise DeviceOffline("FuchsiaDevice %s is not reachable via the "
                                "network." % urlparse(self.address).hostname)
        test_data = json.dumps({
            "jsonrpc": "2.0",
            "id": test_id,
            "method": test_cmd,
            "params": test_args
        })
        try:
            return requests.get(url=self.address,
                                data=test_data,
                                timeout=response_timeout).json()
        except requests.exceptions.Timeout as e:
            if not utils.is_pingable(urlparse(self.address).hostname):
                raise DeviceOffline(
                    "FuchsiaDevice %s is not reachable via the "
                    "network." % urlparse(self.address).hostname)
            else:
                logging.debug(
                    'FuchsiaDevice %s is online but SL4f call timed out.' %
                    urlparse(self.address).hostname)
                raise e
    def verify_ping(self, timeout=30):
        """Verify the fuchsia device can be pinged.

        Args:
            timeout: int, seconds to retry before raising an exception

        Raise:
            ConnecitonError, if device still can't be pinged after timeout.
        """
        end_time = time.time() + timeout
        while time.time() < end_time:
            if utils.is_pingable(self.ip):
                break
            else:
                self.log.debug('Device is not pingable. Retrying in 1 second.')
                time.sleep(1)
        else:
            raise ConnectionError('Device never came back online.')
    def reboot(self,
               use_ssh=False,
               unreachable_timeout=30,
               ping_timeout=30,
               ssh_timeout=30,
               reboot_type=FUCHSIA_REBOOT_TYPE_SOFT,
               testbed_pdus=None):
        """Reboot a FuchsiaDevice.

        Soft reboots the device, verifies it becomes unreachable, then verfifies
        it comes back online. Reinitializes SL4F so the tests can continue.

        Args:
            use_ssh: bool, if True, use fuchsia shell command via ssh to reboot
                instead of SL4F.
            unreachable_timeout: int, time to wait for device to become
                unreachable.
            ping_timeout: int, time to wait for device to respond to pings.
            ssh_timeout: int, time to wait for device to be reachable via ssh.
            reboot_type: boolFUCHSIA_REBOOT_TYPE_SOFT or
                FUCHSIA_REBOOT_TYPE_HARD
            testbed_pdus: list, all testbed PDUs

        Raises:
            ConnectionError, if device fails to become unreachable, fails to
                come back up, or if SL4F does not setup correctly.
        """
        # Call Reboot
        if reboot_type == FUCHSIA_REBOOT_TYPE_SOFT:
            if use_ssh:
                self.log.info('Sending reboot command via SSH.')
                with utils.SuppressLogOutput():
                    self.clean_up()
                    self.send_command_ssh(
                        'dm reboot',
                        timeout=FUCHSIA_RECONNECT_AFTER_REBOOT_TIME,
                        skip_status_code_check=True)
            else:
                self.log.info('Initializing reboot of FuchsiaDevice (%s)'
                              ' with SL4F.' % self.ip)
                self.log.info('Calling SL4F reboot command.')
                with utils.SuppressLogOutput():
                    if self.log_process:
                        self.log_process.stop()
                    self.hardware_power_statecontrol_lib.suspendReboot(
                        timeout=3)
                    if self._persistent_ssh_conn:
                        self._persistent_ssh_conn.close()
                        self._persistent_ssh_conn = None
        elif reboot_type == FUCHSIA_REBOOT_TYPE_HARD:
            self.log.info('Power cycling FuchsiaDevice (%s)' % self.ip)
            device_pdu, device_pdu_port = pdu.get_pdu_port_for_device(
                self.device_pdu_config, testbed_pdus)
            with utils.SuppressLogOutput():
                if self.log_process:
                    self.log_process.stop()
                if self._persistent_ssh_conn:
                    self._persistent_ssh_conn.close()
                    self._persistent_ssh_conn = None
            self.log.info('Killing power to FuchsiaDevice (%s)...' % self.ip)
            device_pdu.off(str(device_pdu_port))

        # Wait for unreachable
        self.log.info('Verifying device is unreachable.')
        timeout = time.time() + unreachable_timeout
        while (time.time() < timeout):
            if utils.is_pingable(self.ip):
                self.log.debug('Device is still pingable. Retrying.')
            else:
                if reboot_type == FUCHSIA_REBOOT_TYPE_HARD:
                    self.log.info('Restoring power to FuchsiaDevice (%s)...' %
                                  self.ip)
                    device_pdu.on(str(device_pdu_port))
                break
        else:
            self.log.info('Device failed to go offline. Reintializing Sl4F.')
            self.start_services()
            self.init_server_connection()
            raise ConnectionError('Device never went down.')
        self.log.info('Device is unreachable as expected.')

        if reboot_type == FUCHSIA_REBOOT_TYPE_HARD:
            self.log.info('Restoring power to FuchsiaDevice (%s)...' % self.ip)
            device_pdu.on(str(device_pdu_port))

        self.log.info('Waiting for device to respond to pings.')
        self.verify_ping(timeout=ping_timeout)
        self.log.info('Device responded to pings.')

        self.log.info('Waiting for device to allow ssh connection.')
        self.verify_ssh(timeout=ssh_timeout)
        self.log.info('Device now available via ssh.')

        # Creating new log process, start it, start new persistent ssh session,
        # start SL4F, and connect via SL4F
        self.log.info(
            'Restarting log process and reinitiating SL4F on FuchsiaDevice %s'
            % self.ip)
        self.log_process.start()
        self.start_services()

        # Verify SL4F is up.
        self.log.info(
            'Initiating connection to SL4F and verifying commands can run.')
        try:
            self.init_server_connection()
            self.hwinfo_lib.getDeviceInfo()
        except Exception as err:
            raise ConnectionError(
                'Failed to connect and run command via SL4F. Err: %s' % err)
        self.log.info(
            'Device has rebooted, SL4F is reconnected and functional.')