def finish(self, src_ignore): devs = self.get_paths_to_delete() if devs: ret = uihelpers.chkbox_helper(self, self.config.get_confirm_delstorage, self.config.set_confirm_delstorage, text1=_("Are you sure you want to delete " "the storage?"), text2=_("All selected storage will " "be deleted.")) if not ret: return self.topwin.set_sensitive(False) self.topwin.get_window().set_cursor( Gdk.Cursor.new(Gdk.CursorType.WATCH)) title = _("Deleting virtual machine '%s'") % self.vm.get_name() text = title if devs: text = title + _(" and selected storage (this may take a while)") progWin = vmmAsyncJob(self._async_delete, [devs], self._finish_cb, [], title, text, self.topwin) progWin.run()
def finish(self, src_ignore): devs = self.get_paths_to_delete() self.topwin.set_sensitive(False) self.topwin.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH)) title = _("Deleting virtual machine '%s'") % self.vm.get_name() text = title if devs: text = title + _(" and selected storage (this may take a while)") progWin = vmmAsyncJob(self._async_delete, [devs], title, text, self.topwin) error, details = progWin.run() self.topwin.set_sensitive(True) self.topwin.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.TOP_LEFT_ARROW)) conn = self.conn if error is not None: self.err.show_err(error, details=details) conn.tick(noStatsUpdate=True) # Update Groups config file, send name of vm being deleted. If this vm is # member of some other group then delete that group. vmaffinityxmlutil.update_GroupsconfigOnDelete(self.vm.get_name()) self.close()
def finish(self, src_ignore): devs = self.get_paths_to_delete() self.topwin.set_sensitive(False) self.topwin.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH)) title = _("Deleting virtual machine '%s'") % self.vm.get_name() text = title if devs: text = title + _(" and selected storage (this may take a while)") progWin = vmmAsyncJob(self._async_delete, [devs], title, text, self.topwin) error, details = progWin.run() self.topwin.set_sensitive(True) self.topwin.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.TOP_LEFT_ARROW)) conn = self.conn if error is not None: self.err.show_err(error, details=details) conn.tick(noStatsUpdate=True) self.close()
def finish(self, src_ignore): devs = self.get_paths_to_delete() if devs: title = _("Are you sure you want to delete the storage?") message = (_("The following paths will be deleted:\n\n%s") % "\n".join(devs)) ret = self.err.chkbox_helper( self.config.get_confirm_delstorage, self.config.set_confirm_delstorage, text1=title, text2=message) if not ret: return self.topwin.set_sensitive(False) self.topwin.get_window().set_cursor( Gdk.Cursor.new(Gdk.CursorType.WATCH)) title = _("Deleting virtual machine '%s'") % self.vm.get_name() text = title if devs: text = title + _(" and selected storage (this may take a while)") progWin = vmmAsyncJob(self._async_delete, [devs], self._finish_cb, [], title, text, self.topwin) progWin.run()
def finish(self, src): # Validate the final page page = self.widget("pages").get_current_page() if self.validate(page) != True: return False activate = self.widget("interface-activate").get_active() # Start the install self.topwin.set_sensitive(False) self.topwin.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH)) progWin = vmmAsyncJob(self.do_install, [activate], _("Creating virtual interface"), _("The virtual interface is now being created."), self.topwin) error, details = progWin.run() self.topwin.set_sensitive(True) self.topwin.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.TOP_LEFT_ARROW)) if error: error = _("Error creating interface: '%s'") % error self.err.show_err(error, details=details) else: # FIXME: Hmm, shouldn't we emit a signal here rather than do this? self.conn.tick(noStatsUpdate=True) self.close()
def finish(self, src): # Validate the final page page = self.widget("pages").get_current_page() if self.validate(page) is not True: return False activate = self.widget("interface-activate").get_active() # Start the install self.topwin.set_sensitive(False) self.topwin.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.WATCH)) progWin = vmmAsyncJob(self.do_install, [activate], _("Creating virtual interface"), _("The virtual interface is now being created."), self.topwin) error, details = progWin.run() self.topwin.set_sensitive(True) self.topwin.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.TOP_LEFT_ARROW)) if error: error = _("Error creating interface: '%s'") % error self.err.show_err(error, details=details) else: # FIXME: Hmm, shouldn't we emit a signal here rather than do this? self.conn.tick(noStatsUpdate=True) self.close()
def _do_save_domain(self, src, uri, uuid): conn = self._lookup_conn(uri) vm = conn.get_vm(uuid) managed = bool(vm.managedsave_supported) if not managed and conn.is_remote(): src.err.val_err( _( "Saving virtual machines over remote " "connections is not supported with this " "libvirt version or hypervisor." ) ) return if not util.chkbox_helper( src, self.config.get_confirm_poweroff, self.config.set_confirm_poweroff, text1=_("Are you sure you want to save '%s'?" % vm.get_name()), ): return path = None if not managed: path = util.browse_local( src.topwin, _("Save Virtual Machine"), conn, dialog_type=gtk.FILE_CHOOSER_ACTION_SAVE, browse_reason=self.config.CONFIG_DIR_SAVE, ) if not path: return _cancel_back = None _cancel_args = [] if vm.getjobinfo_supported: _cancel_back = self._save_cancel _cancel_args = [vm] progWin = vmmAsyncJob( self._save_callback, [vm, path], _("Saving Virtual Machine"), _("Saving virtual machine memory to disk "), src.topwin, cancel_back=_cancel_back, cancel_args=_cancel_args, ) error, details = progWin.run() if error is not None: error = _("Error saving domain: %s") % error src.err.show_err(error, details=details)
def finish(self): self.topwin.set_sensitive(False) self.topwin.get_window().set_cursor( Gdk.Cursor.new(Gdk.CursorType.WATCH)) build = self.widget("pool-build").get_active() progWin = vmmAsyncJob(self._async_pool_create, [build], self._finish_cb, [], _("Creating storage pool..."), _("Creating the storage pool may take a " "while..."), self.topwin) progWin.run()
def _do_save_domain(self, src, uri, uuid): conn = self._lookup_conn(uri) vm = conn.get_vm(uuid) managed = bool(vm.managedsave_supported) if not managed and conn.is_remote(): src.err.val_err( _("Saving virtual machines over remote " "connections is not supported with this " "libvirt version or hypervisor.")) return if not util.chkbox_helper( src, self.config.get_confirm_poweroff, self.config.set_confirm_poweroff, text1=_( "Are you sure you want to save '%s'?" % vm.get_name())): return path = None if not managed: path = util.browse_local(src.topwin, _("Save Virtual Machine"), conn, dialog_type=gtk.FILE_CHOOSER_ACTION_SAVE, browse_reason=self.config.CONFIG_DIR_SAVE) if not path: return _cancel_back = None _cancel_args = [] if vm.getjobinfo_supported: _cancel_back = self._save_cancel _cancel_args = [vm] progWin = vmmAsyncJob(self._save_callback, [vm, path], _("Saving Virtual Machine"), _("Saving virtual machine memory to disk "), src.topwin, cancel_back=_cancel_back, cancel_args=_cancel_args) error, details = progWin.run() if error is not None: error = _("Error saving domain: %s") % error src.err.show_err(error, details=details)
def _do_save_domain(self, src, uri, uuid): conn = self._lookup_conn(uri) vm = conn.get_vm(uuid) managed = bool(vm.managedsave_supported) if not managed and conn.is_remote(): src.err.val_err(_("Saving virtual machines over remote " "connections is not supported with this " "libvirt version or hypervisor.")) return if not uihelpers.chkbox_helper(src, self.config.get_confirm_poweroff, self.config.set_confirm_poweroff, text1=_("Are you sure you want to save '%s'?" % vm.get_name())): return path = None if not managed: path = uihelpers.browse_local(src.topwin, _("Save Virtual Machine"), conn, dialog_type=Gtk.FileChooserAction.SAVE, browse_reason=self.config.CONFIG_DIR_SAVE) if not path: return _cancel_cb = None if vm.getjobinfo_supported: _cancel_cb = (self._save_cancel, vm) def cb(asyncjob): vm.save(path, meter=asyncjob.get_meter()) def finish_cb(error, details): if error is not None: error = _("Error saving domain: %s") % error src.err.show_err(error, details=details) progWin = vmmAsyncJob(cb, [], finish_cb, [], _("Saving Virtual Machine"), _("Saving virtual machine memory to disk "), src.topwin, cancel_cb=_cancel_cb) progWin.run()
def finish(self, src): # Validate the final page page = self.widget("pages").get_current_page() if self.validate(page) is not True: return False activate = self.widget("interface-activate").get_active() # Start the install self.topwin.set_sensitive(False) self.topwin.get_window().set_cursor( Gdk.Cursor.new(Gdk.CursorType.WATCH)) progWin = vmmAsyncJob(self.do_install, [activate], self._finish_cb, [], _("Creating virtual interface"), _("The virtual interface is now being created."), self.topwin) progWin.run()
def _create_new_snapshot(self): snap = self._validate_new_snapshot() if not snap: return xml = snap.get_xml_config() name = snap.name mime, sndata = self._get_screenshot_data_for_save() self.topwin.set_sensitive(False) self.topwin.get_window().set_cursor( Gdk.Cursor.new(Gdk.CursorType.WATCH)) self._snapshot_new_close() progWin = vmmAsyncJob( self._do_create_snapshot, [xml, name, mime, sndata], self._new_finish_cb, [name], _("Creating snapshot"), _("Creating virtual machine snapshot"), self.topwin) progWin.run()
def finish(self): self.topwin.set_sensitive(False) self.topwin.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.WATCH)) build = self.widget("pool-build").get_active() progWin = vmmAsyncJob(self._async_pool_create, [build], _("Creating storage pool..."), _("Creating the storage pool may take a " "while..."), self.topwin) error, details = progWin.run() self.topwin.set_sensitive(True) self.topwin.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.TOP_LEFT_ARROW)) if error: error = _("Error creating pool: %s") % error self.err.show_err(error, details=details) else: self.close()
def finish(self): self.topwin.set_sensitive(False) self.topwin.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH)) build = self.widget("pool-build").get_active() progWin = vmmAsyncJob(self._async_pool_create, [build], _("Creating storage pool..."), _("Creating the storage pool may take a " "while..."), self.topwin) error, details = progWin.run() self.topwin.set_sensitive(True) self.topwin.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.TOP_LEFT_ARROW)) if error: error = _("Error creating pool: %s") % error self.err.show_err(error, details=details) else: self.close()
def _on_new_ok_clicked(self, ignore): name = self.widget("snapshot-new-name").get_text() newsnap = virtinst.DomainSnapshot(self.vm.conn.get_backend()) newsnap.name = name # XXX: all manner of flags here: live, quiesce, atomic, etc. # most aren't relevant for internal? self.topwin.set_sensitive(False) self.topwin.get_window().set_cursor( Gdk.Cursor.new(Gdk.CursorType.WATCH)) self._snapshot_new_close() progWin = vmmAsyncJob( lambda ignore, xml: self.vm.create_snapshot(xml), [newsnap.get_xml_config()], self._finish_cb, [], _("Creating snapshot"), _("Creating virtual machine snapshot"), self.topwin) progWin.run()
def finish(self, src_ignore): devs = self.get_paths_to_delete() if devs: ret = util.chkbox_helper(self, self.config.get_confirm_delstorage, self.config.set_confirm_delstorage, text1=_("Are you sure you want to delete " "all the storage?"), text2=_("This will delete all selected " "storage data.")) if not ret: return self.topwin.set_sensitive(False) self.topwin.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.WATCH)) title = _("Deleting virtual machine '%s'") % self.vm.get_name() text = title if devs: text = title + _(" and selected storage (this may take a while)") progWin = vmmAsyncJob(self._async_delete, [devs], title, text, self.topwin) error, details = progWin.run() self.topwin.set_sensitive(True) self.topwin.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.TOP_LEFT_ARROW)) conn = self.conn if error is not None: self.err.show_err(error, details=details) conn.tick(noStatsUpdate=True) self.close()
def finish(self, src_ignore): devs = self.get_paths_to_delete() if devs: ret = util.chkbox_helper(self, self.config.get_confirm_delstorage, self.config.set_confirm_delstorage, text1=_("Are you sure you want to delete " "the storage?"), text2=_("All selected storage will " "be deleted.")) if not ret: return self.topwin.set_sensitive(False) self.topwin.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.WATCH)) title = _("Deleting virtual machine '%s'") % self.vm.get_name() text = title if devs: text = title + _(" and selected storage (this may take a while)") progWin = vmmAsyncJob(self._async_delete, [devs], title, text, self.topwin) error, details = progWin.run() self.topwin.set_sensitive(True) self.topwin.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.TOP_LEFT_ARROW)) conn = self.conn if error is not None: self.err.show_err(error, details=details) conn.tick(noStatsUpdate=True) self.close()
return except Exception, e: self.err.show_err(_("Uncaught error validating input: %s") % str(e)) return self.topwin.set_sensitive(False) self.topwin.get_window().set_cursor( Gdk.Cursor.new(Gdk.CursorType.WATCH)) title = (_("Creating virtual machine clone '%s'") % self.clone_design.clone_name) text = title if self.clone_design.clone_disks: text = title + _(" and selected storage (this may take a while)") progWin = vmmAsyncJob(self._async_clone, [], self._finish_cb, [], title, text, self.topwin) progWin.run() def _async_clone(self, asyncjob): try: self.orig_vm.set_cloning(True) meter = asyncjob.get_meter() self.clone_design.setup() self.clone_design.start_duplicate(meter) finally: self.orig_vm.set_cloning(False) def change_storage_browse(self, ignore): def callback(src_ignore, txt): self.widget("change-storage-new").set_text(txt)
class vmmMigrateDialog(vmmGObjectUI): def __init__(self, vm, engine): vmmGObjectUI.__init__(self, "vmm-migrate.ui", "vmm-migrate") self.vm = vm self.conn = vm.conn self.engine = engine self.destconn_rows = [] self.builder.connect_signals({ "on_vmm_migrate_delete_event" : self.close, "on_migrate_cancel_clicked" : self.close, "on_migrate_finish_clicked" : self.finish, "on_migrate_dest_changed" : self.destconn_changed, "on_migrate_set_rate_toggled" : self.toggle_set_rate, "on_migrate_set_interface_toggled" : self.toggle_set_interface, "on_migrate_set_port_toggled" : self.toggle_set_port, "on_migrate_set_maxdowntime_toggled" : self.toggle_set_maxdowntime, }) self.bind_escape_key_close() blue = Gdk.color_parse("#0072A8") self.widget("migrate-header").modify_bg(Gtk.StateType.NORMAL, blue) image = Gtk.Image.new_from_icon_name("vm_clone_wizard", Gtk.IconSize.DIALOG) image.show() self.widget("migrate-vm-icon-box").pack_end(image, False, False, False) self.init_state() def show(self, parent): logging.debug("Showing migrate wizard") self.reset_state() self.topwin.resize(1, 1) self.topwin.set_transient_for(parent) self.topwin.present() def close(self, ignore1=None, ignore2=None): logging.debug("Closing migrate wizard") self.topwin.hide() # If we only do this at show time, operation takes too long and # user actually sees the expander close. self.widget("migrate-advanced-expander").set_expanded(False) return 1 def _cleanup(self): self.vm = None self.conn = None self.engine = None self.destconn_rows = None # Not sure why we need to do this manually, but it matters self.widget("migrate-dest").get_model().clear() def init_state(self): # [hostname, conn, can_migrate, tooltip] dest_model = Gtk.ListStore(str, object, bool, str) dest_combo = self.widget("migrate-dest") dest_combo.set_model(dest_model) text = Gtk.CellRendererText() dest_combo.pack_start(text, True) dest_combo.add_attribute(text, 'text', 0) dest_combo.add_attribute(text, 'sensitive', 2) dest_model.set_sort_column_id(0, Gtk.SortType.ASCENDING) # Hook up signals to get connection listing self.engine.connect("conn-added", self.dest_add_conn) self.engine.connect("conn-removed", self.dest_remove_conn) self.destconn_changed(dest_combo) def reset_state(self): title_str = ("<span size='large' color='white'>%s '%s'</span>" % (_("Migrate"), util.xml_escape(self.vm.get_name()))) self.widget("migrate-main-label").set_markup(title_str) self.widget("migrate-cancel").grab_focus() name = self.vm.get_name() srchost = self.conn.get_hostname() self.widget("migrate-label-name").set_text(name) self.widget("migrate-label-src").set_text(srchost) self.widget("migrate-set-interface").set_active(False) self.widget("migrate-set-rate").set_active(False) self.widget("migrate-set-port").set_active(False) self.widget("migrate-set-maxdowntime").set_active(False) self.widget("migrate-max-downtime").set_value(30) running = self.vm.is_active() self.widget("migrate-offline").set_active(not running) self.widget("migrate-offline").set_sensitive(running) self.widget("migrate-rate").set_value(0) self.widget("migrate-secure").set_active(False) downtime_box = self.widget("migrate-maxdowntime-box") support_downtime = self.vm.support_downtime() downtime_tooltip = "" if not support_downtime: downtime_tooltip = _("Libvirt version does not support setting " "downtime.") downtime_box.set_sensitive(support_downtime) downtime_box.set_tooltip_text(downtime_tooltip) if self.conn.is_xen(): # Default xen port is 8002 self.widget("migrate-port").set_value(8002) else: # QEMU migrate port range is 49152+64 self.widget("migrate-port").set_value(49152) secure_box = self.widget("migrate-secure-box") support_secure = hasattr(libvirt, "VIR_MIGRATE_TUNNELLED") secure_tooltip = "" if not support_secure: secure_tooltip = _("Libvirt version does not support tunnelled " "migration.") secure_box.set_sensitive(support_secure) secure_box.set_tooltip_text(secure_tooltip) self.rebuild_dest_rows() def set_state(self, vm): self.vm = vm self.conn = vm.conn self.reset_state() def destconn_changed(self, src): active = src.get_active() tooltip = "" if active == -1: tooltip = _("A valid destination connection must be selected.") self.widget("migrate-finish").set_sensitive(active != -1) self.widget("migrate-finish").set_tooltip_text(tooltip) def toggle_set_rate(self, src): enable = src.get_active() self.widget("migrate-rate").set_sensitive(enable) def toggle_set_interface(self, src): enable = src.get_active() port_enable = self.widget("migrate-set-port").get_active() self.widget("migrate-interface").set_sensitive(enable) self.widget("migrate-set-port").set_sensitive(enable) self.widget("migrate-port").set_sensitive(enable and port_enable) def toggle_set_maxdowntime(self, src): enable = src.get_active() self.widget("migrate-max-downtime").set_sensitive(enable) def toggle_set_port(self, src): enable = src.get_active() self.widget("migrate-port").set_sensitive(enable) def get_config_destconn(self): combo = self.widget("migrate-dest") model = combo.get_model() idx = combo.get_active() if idx == -1: return None row = model[idx] if not row[2]: return None return row[1] def get_config_offline(self): return self.widget("migrate-offline").get_active() def get_config_max_downtime(self): if not self.get_config_max_downtime_enabled(): return 0 return int(self.widget("migrate-max-downtime").get_value()) def get_config_secure(self): return self.widget("migrate-secure").get_active() def get_config_max_downtime_enabled(self): return self.widget("migrate-max-downtime").get_sensitive() def get_config_rate_enabled(self): return self.widget("migrate-rate").get_sensitive() def get_config_rate(self): if not self.get_config_rate_enabled(): return 0 return int(self.widget("migrate-rate").get_value()) def get_config_interface_enabled(self): return self.widget("migrate-interface").get_sensitive() def get_config_interface(self): if not self.get_config_interface_enabled(): return None return self.widget("migrate-interface").get_text() def get_config_port_enabled(self): return self.widget("migrate-port").get_sensitive() def get_config_port(self): if not self.get_config_port_enabled(): return 0 return int(self.widget("migrate-port").get_value()) def build_localhost_uri(self, destconn, srcuri): desthost = destconn.get_qualified_hostname() if desthost == "localhost": # We couldn't find a host name for the destination machine # that is accessible from the source machine. # /etc/hosts is likely borked and the only hostname it will # give us is localhost. Remember, the dest machine can actually # be our local machine so we may not already know its hostname raise RuntimeError(_("Could not determine remotely accessible " "hostname for destination connection.")) # Since the connection started as local, we have no clue about # how to access it remotely. Assume users have a uniform access # setup and use the same credentials as the remote source URI return self.edit_uri(srcuri, desthost, None) def edit_uri(self, uri, hostname, port): split = list(uriutil.uri_split(uri)) hostname = hostname or split[2] if port: if hostname.count(":"): hostname = hostname.split(":")[0] hostname += ":%s" % port split[2] = hostname return uri_join(tuple(split)) def build_migrate_uri(self, destconn, srcuri): conn = self.conn interface = self.get_config_interface() port = self.get_config_port() secure = self.get_config_secure() if not interface and not secure: return None if secure: # P2P migration uri is a libvirt connection uri, e.g. # qemu+ssh://root@foobar/system # For secure migration, we need to make sure we aren't migrating # to the local connection, because libvirt will pull try to use # 'qemu:///system' as the migrate URI which will deadlock if destconn.is_local(): uri = self.build_localhost_uri(destconn, srcuri) else: uri = destconn.get_uri() uri = self.edit_uri(uri, interface, port) else: # Regular migration URI is HV specific uri = "" if conn.is_xen(): uri = "xenmigr://%s" % interface else: uri = "tcp:%s" % interface if port: uri += ":%s" % port return uri or None def rebuild_dest_rows(self): newrows = [] for row in self.destconn_rows: newrows.append(self.build_dest_row(row[1])) self.destconn_rows = newrows self.populate_dest_combo() def populate_dest_combo(self): combo = self.widget("migrate-dest") model = combo.get_model() idx = combo.get_active() idxconn = None if idx != -1: idxconn = model[idx][1] rows = [[_("No connections available."), None, False, None]] if self.destconn_rows: rows = self.destconn_rows model.clear() for r in rows: # Don't list the current connection if r[1] == self.conn: continue model.append(r) # Find old index idx = -1 for i in range(len(model)): row = model[i] conn = row[1] if idxconn: if conn == idxconn and row[2]: idx = i break else: if row[2]: idx = i break combo.set_active(idx) def dest_add_conn(self, engine_ignore, conn): combo = self.widget("migrate-dest") model = combo.get_model() newrow = self.build_dest_row(conn) # Make sure connection isn't already present for row in model: if row[1] and row[1].get_uri() == newrow[1].get_uri(): return conn.connect("state-changed", self.destconn_state_changed) self.destconn_rows.append(newrow) self.populate_dest_combo() def dest_remove_conn(self, engine_ignore, uri): # Make sure connection isn't already present for row in self.destconn_rows: if row[1] and row[1].get_uri() == uri: self.destconn_rows.remove(row) self.populate_dest_combo() def destconn_state_changed(self, conn): for row in self.destconn_rows: if row[1] == conn: self.destconn_rows.remove(row) self.destconn_rows.append(self.build_dest_row(conn)) self.populate_dest_combo() def build_dest_row(self, destconn): driver = self.conn.get_driver() origuri = self.conn.get_uri() can_migrate = False desc = destconn.get_pretty_desc_inactive() reason = "" desturi = destconn.get_uri() if destconn.get_driver() != driver: reason = _("Connection hypervisors do not match.") elif destconn.get_state() == destconn.STATE_DISCONNECTED: reason = _("Connection is disconnected.") elif destconn.get_uri() == origuri: # Same connection pass elif destconn.get_state() == destconn.STATE_ACTIVE: # Assumably we can migrate to this connection can_migrate = True reason = desturi return [desc, destconn, can_migrate, reason] def validate(self): interface = self.get_config_interface() rate = self.get_config_rate() port = self.get_config_port() max_downtime = self.get_config_max_downtime() if self.get_config_max_downtime_enabled() and max_downtime == 0: return self.err.val_err(_("max downtime must be greater than 0.")) if self.get_config_interface_enabled() and interface is None: return self.err.val_err(_("An interface must be specified.")) if self.get_config_rate_enabled() and rate == 0: return self.err.val_err(_("Transfer rate must be greater than 0.")) if self.get_config_port_enabled() and port == 0: return self.err.val_err(_("Port must be greater than 0.")) return True def finish(self, src_ignore): try: if not self.validate(): return destconn = self.get_config_destconn() srcuri = self.vm.conn.get_uri() srchost = self.vm.conn.get_hostname() dsthost = destconn.get_qualified_hostname() max_downtime = self.get_config_max_downtime() live = not self.get_config_offline() secure = self.get_config_secure() uri = self.build_migrate_uri(destconn, srcuri) rate = self.get_config_rate() if rate: rate = int(rate) except Exception, e: details = "".join(traceback.format_exc()) self.err.show_err((_("Uncaught error validating input: %s") % str(e)), details=details) return self.topwin.set_sensitive(False) self.topwin.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.WATCH)) cancel_cb = None if self.vm.getjobinfo_supported: cancel_cb = (self.cancel_migration, self.vm) progWin = vmmAsyncJob(self._async_migrate, [self.vm, destconn, uri, rate, live, secure, max_downtime], _("Migrating VM '%s'" % self.vm.get_name()), (_("Migrating VM '%s' from %s to %s. " "This may take a while.") % (self.vm.get_name(), srchost, dsthost)), self.topwin, cancel_cb=cancel_cb) error, details = progWin.run() self.topwin.set_sensitive(True) self.topwin.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.TOP_LEFT_ARROW)) if error: error = _("Unable to migrate guest: %s") % error self.err.show_err(error, details=details) else: self.conn.tick(noStatsUpdate=True) destconn.tick(noStatsUpdate=True) self.close()
except Exception, e: self.err.show_err( _("Uncaught error validating input: %s") % str(e)) return self.topwin.set_sensitive(False) self.topwin.get_window().set_cursor( Gdk.Cursor.new(Gdk.CursorType.WATCH)) title = (_("Creating virtual machine clone '%s'") % self.clone_design.clone_name) text = title if self.clone_design.clone_devices: text = title + _(" and selected storage (this may take a while)") progWin = vmmAsyncJob(self._async_clone, [], title, text, self.topwin) error, details = progWin.run() self.topwin.set_sensitive(True) self.topwin.get_window().set_cursor( Gdk.Cursor.new(Gdk.CursorType.TOP_LEFT_ARROW)) if error is not None: error = (_("Error creating virtual machine clone '%s': %s") % (self.clone_design.clone_name, error)) self.err.show_err(error, details=details) else: self.close() self.conn.tick(noStatsUpdate=True) def _async_clone(self, asyncjob):
def check_packagekit(errbox, packages, ishv): """ Returns None when we determine nothing useful. Returns (success, did we just install libvirt) otherwise. """ if not packages: logging.debug("No PackageKit packages to search for.") return logging.debug("Asking PackageKit what's installed locally.") try: bus = Gio.bus_get_sync(Gio.BusType.SYSTEM, None) pk_control = Gio.DBusProxy.new_sync(bus, 0, None, "org.freedesktop.PackageKit", "/org/freedesktop/PackageKit", "org.freedesktop.PackageKit", None) except Exception: logging.exception("Couldn't connect to packagekit") return if ishv: msg = _("Searching for available hypervisors...") else: msg = _("Checking for installed package '%s'") % packages[0] cancellable = Gio.Cancellable() progWin = vmmAsyncJob(_do_async_search, [bus, pk_control, packages, cancellable], msg, msg, errbox.get_parent(), async=False, cancel_cb=[_cancel_search, cancellable]) error, ignore = progWin.run() if error: return found = progWin.get_extra_data() not_found = [x for x in packages if x not in found] logging.debug("Missing packages: %s", not_found) do_install = not_found if not do_install: if not not_found: # Got everything we wanted, try to connect logging.debug("All packages found locally.") return [] else: logging.debug("No packages are available for install.") return missing = reduce(lambda x, y: x + "\n" + y, do_install, "") if ishv: msg = (_("The following packages are not installed:\n%s\n\n" "These are required to create KVM guests locally.\n" "Would you like to install them now?") % missing) title = _("Packages required for KVM usage") else: msg = _("The following packages are not installed:\n%s\n\n" "Would you like to install them now?" % missing) title = _("Recommended package installs") ret = errbox.yes_no(title, msg) if not ret: logging.debug("Package install declined.") return try: packagekit_install(do_install) except Exception, e: errbox.show_err(_("Error talking to PackageKit: %s") % str(e)) return
class vmmCreateVolume(vmmGObjectUI): __gsignals__ = { "vol-created": (GObject.SignalFlags.RUN_FIRST, None, []), } def __init__(self, conn, parent_pool): vmmGObjectUI.__init__(self, "vmm-create-vol.ui", "vmm-create-vol") self.conn = conn self.parent_pool = parent_pool self.name_hint = None self.vol = None self.vol_class = Storage.StoragePool.get_volume_for_pool(parent_pool.get_type()) self.builder.connect_signals({ "on_vmm_create_vol_delete_event" : self.close, "on_vol_cancel_clicked" : self.close, "on_vol_create_clicked" : self.finish, "on_vol_name_changed" : self.vol_name_changed, "on_vol_allocation_value_changed" : self.vol_allocation_changed, "on_vol_capacity_value_changed" : self.vol_capacity_changed, }) self.bind_escape_key_close() format_list = self.widget("vol-format") format_model = Gtk.ListStore(str, str) format_list.set_model(format_model) text2 = Gtk.CellRendererText() format_list.pack_start(text2, False) format_list.add_attribute(text2, 'text', 1) self.widget("vol-info-view").modify_bg(Gtk.StateType.NORMAL, Gdk.Color.parse("grey")[1]) finish_img = Gtk.Image.new_from_stock(Gtk.STOCK_QUIT, Gtk.IconSize.BUTTON) self.widget("vol-create").set_image(finish_img) self.reset_state() def show(self, parent): logging.debug("Showing new volume wizard") self.reset_state() self.topwin.set_transient_for(parent) self.topwin.present() def close(self, ignore1=None, ignore2=None): logging.debug("Closing new volume wizard") self.topwin.hide() self.set_modal(False) return 1 def _cleanup(self): self.conn = None self.parent_pool = None def set_name_hint(self, hint): self.name_hint = hint def set_modal(self, modal): self.topwin.set_modal(bool(modal)) def set_parent_pool(self, pool): self.parent_pool = pool self.vol_class = Storage.StoragePool.get_volume_for_pool(self.parent_pool.get_type()) def default_vol_name(self): if not self.name_hint: return "" suffix = self.default_suffix() ret = "" try: ret = Storage.StorageVolume.find_free_name(self.name_hint, pool_object=self.parent_pool.pool, suffix=suffix) ret = ret.rstrip(suffix) except: pass return ret def default_suffix(self): suffix = "" if self.vol_class == Storage.FileVolume: suffix = ".img" return suffix def reset_state(self): default_name = self.default_vol_name() self.widget("vol-name").set_text("") self.widget("vol-create").set_sensitive(False) if default_name: self.widget("vol-name").set_text(default_name) self.widget("vol-name").grab_focus() self.populate_vol_format() self.populate_vol_suffix() if len(self.vol_class.formats): self.widget("vol-format").set_sensitive(True) self.widget("vol-format").set_active(0) else: self.widget("vol-format").set_sensitive(False) alloc = DEFAULT_ALLOC if self.parent_pool.get_type() == "logical": # Sparse LVM volumes don't auto grow, so alloc=0 is useless alloc = DEFAULT_CAP self.widget("vol-allocation").set_range(0, int(self.parent_pool.get_available() / 1024 / 1024)) self.widget("vol-allocation").set_value(alloc) self.widget("vol-capacity").set_range(1, int(self.parent_pool.get_available() / 1024 / 1024)) self.widget("vol-capacity").set_value(DEFAULT_CAP) self.widget("vol-parent-name").set_markup( "<b>" + self.parent_pool.get_name() + "'s</b>") self.widget("vol-parent-space").set_text( self.parent_pool.get_pretty_available()) def get_config_format(self): format_combo = self.widget("vol-format") model = format_combo.get_model() if format_combo.get_active_iter() is not None: model = format_combo.get_model() return model.get_value(format_combo.get_active_iter(), 0) return None def populate_vol_format(self): rhel6_file_whitelist = ["raw", "qcow2", "qed"] model = self.widget("vol-format").get_model() model.clear() formats = self.vol_class.formats if hasattr(self.vol_class, "create_formats"): formats = getattr(self.vol_class, "create_formats") if (self.vol_class == Storage.FileVolume and not self.conn.rhel6_defaults_caps()): newfmts = [] for f in rhel6_file_whitelist: if f in formats: newfmts.append(f) formats = newfmts for f in formats: model.append([f, f]) def populate_vol_suffix(self): suffix = self.default_suffix() if self.vol_class == Storage.FileVolume: suffix = ".img" self.widget("vol-name-suffix").set_text(suffix) def vol_name_changed(self, src): text = src.get_text() self.widget("vol-create").set_sensitive(bool(text)) def vol_allocation_changed(self, src): cap_widget = self.widget("vol-capacity") alloc = src.get_value() cap = cap_widget.get_value() if alloc > cap: cap_widget.set_value(alloc) def vol_capacity_changed(self, src): alloc_widget = self.widget("vol-allocation") cap = src.get_value() alloc = self.widget("vol-allocation").get_value() if cap < alloc: alloc_widget.set_value(cap) def finish(self, src_ignore): try: if not self.validate(): return except Exception, e: self.show_err(_("Uncaught error validating input: %s") % str(e)) return logging.debug("Creating volume with xml:\n%s", self.vol.get_xml_config()) self.topwin.set_sensitive(False) self.topwin.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.WATCH)) progWin = vmmAsyncJob(self._async_vol_create, [], _("Creating storage volume..."), _("Creating the storage volume may take a " "while..."), self.topwin) error, details = progWin.run() self.topwin.set_sensitive(True) self.topwin.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.TOP_LEFT_ARROW)) if error: error = _("Error creating vol: %s") % error self.show_err(error, details=details) else: self.emit("vol-created") self.close()
def check_packagekit(errbox, packages, ishv): """ Returns None when we determine nothing useful. Returns (success, did we just install libvirt) otherwise. """ if not packages: logging.debug("No PackageKit packages to search for.") return logging.debug("Asking PackageKit what's installed locally.") try: session = dbus.SystemBus() pk_control = dbus.Interface( session.get_object("org.freedesktop.PackageKit", "/org/freedesktop/PackageKit"), "org.freedesktop.PackageKit") except Exception: logging.exception("Couldn't connect to packagekit") return if ishv: msg = _("Searching for available hypervisors...") else: msg = _("Checking for installed package '%s'") % packages[0] found = [] progWin = vmmAsyncJob(_do_async_search, [session, pk_control, packages], msg, msg, None, async=False) error, ignore = progWin.run() if error: return found = progWin.get_data() not_found = filter(lambda x: x not in found, packages) logging.debug("Missing packages: %s", not_found) do_install = not_found if not do_install: if not not_found: # Got everything we wanted, try to connect logging.debug("All packages found locally.") return [] else: logging.debug("No packages are available for install.") return missing = reduce(lambda x, y: x + "\n" + y, do_install, "") if ishv: msg = (_("The following packages are not installed:\n%s\n\n" "These are required to create KVM guests locally.\n" "Would you like to install them now?") % missing) title = _("Packages required for KVM usage") else: msg = _("The following packages are not installed:\n%s\n\n" "Would you like to install them now?" % missing) title = _("Recommended package installs") ret = errbox.yes_no(title, msg) if not ret: logging.debug("Package install declined.") return try: packagekit_install(do_install) except Exception, e: errbox.show_err(_("Error talking to PackageKit: %s") % str(e)) return
if error: error = _("Error creating virtual network: %s") % str(error) self.err.show_err(error, details=details) else: self.conn.schedule_priority_tick(pollnet=True) self.close() def _async_net_create(self, asyncjob, net): ignore = asyncjob net.install() def finish(self, ignore): try: net = self._build_xmlobj() except Exception, e: self.err.show_erro(_("Error generating network xml: %s" % str(e))) return self.topwin.set_sensitive(False) self.topwin.get_window().set_cursor( Gdk.Cursor.new(Gdk.CursorType.WATCH)) progWin = vmmAsyncJob(self._async_net_create, [net], self._finish_cb, [], _("Creating virtual network..."), _("Creating the virtual network may take a " "while..."), self.topwin) progWin.run()