Пример #1
0
    def wait_for_post_boot(self, pre_server):
        """
        Wait for the post-boot environment to come online.

        :param pre_server: A :class:`ServerDetails` object created by :func:`wait_for_pre_boot()`.
        """
        method_timer = Timer()
        check_keys = bool(pre_server.host_keys)
        check_headers = (
            self.pre_boot.port_number == self.post_boot.port_number)
        logger.info(
            "Waiting for post-boot environment based on SSH %s ..",
            "host keys" if check_keys else
            ("server headers" if check_headers else "port numbers"))
        with AutomaticSpinner("Waiting for post-boot environment",
                              show_time=True):
            while True:
                iteration_timer = Timer()
                if check_headers or check_keys:
                    post_server = self.scan_ssh_server(self.post_boot)
                    if check_keys and post_server.host_keys:
                        logger.verbose(
                            "Checking if SSH host keys have changed ..")
                        if post_server.host_keys != pre_server.host_keys:
                            logger.info("Detected change in SSH host keys.")
                            self.store_host_keys(pre_server, post_server)
                            break
                    if check_headers and pre_server.header and post_server.header:
                        logger.verbose(
                            "Checking if SSH server header has changed ..")
                        if post_server.header != pre_server.header:
                            logger.info(
                                "Detected change in SSH server header.")
                            break
                elif self.test_ssh_connection(self.post_boot,
                                              self.post_context):
                    logger.info("Detected change in SSH port number.")
                    break
                if method_timer.elapsed_time >= self.boot_timeout:
                    raise BootTimeoutError(
                        format(
                            "Timed out waiting for post-boot environment of %s to come online within %s!",
                            self.post_context,
                            format_timespan(self.boot_timeout),
                        ))
                iteration_timer.sleep(self.retry_interval)
        logger.info("Waited %s for post-boot environment.", method_timer)
Пример #2
0
    def wait_for_pre_boot(self):
        """
        Wait for the pre-boot environment to become available.

        :returns: A :class:`ServerDetails` object.
        :raises: The following exceptions can be raised:

                 - :exc:`SystemUnreachableError` when :attr:`connect_timeout`
                   seconds have passed and we still haven't managed to query
                   the SSH server in the pre-boot environment.
                 - :exc:`UnlockAbortedError` when the post-boot environment is
                   detected and the operator aborts the unlock sequence.
        """
        method_timer = Timer()
        logger.info("Waiting for pre-boot environment to become available ..")
        with AutomaticSpinner("Waiting for pre-boot environment",
                              show_time=True):
            while True:
                iteration_timer = Timer()
                server = self.scan_ssh_server(self.pre_boot)
                known_keys = self.get_known_host_keys('pre-boot-host-keys')
                if server.host_keys and known_keys:
                    logger.verbose(
                        "Checking if SSH host keys match known keys ..")
                    if server.host_keys & known_keys:
                        logger.info(
                            "Matched known SSH host keys of pre-boot environment."
                        )
                        break
                    else:
                        logger.warning(
                            compact("""
                            Detected post-boot environment while waiting for
                            pre-boot environment to become available, will keep
                            retrying...
                        """))
                elif server.match_header('dropbear'):
                    logger.info(
                        "Detected Dropbear in pre-boot environment (as expected)."
                    )
                    break
                elif server.match_header('openssh'):
                    logger.warning(
                        compact("""
                        Detected OpenSSH server while connecting to pre-boot
                        environment where I was expecting Dropbear instead!
                        Could it be that you're accidentally connecting
                        to the post-boot environment?
                    """))
                    if self.interactive:
                        if prompt_for_confirmation(
                                "Continue connecting anyway?"):
                            logger.info(
                                "Continuing unlock sequence with operator consent .."
                            )
                        else:
                            raise UnlockAbortedError(
                                "Unlock sequence aborted by operator.")
                    break
                if method_timer.elapsed_time >= self.connect_timeout:
                    raise SystemUnreachableError(
                        format(
                            "Timed out waiting for pre-boot environment of %s to become available within %s!",
                            self.pre_context,
                            format_timespan(self.connect_timeout),
                        ))
                iteration_timer.sleep(self.retry_interval)
        logger.info("Waited %s for pre-boot environment.", method_timer)
        return server