From ac8591192f6cefe586813e7b1568451e47359e3d Mon Sep 17 00:00:00 2001 From: Cole Robinson Date: Wed, 9 Sep 2020 19:04:44 -0400 Subject: [PATCH] console: Add option to disable autoconnect As part of making virt-manager cooperate better with external viewers, add an option to disable console autoconnect. When opening a VM window for a running VM, you'll see a 'Connect to console' button in place of the spice/vnc viewer. Click that and things proceed like normal. This is useful to prevent virt-manager from disconnecting a virt-viewer instance that's already attached to a VM https://bugzilla.redhat.com/show_bug.cgi?id=1793876 Signed-off-by: Cole Robinson --- .../org.virt-manager.virt-manager.gschema.xml | 12 +++++++ tests/uitests/test_livetests.py | 18 ++++++++++ tests/uitests/test_prefs.py | 1 + ui/console.ui | 36 ++++++++++++++++--- ui/preferences.ui | 28 +++++++++++++++ ui/vmwindow.ui | 9 +++++ virtManager/config.py | 5 +++ virtManager/details/console.py | 24 +++++++++---- virtManager/object/domain.py | 11 ++++++ virtManager/preferences.py | 7 ++++ virtManager/vmwindow.py | 13 +++++++ 11 files changed, 152 insertions(+), 12 deletions(-) diff --git a/data/org.virt-manager.virt-manager.gschema.xml b/data/org.virt-manager.virt-manager.gschema.xml index 533bc6aa1..7ba402fff 100644 --- a/data/org.virt-manager.virt-manager.gschema.xml +++ b/data/org.virt-manager.virt-manager.gschema.xml @@ -25,6 +25,12 @@ Automatically resize guest when window size changes Automatically change guest resolution along with virt-manager window. Only works with spice with a vdagent set up. -1 = global default, 0 = off, 1 = on. + + + -1 + Autoconnect to the default VM console when the VM window is opened + Autoconnect to the default VM console when the VM window is opened. Users may want to turn this off if they prefer to use another viewer app for their VMs, and don't want virt-manager to interfere, but they still want to use virt-manager's details. -1 = global default, 0 = off, 1 = on + @@ -222,6 +228,12 @@ Enable SPICE Auto USB redirection in console window Whether to enable SPICE Auto USB redirection while connected to the guest console. + + + true + Autoconnect to the default VM console when the VM window is opened + Autoconnect to the default VM console when the VM window is opened. Users may want to turn this off if they prefer to use another viewer app for their VMs, and don't want virt-manager to interfere, but they still want to use virt-manager's details. + + + True + False + gtk-apply + True True @@ -282,6 +287,32 @@ False + + + _Connect to console + True + True + True + center + center + True + + + + 3 + + + + + True + False + Connect + + + 3 + False + + 2 @@ -304,9 +335,4 @@ - - True - False - gtk-apply - diff --git a/ui/preferences.ui b/ui/preferences.ui index 7b5ec702e..8d1dfc898 100644 --- a/ui/preferences.ui +++ b/ui/preferences.ui @@ -745,6 +745,34 @@ Redirection: 3 + + + True + False + If disabled, the VM window will not automatically connect to the running VM graphical console. + start + Console autoconnec_t: + True + prefs-console-autoconnect + + + 0 + 4 + + + + + True + True + False + True + + + + 1 + 4 + + diff --git a/ui/vmwindow.ui b/ui/vmwindow.ui index a88cde120..457a79e58 100644 --- a/ui/vmwindow.ui +++ b/ui/vmwindow.ui @@ -246,6 +246,15 @@ True + + + True + False + _Autoconnect + True + + + True diff --git a/virtManager/config.py b/virtManager/config.py index 5f689c8f2..f552906c2 100644 --- a/virtManager/config.py +++ b/virtManager/config.py @@ -487,6 +487,11 @@ class vmmConfig(object): def set_auto_usbredir(self, state): self.conf.set("/console/auto-redirect", state) + def get_console_autoconnect(self): + return bool(self.conf.get("/console/autoconnect")) + def set_console_autoconnect(self, val): + return self.conf.set("/console/autoconnect", val) + # Show VM details toolbar def get_details_show_toolbar(self): res = self.conf.get("/details/show-toolbar") diff --git a/virtManager/details/console.py b/virtManager/details/console.py index 9f1b126ff..f1274eff4 100644 --- a/virtManager/details/console.py +++ b/virtManager/details/console.py @@ -25,7 +25,8 @@ from ..lib.keyring import vmmKeyring # console-gfx-pages IDs (_GFX_PAGE_VIEWER, _GFX_PAGE_AUTH, - _GFX_PAGE_UNAVAILABLE) = range(3) + _GFX_PAGE_UNAVAILABLE, + _GFX_PAGE_CONNECT) = range(4) class _TimedRevealer(vmmGObject): @@ -317,6 +318,7 @@ class vmmConsolePages(vmmGObjectUI): # Initialize display widget self._viewer = None + self._viewer_connect_clicked = False self._in_fullscreen = False # Fullscreen toolbar @@ -350,6 +352,7 @@ class vmmConsolePages(vmmGObjectUI): "on_console_pages_switch_page": self._page_changed_cb, "on_console_auth_password_activate": self._auth_login_cb, "on_console_auth_login_clicked": self._auth_login_cb, + "on_console_connect_button_clicked": self._connect_button_clicked_cb, }) self.widget("console-gfx-scroll").connect("size-allocate", @@ -372,12 +375,6 @@ class vmmConsolePages(vmmGObjectUI): self._serial_consoles = [] - ########################## - # Initialization helpers # - ########################## - - - ################# # Internal APIs # ################# @@ -596,6 +593,7 @@ class vmmConsolePages(vmmGObjectUI): def _close_viewer(self): self._leave_fullscreen() + self._viewer_connect_clicked = False for serial in self._serial_consoles: serial.close() @@ -679,6 +677,9 @@ class vmmConsolePages(vmmGObjectUI): if self._viewer: self._viewer.console_grab_focus() + def _activate_gfx_connect_page(self): + self.widget("console-gfx-pages").set_current_page(_GFX_PAGE_CONNECT) + def _viewer_is_visible(self): is_visible = self.widget("console-pages").is_visible() cpage = self.widget("console-pages").get_current_page() @@ -733,6 +734,11 @@ class vmmConsolePages(vmmGObjectUI): self._activate_gfx_unavailable_page(msg) return + if (not self.vm.get_console_autoconnect() and + not self._viewer_connect_clicked): + self._activate_gfx_connect_page() + return + self._activate_gfx_unavailable_page( _("Connecting to graphical console for guest")) @@ -942,6 +948,10 @@ class vmmConsolePages(vmmGObjectUI): def _auth_login_cb(self, src): self._set_credentials() + def _connect_button_clicked_cb(self, src): + self._viewer_connect_clicked = True + self._init_viewer() + def _page_changed_cb(self, src, origpage, newpage): # Hide the contents of all other pages, so they don't screw # up window sizing diff --git a/virtManager/object/domain.py b/virtManager/object/domain.py index ea9d35032..7310db101 100644 --- a/virtManager/object/domain.py +++ b/virtManager/object/domain.py @@ -1558,6 +1558,17 @@ class vmmDomain(vmmLibvirtObject): return self.config.get_console_resizeguest() return ret + def on_console_autoconnect_changed(self, *args, **kwargs): + return self.config.listen_pervm(self.get_uuid(), "/resize-guest", + *args, **kwargs) + def set_console_autoconnect(self, value): + self.config.set_pervm(self.get_uuid(), "/autoconnect", value) + def get_console_autoconnect(self): + ret = self.config.get_pervm(self.get_uuid(), "/autoconnect") + if ret == -1: + return self.config.get_console_autoconnect() + return ret + def set_details_window_size(self, w, h): self.config.set_pervm(self.get_uuid(), "/vm-window-size", (w, h)) def get_details_window_size(self): diff --git a/virtManager/preferences.py b/virtManager/preferences.py index 73fcccbe7..a45cccf9b 100644 --- a/virtManager/preferences.py +++ b/virtManager/preferences.py @@ -42,6 +42,7 @@ class vmmPreferences(vmmGObjectUI): self.refresh_console_scaling() self.refresh_console_resizeguest() self.refresh_console_autoredir() + self.refresh_console_autoconnect() self.refresh_new_vm_sound() self.refresh_graphics_type() self.refresh_add_spice_usbredir() @@ -70,6 +71,7 @@ class vmmPreferences(vmmGObjectUI): "on_prefs_console_scaling_changed": self.change_console_scaling, "on_prefs_console_resizeguest_changed": self.change_console_resizeguest, "on_prefs_console_autoredir_changed": self.change_console_autoredir, + "on_prefs_console_autoconnect_toggled": self.change_console_autoconnect, "on_prefs_new_vm_sound_toggled": self.change_new_vm_sound, "on_prefs_graphics_type_changed": self.change_graphics_type, "on_prefs_add_spice_usbredir_changed": self.change_add_spice_usbredir, @@ -230,6 +232,9 @@ class vmmPreferences(vmmGObjectUI): combo = self.widget("prefs-console-autoredir") val = self.config.get_auto_usbredir() uiutil.set_list_selection(combo, val) + def refresh_console_autoconnect(self): + val = self.config.get_console_autoconnect() + self.widget("prefs-console-autoconnect").set_active(val) def refresh_new_vm_sound(self): self.widget("prefs-new-vm-sound").set_active( @@ -378,6 +383,8 @@ class vmmPreferences(vmmGObjectUI): def change_console_autoredir(self, box): val = uiutil.get_list_selection(box) self.config.set_auto_usbredir(val) + def change_console_autoconnect(self, src): + self.config.set_console_autoconnect(bool(src.get_active())) def change_new_vm_sound(self, src): self.config.set_new_vm_sound(src.get_active()) diff --git a/virtManager/vmwindow.py b/virtManager/vmwindow.py index b49d90d7c..62fc6cb81 100644 --- a/virtManager/vmwindow.py +++ b/virtManager/vmwindow.py @@ -128,6 +128,7 @@ class vmmVMWindow(vmmGObjectUI): "on_details_menu_view_scale_fullscreen_toggled": self._scaling_ui_changed_cb, "on_details_menu_view_scale_never_toggled": self._scaling_ui_changed_cb, "on_details_menu_view_resizeguest_toggled": self._resizeguest_ui_changed_cb, + "on_details_menu_view_autoconnect_activate": self._autoconnect_ui_changed_cb, }) # Deliberately keep all this after signal connection @@ -146,6 +147,10 @@ class vmmVMWindow(vmmGObjectUI): self.vm.on_console_resizeguest_changed( self._console_refresh_resizeguest_from_settings)) + self._console_refresh_autoconnect_from_settings() + self.add_gsettings_handle( + self.vm.on_console_autoconnect_changed( + self._console_refresh_autoconnect_from_settings)) self.refresh_vm_state() self.activate_default_page() @@ -671,6 +676,14 @@ class vmmVMWindow(vmmGObjectUI): self._console.vmwindow_sync_resizeguest_with_display() + def _autoconnect_ui_changed_cb(self, src): + val = int(self.widget("details-menu-view-autoconnect").get_active()) + self.vm.set_console_autoconnect(val) + + def _console_refresh_autoconnect_from_settings(self): + val = self.vm.get_console_autoconnect() + self.widget("details-menu-view-autoconnect").set_active(val) + def _size_to_vm_cb(self, src): self._console.vmwindow_set_size_to_vm()