def install_os(self, image_name, controller="both", save_config=True, **vendor_specifics): """ Install an operating system on the controller. Args: image_name (str): The version to install on the device. controller (str): The controller(s) to reboot for install (only applies to HA device). save_config (bool): Whether the config should be saved to the device before reboot. Returns: bool: True when the install is successful, False when the version is deemed to already be running. Raises: OSInstallError: When the device is not booted with the specified image after reload. RebootTimeoutError: When the device is unreachable longer than the reboot timeout value. Example: >>> device = AIREOSDevice(**connection_args) >>> device.boot_options { 'backup': '8.8.125.0', 'primary': '8.9.100.0', 'sys': '8.9.100.0' } >>> device.file_copy("user", "password", "10.1.1.1", "/images/aireos/AIR-CT5500-K9-8-10-105-0.aes") >>> device.boot_options { 'backup': '8.9.100.0', 'primary': '8.10.105.0', 'sys': '8.10.105.0' } >>> device.install_os("8.10.105.0") >>> """ timeout = vendor_specifics.get("timeout", 3600) if not self._image_booted(image_name): peer_redundancy = self.peer_redundancy_state self.set_boot_options(image_name, **vendor_specifics) self.reboot(confirm=True, controller=controller, save_config=save_config) self._wait_for_device_reboot(timeout=timeout) if not self._image_booted(image_name): raise OSInstallError(hostname=self.host, desired_boot=image_name) if not self.peer_redundancy_state == peer_redundancy: raise OSInstallError(hostname=f"{self.host}-standby", desired_boot=image_name) return True return False
def install_os(self, image_name, **vendor_specifics): """ Install OS on device. Args: image_name (str): Name of the image to be installed. Raises: OSInstallError: Message stating the end device could not boot into the new image. Returns: bool: True if new image is installed correctly. False if device is already running image_name. """ timeout = vendor_specifics.get("timeout", 3600) if not self._image_booted(image_name): self.set_boot_options(image_name, **vendor_specifics) self.reboot() self._wait_for_device_reboot(timeout=timeout) if not self._image_booted(image_name): raise OSInstallError(hostname=self.facts.get("hostname"), desired_boot=image_name) return True return False
def _wait_for_image_installed(self, image_name, volume, timeout=1800): """Waits for the device to install image on a volume Args: image_name (str): The name of the image that should be booting. volume (str): The volume that the device should be booting into. timeout (int): The number of seconds to wait for device to boot up. Raises: OSInstallError: When the volume is not booted before the timeout is reached. """ end_time = time.time() + timeout while time.time() < end_time: time.sleep(20) # Avoid race-conditions issues. Newly created volumes _might_ lack # of .version attribute in first seconds of their live. try: if self.image_installed(image_name=image_name, volume=volume): return except: pass raise OSInstallError(hostname=self.facts.get("hostname"), desired_boot=volume)
def install_os(self, image_name, install_mode=False, install_mode_delay_factor=10, **vendor_specifics): """Installs the prescribed Network OS, which must be present before issuing this command. Args: image_name (str): Name of the IOS image to boot into install_mode (bool, optional): Uses newer install method on devices. Defaults to False. Raises: OSInstallError: Unable to install OS Error type Returns: bool: False if no install is needed, true if the install completes successfully """ timeout = vendor_specifics.get("timeout", 3600) if not self._image_booted(image_name): if install_mode: # Change boot statement to be boot system <flash>:packages.conf self.set_boot_options(INSTALL_MODE_FILE_NAME, **vendor_specifics) # Check for OS Version specific upgrade path # https://www.cisco.com/c/en/us/td/docs/switches/lan/catalyst9300/software/release/17-2/release_notes/ol-17-2-9300.html os_version = self.os_version if "16.5.1a" in os_version or "16.6.1" in os_version: # Run install command and reboot device command = f"request platform software package install switch all file {self._get_file_system()}{image_name} auto-copy" self.show(command, delay_factor=install_mode_delay_factor) self.reboot(confirm=True) else: # Run install command (which reboots the device) command = ( f"install add file {self._get_file_system()}{image_name} activate commit prompt-level none" ) # Set a higher delay factor and send it in try: self.show(command, delay_factor=install_mode_delay_factor) except IOError: pass else: self.set_boot_options(image_name, **vendor_specifics) self.reboot(confirm=True) # Wait for the reboot to finish self._wait_for_device_reboot(timeout=timeout) # Verify the OS level if not self._image_booted(image_name): raise OSInstallError(hostname=self.hostname, desired_boot=image_name) return True return False
def install_os(self, image_name, **vendor_specifics): timeout = vendor_specifics.get("timeout", 3600) if not self._image_booted(image_name): self.set_boot_options(image_name, **vendor_specifics) self.reboot(confirm=True) self._wait_for_device_reboot(timeout=timeout) if not self._image_booted(image_name): raise OSInstallError(hostname=self.facts.get("hostname"), desired_boot=image_name) return True return False
def _wait_for_image_installed(self, image_name, volume, timeout=900): """Waits for the device to install image on a volume Args: image_name (str): The name of the image that should be booting. volume (str): The volume that the device should be booting into. timeout (int): The number of seconds to wait for device to boot up. Raises: OSInstallError: When the volume is not booted before the timeout is reached. """ end_time = time.time() + timeout while time.time() < end_time: time.sleep(20) if self.image_installed(image_name=image_name, volume=volume): return raise OSInstallError(hostname=self.facts.get("hostname"), desired_boot=volume)