From: Leonardo Garcia <lagarcia@xxxxxxxxxx> --- ui/vmm-delete.ui | 46 +++++++++++++++++++++++++++++++++++++++++++++- ui/vmm-details.ui | 15 +++++++++++++++ virtManager/console.py | 10 ++++++++-- virtManager/delete.py | 35 +++++++++++++++++++++++++++++++++-- virtManager/details.py | 6 ++++++ virtManager/engine.py | 16 ++++++++++++++++ virtManager/manager.py | 20 ++------------------ 7 files changed, 125 insertions(+), 23 deletions(-) diff --git a/ui/vmm-delete.ui b/ui/vmm-delete.ui index fa1e75e..7cbab36 100644 --- a/ui/vmm-delete.ui +++ b/ui/vmm-delete.ui @@ -116,6 +116,50 @@ </packing> </child> <child> + <object class="GtkAlignment" id="delete-warn-running-vm-align"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="left_padding">6</property> + <child> + <object class="GtkHBox" id="delete-warn-running-vm-box"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">3</property> + <child> + <object class="GtkImage" id="delete-warn-running-vm-icon"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="stock">gtk-dialog-warning</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="delete-warn-running-vm-label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes"><small>This VM is currently running and will be forced off before being deleted</small></property> + <property name="use_markup">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> <object class="GtkCheckButton" id="delete-remove-storage"> <property name="label" translatable="yes">Delete _associated storage files</property> <property name="visible">True</property> @@ -129,7 +173,7 @@ <packing> <property name="expand">False</property> <property name="fill">True</property> - <property name="position">1</property> + <property name="position">2</property> </packing> </child> </object> diff --git a/ui/vmm-details.ui b/ui/vmm-details.ui index ddb2a71..ea4b53e 100644 --- a/ui/vmm-details.ui +++ b/ui/vmm-details.ui @@ -314,6 +314,21 @@ </object> </child> <child> + <object class="GtkMenuItem" id="details-menu-delete"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">_Delete...</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_details_menu_delete_activate" swapped="no"/> + </object> + </child> + <child> + <object class="GtkSeparatorMenuItem" id="separator2"> + <property name="visible">True</property> + <property name="can_focus">False</property> + </object> + </child> + <child> <object class="GtkMenuItem" id="details-menu-vm-screenshot"> <property name="visible">True</property> <property name="can_focus">False</property> diff --git a/virtManager/console.py b/virtManager/console.py index b9186ce..001318e 100644 --- a/virtManager/console.py +++ b/virtManager/console.py @@ -651,7 +651,10 @@ class vmmConsolePages(vmmGObjectUI): self.page_changed() def is_visible(self): - return self.topwin.get_visible() + if self.topwin: + return self.topwin.get_visible() + else: + return False def _cleanup(self): self.vm = None @@ -892,6 +895,9 @@ class vmmConsolePages(vmmGObjectUI): ########################## def view_vm_status(self): + if not self.vm: + # window has been closed and no pages to update are available. + return status = self.vm.status() if status == libvirt.VIR_DOMAIN_SHUTOFF: self.activate_unavailable_page(_("Guest not running")) @@ -900,7 +906,6 @@ class vmmConsolePages(vmmGObjectUI): self.activate_unavailable_page(_("Guest has crashed")) def close_viewer(self): - viewport = self.widget("console-gfx-viewport") if self.viewer is None: return @@ -908,6 +913,7 @@ class vmmConsolePages(vmmGObjectUI): self.viewer = None w = v.display + viewport = self.widget("console-gfx-viewport") if w and w in viewport.get_children(): viewport.remove(w) diff --git a/virtManager/delete.py b/virtManager/delete.py index b7cb50d..ce55105 100644 --- a/virtManager/delete.py +++ b/virtManager/delete.py @@ -99,6 +99,10 @@ class vmmDeleteDialog(vmmGObjectUI): self.widget("delete-cancel").grab_focus() + # Show warning message if VM is running + vm_active = self.vm.is_active() + self.widget("delete-warn-running-vm-box").set_visible(vm_active) + # Disable storage removal by default self.widget("delete-remove-storage").set_active(True) self.widget("delete-remove-storage").toggled() @@ -140,10 +144,38 @@ class vmmDeleteDialog(vmmGObjectUI): if not ret: return + conn = self.conn + vm = self.vm 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() + if vm.is_active(): + def tmpcb(job, *args, **kwargs): + ignore = job + vm.destroy() + docb = tmpcb + title = _("Forcing VM Power off") + text = _("Powering off the VM in order to proceed with its deletion.") + + syncjob = vmmAsyncJob(docb, [], title, text, self.topwin, + async=False) + error, details = syncjob.run() + + if error is not None: + self.topwin.set_sensitive(True) + self.topwin.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.TOP_LEFT_ARROW)) + + self.err.show_err(error, details=details) + + conn.tick(noStatsUpdate=True) + + self.close() + return + + logging.debug("Forced power off of vm '%s in order to proceed with " + "its deletion'", vm.get_name()) + + title = _("Deleting virtual machine '%s'") % vm.get_name() text = title if devs: text = title + _(" and selected storage (this may take a while)") @@ -154,7 +186,6 @@ class vmmDeleteDialog(vmmGObjectUI): 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) diff --git a/virtManager/details.py b/virtManager/details.py index fb4b493..b2d496e 100644 --- a/virtManager/details.py +++ b/virtManager/details.py @@ -329,6 +329,7 @@ class vmmDetails(vmmGObjectUI): "action-exit-app": (GObject.SignalFlags.RUN_FIRST, None, []), "action-view-manager": (GObject.SignalFlags.RUN_FIRST, None, []), "action-migrate-domain": (GObject.SignalFlags.RUN_FIRST, None, [str, str]), + "action-delete-domain": (GObject.SignalFlags.RUN_FIRST, None, [str, str]), "action-clone-domain": (GObject.SignalFlags.RUN_FIRST, None, [str, str]), "details-closed": (GObject.SignalFlags.RUN_FIRST, None, []), "details-opened": (GObject.SignalFlags.RUN_FIRST, None, []), @@ -412,6 +413,7 @@ class vmmDetails(vmmGObjectUI): "on_details_menu_pause_activate": self.control_vm_pause, "on_details_menu_clone_activate": self.control_vm_clone, "on_details_menu_migrate_activate": self.control_vm_migrate, + "on_details_menu_delete_activate": self.control_vm_delete, "on_details_menu_screenshot_activate": self.control_vm_screenshot, "on_details_menu_view_toolbar_activate": self.toggle_toolbar, "on_details_menu_view_manager_activate": self.view_manager, @@ -1580,6 +1582,10 @@ class vmmDetails(vmmGObjectUI): self.emit("action-migrate-domain", self.vm.conn.get_uri(), self.vm.get_uuid()) + def control_vm_delete(self, src_ignore): + self.emit("action-delete-domain", + self.vm.conn.get_uri(), self.vm.get_uuid()) + def control_vm_screenshot(self, src): ignore = src try: diff --git a/virtManager/engine.py b/virtManager/engine.py index 8950451..b636ac2 100644 --- a/virtManager/engine.py +++ b/virtManager/engine.py @@ -48,6 +48,7 @@ from virtManager.create import vmmCreate from virtManager.host import vmmHost from virtManager.error import vmmErrorDialog from virtManager.systray import vmmSystray +from virtManager.delete import vmmDeleteDialog # Enable this to get a report of leaked objects on app shutdown # gtk3/pygobject has issues here as of Fedora 18 @@ -95,6 +96,7 @@ class vmmEngine(vmmGObject): self.last_timeout = 0 self.systray = None + self.delete_dialog = None self.application = Gtk.Application( application_id="com.redhat.virt-manager", flags=0) @@ -376,6 +378,10 @@ class vmmEngine(vmmGObject): self.windowMigrate.cleanup() self.windowMigrate = None + if self.delete_dialog: + self.delete_dialog.cleanup() + self.delete_dialog = None + # Do this last, so any manually 'disconnected' signals # take precedence over cleanup signal removal for uri in self.conns: @@ -605,6 +611,7 @@ class vmmEngine(vmmGObject): obj.connect("action-exit-app", self.exit_app) obj.connect("action-view-manager", self._do_show_manager) obj.connect("action-migrate-domain", self._do_show_migrate) + obj.connect("action-delete-domain", self._do_delete_domain) obj.connect("action-clone-domain", self._do_show_clone) obj.connect("details-opened", self.increment_window_counter) obj.connect("details-closed", self.decrement_window_counter) @@ -648,6 +655,7 @@ class vmmEngine(vmmGObject): obj.connect("action-reset-domain", self._do_reset_domain) obj.connect("action-save-domain", self._do_save_domain) obj.connect("action-migrate-domain", self._do_show_migrate) + obj.connect("action-delete-domain", self._do_delete_domain) obj.connect("action-clone-domain", self._do_show_clone) obj.connect("action-show-vm", self._do_show_vm) obj.connect("action-show-preferences", self._do_show_preferences) @@ -991,3 +999,11 @@ class vmmEngine(vmmGObject): logging.debug("Resetting vm '%s'", vm.get_name()) vmmAsyncJob.simple_async_noshow(vm.reset, [], src, _("Error resetting domain")) + + def _do_delete_domain(self, src, uri, uuid): + conn = self._lookup_conn(uri) + vm = conn.get_vm(uuid) + + if not self.delete_dialog: + self.delete_dialog = vmmDeleteDialog() + self.delete_dialog.show(vm, src.topwin) diff --git a/virtManager/manager.py b/virtManager/manager.py index 3620268..8a90eed 100644 --- a/virtManager/manager.py +++ b/virtManager/manager.py @@ -95,6 +95,7 @@ class vmmManager(vmmGObjectUI): "action-destroy-domain": (GObject.SignalFlags.RUN_FIRST, None, [str, str]), "action-save-domain": (GObject.SignalFlags.RUN_FIRST, None, [str, str]), "action-migrate-domain": (GObject.SignalFlags.RUN_FIRST, None, [str, str]), + "action-delete-domain": (GObject.SignalFlags.RUN_FIRST, None, [str, str]), "action-clone-domain": (GObject.SignalFlags.RUN_FIRST, None, [str, str]), "action-exit-app": (GObject.SignalFlags.RUN_FIRST, None, []), "manager-closed": (GObject.SignalFlags.RUN_FIRST, None, []), @@ -106,7 +107,6 @@ class vmmManager(vmmGObjectUI): def __init__(self): vmmGObjectUI.__init__(self, "vmm-manager.ui", "vmm-manager") - self.delete_dialog = None self.ignore_pause = False # Mapping of VM UUID -> tree model rows to @@ -227,10 +227,6 @@ class vmmManager(vmmGObjectUI): self.hostcpucol = None self.netcol = None - if self.delete_dialog: - self.delete_dialog.cleanup() - self.delete_dialog = None - self.vmmenu.destroy() self.vmmenu = None self.vmmenu_items = None @@ -586,7 +582,7 @@ class vmmManager(vmmGObjectUI): if vm is None: self._do_delete_conn(conn) else: - self._do_delete_vm(vm) + self.emit("action-delete-domain", conn.get_uri(), vm.get_uuid()) def _do_delete_conn(self, conn): if conn is None: @@ -599,14 +595,6 @@ class vmmManager(vmmGObjectUI): self.emit("remove-conn", conn.get_uri()) - def _do_delete_vm(self, vm): - if vm.is_active(): - return - - if not self.delete_dialog: - self.delete_dialog = vmmDeleteDialog() - self.delete_dialog.show(vm, self.topwin) - def set_pause_state(self, state): src = self.widget("vm-pause") try: @@ -1065,8 +1053,6 @@ class vmmManager(vmmGObjectUI): show_details = bool(vm) host_details = bool(len(self.rows)) - delete = bool((vm and vm.is_runable()) or - (not vm and conn)) show_run = bool(vm and vm.is_runable()) is_paused = bool(vm and vm.is_paused()) if is_paused: @@ -1086,7 +1072,6 @@ class vmmManager(vmmGObjectUI): self.widget("menu_edit_details").set_sensitive(show_details) self.widget("menu_host_details").set_sensitive(host_details) - self.widget("menu_edit_delete").set_sensitive(delete) def popup_vm_menu_key(self, widget_ignore, event): if Gdk.keyval_name(event.keyval) != "Menu": @@ -1131,7 +1116,6 @@ class vmmManager(vmmGObjectUI): self.vmmenu_items["resume"].set_sensitive(paused) self.vmmenu_items["migrate"].set_sensitive(stop) self.vmmenu_items["clone"].set_sensitive(not ro) - self.vmmenu_items["delete"].set_sensitive(run) self.vmmenushutdown_items["poweroff"].set_sensitive(stop) self.vmmenushutdown_items["reboot"].set_sensitive(stop) -- 1.7.1 _______________________________________________ virt-tools-list mailing list virt-tools-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/virt-tools-list