def ZeroFreeSpace(self, feedback_fn): """Zeroes the free space on a shutdown instance. @type feedback_fn: function @param feedback_fn: Function used to log progress """ assert self.op.zeroing_timeout_fixed is not None assert self.op.zeroing_timeout_per_mib is not None zeroing_image = self.cfg.GetZeroingImage() src_node_uuid = self.instance.primary_node disk_size = self._DetermineImageSize(zeroing_image, src_node_uuid) # Calculate the sum prior to adding the temporary disk instance_disks_size_sum = self._InstanceDiskSizeSum() with TemporaryDisk(self, self.instance, disk_size, feedback_fn): feedback_fn("Activating instance disks") StartInstanceDisks(self, self.instance, False) feedback_fn("Imaging disk with zeroing image") ImageDisks(self, self.instance, zeroing_image) feedback_fn("Starting instance with zeroing image") result = self.rpc.call_instance_start(src_node_uuid, (self.instance, [], []), False, self.op.reason) result.Raise( "Could not start instance %s when using the zeroing image " "%s" % (self.instance.name, zeroing_image)) # First wait for the instance to start up running_check = lambda: IsInstanceRunning( self, self.instance, check_user_shutdown=True) instance_up = retry.SimpleRetry(True, running_check, 5.0, self.op.shutdown_timeout) if not instance_up: raise errors.OpExecError( "Could not boot instance when using the " "zeroing image %s" % zeroing_image) feedback_fn("Instance is up, now awaiting shutdown") # Then for it to be finished, detected by its shutdown timeout = self.op.zeroing_timeout_fixed + \ self.op.zeroing_timeout_per_mib * instance_disks_size_sum instance_up = retry.SimpleRetry(False, running_check, 20.0, timeout) if instance_up: self.LogWarning( "Zeroing not completed prior to timeout; instance will" "be shut down forcibly") feedback_fn("Zeroing completed!")
def Exec(self, feedback_fn): """Reinstall the instance. """ os_image = objects.GetOSImage(self.op.osparams) if os_image is not None: feedback_fn("Using OS image '%s'" % os_image) else: os_image = objects.GetOSImage(self.instance.osparams) os_type = self.op.os_type if os_type is not None: feedback_fn("Changing OS scripts to '%s'..." % os_type) self.instance.os = os_type self.cfg.Update(self.instance, feedback_fn) else: os_type = self.instance.os if not os_image and not os_type: self.LogInfo("No OS scripts or OS image specified or found in the" " instance's configuration, nothing to install") else: if self.op.osparams is not None: self.instance.osparams = self.op.osparams if self.op.osparams_private is not None: self.instance.osparams_private = self.op.osparams_private self.cfg.Update(self.instance, feedback_fn) StartInstanceDisks(self, self.instance, None) self.instance = self.cfg.GetInstanceInfo(self.instance.uuid) try: if os_image: ImageDisks(self, self.instance, os_image) if os_type: self._ReinstallOSScripts(self.instance, self.osparams, self.op.debug_level) UpdateMetadata(feedback_fn, self.rpc, self.instance, osparams_public=self.osparams, osparams_private=self.osparams_private, osparams_secret=self.osparams_secret) finally: ShutdownInstanceDisks(self, self.instance)
raise errors.OpExecError( "Could not create temporary disk for zeroing:" " %s", err) # Calculate the sum prior to adding the temporary disk instance_disks_size_sum = self._InstanceDiskSizeSum() with TemporaryDisk( self, self.instance, [(constants.DT_PLAIN, constants.DISK_RDWR, disk_size)], feedback_fn): feedback_fn("Activating instance disks") StartInstanceDisks(self, self.instance, False) feedback_fn("Imaging disk with zeroing image") ImageDisks(self, self.instance, zeroing_image) feedback_fn("Starting instance with zeroing image") result = self.rpc.call_instance_start(src_node_uuid, (self.instance, [], []), False, self.op.reason) result.Raise( "Could not start instance %s when using the zeroing image " "%s" % (self.instance.name, zeroing_image)) # First wait for the instance to start up running_check = lambda: IsInstanceRunning( self, self.instance, prereq=False) instance_up = retry.SimpleRetry(True, running_check, 5.0, self.op.shutdown_timeout) if not instance_up:
else: log_feedback = lambda _: None try: disk_size = DetermineImageSize(lu, vm_image, instance.primary_node) except errors.OpExecError, err: raise errors.OpExecError("Could not create temporary disk: %s", err) with TemporaryDisk(lu, instance, [(constants.DT_PLAIN, constants.DISK_RDWR, disk_size)], log_feedback): log_feedback("Activating helper VM's temporary disks") StartInstanceDisks(lu, instance, False) log_feedback("Imaging temporary disks with image %s" % (vm_image, )) ImageDisks(lu, instance, vm_image) log_feedback("Starting helper VM") result = lu.rpc.call_instance_start(instance.primary_node, (instance, [], []), False, lu.op.reason) result.Raise( add_prefix("Could not start helper VM with image %s" % (vm_image, ))) # First wait for the instance to start up running_check = lambda: IsInstanceRunning(lu, instance, prereq=False) instance_up = retry.SimpleRetry(True, running_check, 5.0, startup_timeout) if not instance_up: raise errors.OpExecError(
def HelperVM(lu, instance, vm_image, startup_timeout, vm_timeout, log_prefix=None, feedback_fn=None): """Runs a given helper VM for a given instance. @type lu: L{LogicalUnit} @param lu: the lu on whose behalf we execute @type instance: L{objects.Instance} @param instance: the instance definition @type vm_image: string @param vm_image: the name of the helper VM image to dump on a temporary disk @type startup_timeout: int @param startup_timeout: how long to wait for the helper VM to start up @type vm_timeout: int @param vm_timeout: how long to wait for the helper VM to finish its work @type log_prefix: string @param log_prefix: a prefix for all log messages @type feedback_fn: function @param feedback_fn: Function used to log progress """ if log_prefix: add_prefix = lambda msg: "%s: %s" % (log_prefix, msg) else: add_prefix = lambda msg: msg if feedback_fn is not None: log_feedback = lambda msg: feedback_fn(add_prefix(msg)) else: log_feedback = lambda _: None try: disk_size = DetermineImageSize(lu, vm_image, instance.primary_node) except errors.OpExecError as err: raise errors.OpExecError("Could not create temporary disk: %s", err) with TemporaryDisk(lu, instance, [(constants.DT_PLAIN, constants.DISK_RDWR, disk_size)], log_feedback): log_feedback("Activating helper VM's temporary disks") StartInstanceDisks(lu, instance, False) log_feedback("Imaging temporary disks with image %s" % (vm_image, )) ImageDisks(lu, instance, vm_image) log_feedback("Starting helper VM") result = lu.rpc.call_instance_start(instance.primary_node, (instance, [], []), False, lu.op.reason) result.Raise( add_prefix("Could not start helper VM with image %s" % (vm_image, ))) # First wait for the instance to start up running_check = lambda: IsInstanceRunning(lu, instance, prereq=False) instance_up = retry.SimpleRetry(True, running_check, 5.0, startup_timeout) if not instance_up: raise errors.OpExecError( add_prefix("Could not boot instance using" " image %s" % (vm_image, ))) log_feedback("Helper VM is up") def cleanup(): log_feedback("Waiting for helper VM to finish") # Then for it to be finished, detected by its shutdown instance_up = retry.SimpleRetry(False, running_check, 20.0, vm_timeout) if instance_up: lu.LogWarning( add_prefix("Helper VM has not finished within the" " timeout; shutting it down forcibly")) return \ lu.rpc.call_instance_shutdown(instance.primary_node, instance, constants.DEFAULT_SHUTDOWN_TIMEOUT, lu.op.reason) else: return None # Run the inner block and handle possible errors try: yield except Exception: # if the cleanup failed for some reason, log it and just re-raise result = cleanup() if result: result.Warn( add_prefix("Could not shut down helper VM with image" " %s within timeout" % (vm_image, ))) log_feedback("Error running helper VM with image %s" % (vm_image, )) raise else: result = cleanup() # if the cleanup failed for some reason, throw an exception if result: result.Raise( add_prefix("Could not shut down helper VM with image %s" " within timeout" % (vm_image, ))) raise errors.OpExecError( "Error running helper VM with image %s" % (vm_image, )) log_feedback("Helper VM execution completed")