def _verify_reboot(self, disconnect_timeout=None, bootup_timeout=None): """Verifies the device reboots correctly. Ensures the device goes offline, comes back online, and finishes booting up. Args: disconnect_timeout (int): max time to wait for device to go offline & come back online. bootup_timeout (int): max time to wait for device to finish booting up. Raises: DeviceNotBootupCompleteError: device failed to boot up. """ disconnect_timeout = disconnect_timeout or self.timeouts["DISCONNECT"] bootup_timeout = bootup_timeout or self.timeouts["BOOT_UP"] start_time = time.time() max_disconnect_time = start_time + disconnect_timeout last_ping = True while time.time() < max_disconnect_time: ping = host_utils.is_pingable(self.ip_address) if not ping and not last_ping: logger.info("{} offline in {}s.".format(self.name, int(time.time() - start_time))) break time.sleep(.5) last_ping = ping else: raise errors.DeviceNotBootupCompleteError( self.name, "failed to go offline in {}s".format(disconnect_timeout)) # close ssh transport as the ssh connection is disconnected. self.switchboard.close_all_transports() time.sleep(5) # wait for a bit start_time = time.time() while time.time() < max_disconnect_time: if host_utils.is_pingable(self.ip_address): logger.info("{} online in {}s".format(self.name, int(time.time() - start_time))) break time.sleep(.5) else: raise errors.DeviceNotBootupCompleteError( self.name, "failed to come online {}s".format(int(time.time() - start_time))) # There's a delay between the device being responsive to ping # and being able to open SSH connections time.sleep(self.timeouts["PING_TO_SSH_DELAY"]) # Reopen ssh transport as ssh connection is once more available. self.switchboard.open_all_transports() self.wait_for_bootup_complete(timeout=bootup_timeout) logger.info("{} booted up successfully in {}s.".format( self.name, int(time.time() - start_time))) self._after_boot_hook()
def _ensure_device_goes_offline(self, timeout=None): """Ensure device is no longer pingable over ssh. Args: timeout (float): Time in seconds to wait for device to respond. Raises: DeviceError: Device failed to go offline before the timeout """ timeout = timeout or self.timeouts["SHUTDOWN"] start_time = time.time() max_disconnect_time = start_time + timeout count = 0 while time.time() < max_disconnect_time: if not host_utils.is_pingable(self.ip_address): count += 1 # Ensure device is really offline not just a blip else: count = 0 if count == 2: logger.info("{} offline in {}s.".format(self.name, int(time.time() - start_time))) # close ssh transport as the ssh connection is disconnected. self.switchboard.close_all_transports() time.sleep(5) # to ensure offline return time.sleep(.5) raise errors.DeviceError("Failed to go offline within {}s.".format(timeout))
def is_connected(cls, device_config): """Checks whether or not the device is connected to the computer. Args: device_config (dict): contains "persistent" dict Returns: bool: True if device is pingable, False otherwise. """ ip_address = device_config["persistent"]["console_port_name"] return host_utils.is_pingable(ip_address)
def is_connected(cls, device_config): """Checks whether or not the DLI Power Switch is connected. Args: device_config (dict): contains "persistent" dict Returns: bool: whether the device responds to a ping. """ return host_utils.is_pingable( device_config["persistent"]["console_port_name"])
def _ensure_device_is_online(self, timeout=None): """Ensure device is online and configs are fully loaded. Args: timeout(float): Time in seconds to wait for device to respond. Raises: DeviceError: Device failed to come online before the timeout. """ timeout = timeout or self.timeouts["ONLINE"] start_time = time.time() max_disconnect_time = start_time + timeout while time.time() < max_disconnect_time: if host_utils.is_pingable(self.ip_address): # There's a delay between the device being responsive to ping # and being able to open SSH connections time.sleep(10) self.switchboard.open_all_transports() break time.sleep(.5) else: raise errors.DeviceError("{} failed to become pingable in {}s.".format( self.name, timeout)) output = "Device still offline" while time.time() < max_disconnect_time: # Ensure the BOOTUP_COMPLETE command is only sent once boot_up_complete_timeout = max_disconnect_time - time.time() try: output, return_code = self.shell( self.commands["BOOTUP_COMPLETE"], timeout=boot_up_complete_timeout, include_return_code=True) if return_code == 0: # command executed logger.info("{} online in {}s".format(self.name, int(time.time() - start_time))) return self.shell(self.commands["RESET_FAILED"]) except errors.DeviceError: logger.debug( "{} failed to respond to {!r}.".format( self.name, self.commands["BOOTUP_COMPLETE"]), exc_info=True) time.sleep(.5) raise errors.DeviceError( "Failed to come online and respond to {!r} in {}s. Response: {}".format( self.commands["BOOTUP_COMPLETE"], timeout, output))
def _check_ip_address_valid(self, ip_address): """Checks that the IP address of the device is valid (non-empty and pingable). Args: ip_address (str): IP address of the device. Raises: DeviceError: device has no IP address, or the IP address is not pingable. """ if not ip_address: raise errors.DeviceError( f"{self._device_name} does not have an IPv4 address. " "An IPv4 address is required for file transfer functionality.") if not host_utils.is_pingable(ip_address): raise errors.DeviceError("{}'s IP address {} is not pingable.".format( self._device_name, ip_address))
def _is_ready_to_open(self): return host_utils.is_pingable(self.comms_address)