def Exec(self, feedback_fn): """Remove the instance. """ assert (self.owned_locks(locking.LEVEL_NODE) == self.owned_locks( locking.LEVEL_NODE_RES)) assert not (set(self.cfg.GetInstanceNodes(self.instance.uuid)) - self.owned_locks(locking.LEVEL_NODE)), \ "Not owning correct locks" if not self.instance.forthcoming: logging.info("Shutting down instance %s on node %s", self.instance.name, self.cfg.GetNodeName(self.instance.primary_node)) result = self.rpc.call_instance_shutdown( self.instance.primary_node, self.instance, self.op.shutdown_timeout, self.op.reason) if self.op.ignore_failures: result.Warn("Warning: can't shutdown instance", feedback_fn) else: result.Raise( "Could not shutdown instance %s on node %s" % (self.instance.name, self.cfg.GetNodeName(self.instance.primary_node))) else: logging.info( "Instance %s on node %s is forthcoming; not shutting down", self.instance.name, self.cfg.GetNodeName(self.instance.primary_node)) RemoveInstance(self, feedback_fn, self.instance, self.op.ignore_failures)
def Exec(self, feedback_fn): """Export an instance to an image in the cluster. """ assert self.op.mode in constants.EXPORT_MODES src_node_uuid = self.instance.primary_node if self.op.shutdown: # shutdown the instance, but not the disks feedback_fn("Shutting down instance %s" % self.instance.name) result = self.rpc.call_instance_shutdown(src_node_uuid, self.instance, self.op.shutdown_timeout, self.op.reason) # TODO: Maybe ignore failures if ignore_remove_failures is set result.Raise( "Could not shutdown instance %s on" " node %s" % (self.instance.name, self.cfg.GetNodeName(src_node_uuid))) if self.op.zero_free_space: self.ZeroFreeSpace(feedback_fn) activate_disks = not self.instance.disks_active if activate_disks: # Activate the instance disks if we're exporting a stopped instance feedback_fn("Activating disks for %s" % self.instance.name) StartInstanceDisks(self, self.instance, None) self.instance = self.cfg.GetInstanceInfo(self.instance.uuid) try: helper = masterd.instance.ExportInstanceHelper( self, feedback_fn, self.instance) helper.CreateSnapshots() try: if (self.op.shutdown and self.instance.admin_state == constants.ADMINST_UP and not self.op.remove_instance): assert self.instance.disks_active feedback_fn("Starting instance %s" % self.instance.name) result = self.rpc.call_instance_start( src_node_uuid, (self.instance, None, None), False, self.op.reason) msg = result.fail_msg if msg: feedback_fn("Failed to start instance: %s" % msg) ShutdownInstanceDisks(self, self.instance) raise errors.OpExecError( "Could not start instance: %s" % msg) if self.op.mode == constants.EXPORT_MODE_LOCAL: (fin_resu, dresults) = helper.LocalExport(self.dst_node, self.op.compress) elif self.op.mode == constants.EXPORT_MODE_REMOTE: connect_timeout = constants.RIE_CONNECT_TIMEOUT timeouts = masterd.instance.ImportExportTimeouts( connect_timeout) (key_name, _, _) = self.x509_key_name dest_ca_pem = \ OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, self.dest_x509_ca) (fin_resu, dresults) = helper.RemoteExport( self.dest_disk_info, key_name, dest_ca_pem, self.op.compress, timeouts) finally: helper.Cleanup() # Check for backwards compatibility assert len(dresults) == len(self.instance.disks) assert compat.all(isinstance(i, bool) for i in dresults), \ "Not all results are boolean: %r" % dresults finally: if activate_disks: feedback_fn("Deactivating disks for %s" % self.instance.name) ShutdownInstanceDisks(self, self.instance) if not (compat.all(dresults) and fin_resu): failures = [] if not fin_resu: failures.append("export finalization") if not compat.all(dresults): fdsk = utils.CommaJoin(idx for (idx, dsk) in enumerate(dresults) if not dsk) failures.append("disk export: disk(s) %s" % fdsk) raise errors.OpExecError("Export failed, errors in %s" % utils.CommaJoin(failures)) # At this point, the export was successful, we can cleanup/finish # Remove instance if requested if self.op.remove_instance: feedback_fn("Removing instance %s" % self.instance.name) RemoveInstance(self, feedback_fn, self.instance, self.op.ignore_remove_failures) if self.op.mode == constants.EXPORT_MODE_LOCAL: self._CleanupExports(feedback_fn) return fin_resu, dresults