mirror of
https://github.com/virt-manager/virt-manager.git
synced 2025-02-25 18:55:27 -06:00
Allow disabling 'force poweroff' prompt.
Also allow enabling poweroff, reboot, and pause prompts. This was folks administering live servers can add extra security and be sure they don't accidentally hit a button and cause damage.
This commit is contained in:
@@ -272,5 +272,44 @@
|
||||
<long>Default path for saving screenshots from VMs</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/apps/::PACKAGE::/confirm/forcepoweroff</key>
|
||||
<applyto>/apps/::PACKAGE::/confirm/forcepoweroff</applyto>
|
||||
<owner>::PACKAGE::</owner>
|
||||
<type>bool</type>
|
||||
<default>1</default>
|
||||
|
||||
<locale name="C">
|
||||
<short>Confirm force poweroff request</short>
|
||||
<long>Whether we require confirmation to forcepoweroff a VM</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/apps/::PACKAGE::/confirm/poweroff</key>
|
||||
<applyto>/apps/::PACKAGE::/confirm/poweroff</applyto>
|
||||
<owner>::PACKAGE::</owner>
|
||||
<type>bool</type>
|
||||
<default>0</default>
|
||||
|
||||
<locale name="C">
|
||||
<short>Confirm poweroff request</short>
|
||||
<long>Whether we require confirmation to poweroff/reboot a VM</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/apps/::PACKAGE::/confirm/pause</key>
|
||||
<applyto>/apps/::PACKAGE::/confirm/pause</applyto>
|
||||
<owner>::PACKAGE::</owner>
|
||||
<type>bool</type>
|
||||
<default>0</default>
|
||||
|
||||
<locale name="C">
|
||||
<short>Confirm pause request</short>
|
||||
<long>Whether we require confirmation to pause a VM</long>
|
||||
</locale>
|
||||
</schema>
|
||||
</schemalist>
|
||||
</gconfschemafile>
|
||||
|
||||
@@ -287,6 +287,29 @@ class vmmConfig:
|
||||
cb)
|
||||
|
||||
|
||||
# Confirmation preferences
|
||||
def get_confirm_forcepoweroff(self):
|
||||
return self.conf.get_bool(self.conf_dir + "/confirm/forcepoweroff")
|
||||
def get_confirm_poweroff(self):
|
||||
return self.conf.get_bool(self.conf_dir + "/confirm/poweroff")
|
||||
def get_confirm_pause(self):
|
||||
return self.conf.get_bool(self.conf_dir + "/confirm/pause")
|
||||
|
||||
def set_confirm_forcepoweroff(self, val):
|
||||
self.conf.set_bool(self.conf_dir + "/confirm/forcepoweroff", val)
|
||||
def set_confirm_poweroff(self, val):
|
||||
self.conf.set_bool(self.conf_dir + "/confirm/poweroff", val)
|
||||
def set_confirm_pause(self, val):
|
||||
self.conf.set_bool(self.conf_dir + "/confirm/pause", val)
|
||||
|
||||
def on_confirm_forcepoweroff_changed(self, cb):
|
||||
self.conf.notify_add(self.conf_dir + "/confirm/forcepoweroff", cb)
|
||||
def on_confirm_poweroff_changed(self, cb):
|
||||
self.conf.notify_add(self.conf_dir + "/confirm/poweroff", cb)
|
||||
def on_confirm_pause_changed(self, cb):
|
||||
self.conf.notify_add(self.conf_dir + "/confirm/pause", cb)
|
||||
|
||||
|
||||
# System tray visibility
|
||||
def on_view_system_tray_changed(self, callback):
|
||||
self.conf.notify_add(self.conf_dir + "/system-tray", callback)
|
||||
|
||||
@@ -517,14 +517,21 @@ class vmmEngine(gobject.GObject):
|
||||
def destroy_domain(self, src, uri, uuid):
|
||||
conn = self._lookup_connection(uri)
|
||||
vm = conn.get_vm(uuid)
|
||||
do_prompt = self.config.get_confirm_forcepoweroff()
|
||||
|
||||
resp = self.err.yes_no(text1=_("About to poweroff virtual "
|
||||
"machine %s" % vm.get_name()),
|
||||
text2=_("This will immediately poweroff the VM "
|
||||
"without shutting down the OS and may "
|
||||
"cause data loss. Are you sure?"))
|
||||
if not resp:
|
||||
return
|
||||
if do_prompt:
|
||||
res = self.err.warn_chkbox(
|
||||
text1=(_("Are you sure you want to force poweroff '%s'?") %
|
||||
vm.get_name()),
|
||||
text2=_("This will immediately poweroff the VM without "
|
||||
"shutting down the OS and may cause data loss."),
|
||||
chktext=_("Don't ask me again."),
|
||||
buttons=gtk.BUTTONS_YES_NO)
|
||||
|
||||
response, skip_prompt = res
|
||||
if not response:
|
||||
return
|
||||
self.config.set_confirm_forcepoweroff(not skip_prompt)
|
||||
|
||||
logging.debug("Destroying vm '%s'." % vm.get_name())
|
||||
try:
|
||||
@@ -536,6 +543,19 @@ class vmmEngine(gobject.GObject):
|
||||
def suspend_domain(self, src, uri, uuid):
|
||||
conn = self._lookup_connection(uri)
|
||||
vm = conn.get_vm(uuid)
|
||||
do_prompt = self.config.get_confirm_pause()
|
||||
|
||||
if do_prompt:
|
||||
res = self.err.warn_chkbox(
|
||||
text1=_("Are you sure you want to pause "
|
||||
"'%s'?" % vm.get_name()),
|
||||
chktext=_("Don't ask me again."),
|
||||
buttons=gtk.BUTTONS_YES_NO)
|
||||
|
||||
response, skip_prompt = res
|
||||
if not response:
|
||||
return
|
||||
self.config.set_confirm_pause(not skip_prompt)
|
||||
|
||||
logging.debug("Pausing vm '%s'." % vm.get_name())
|
||||
try:
|
||||
@@ -569,6 +589,19 @@ class vmmEngine(gobject.GObject):
|
||||
def shutdown_domain(self, src, uri, uuid):
|
||||
conn = self._lookup_connection(uri)
|
||||
vm = conn.get_vm(uuid)
|
||||
do_prompt = self.config.get_confirm_poweroff()
|
||||
|
||||
if do_prompt:
|
||||
res = self.err.warn_chkbox(
|
||||
text1=_("Are you sure you want to poweroff "
|
||||
"'%s'?" % vm.get_name()),
|
||||
chktext=_("Don't ask me again."),
|
||||
buttons=gtk.BUTTONS_YES_NO)
|
||||
|
||||
response, skip_prompt = res
|
||||
if not response:
|
||||
return
|
||||
self.config.set_confirm_poweroff(not skip_prompt)
|
||||
|
||||
logging.debug("Shutting down vm '%s'." % vm.get_name())
|
||||
try:
|
||||
@@ -580,6 +613,19 @@ class vmmEngine(gobject.GObject):
|
||||
def reboot_domain(self, src, uri, uuid):
|
||||
conn = self._lookup_connection(uri)
|
||||
vm = conn.get_vm(uuid)
|
||||
do_prompt = self.config.get_confirm_poweroff()
|
||||
|
||||
if do_prompt:
|
||||
res = self.err.warn_chkbox(
|
||||
text1=_("Are you sure you want to reboot "
|
||||
"'%s'?" % vm.get_name()),
|
||||
chktext=_("Don't ask me again."),
|
||||
buttons=gtk.BUTTONS_YES_NO)
|
||||
|
||||
response, skip_prompt = res
|
||||
if not response:
|
||||
return
|
||||
self.config.set_confirm_poweroff(not skip_prompt)
|
||||
|
||||
logging.debug("Rebooting vm '%s'." % vm.get_name())
|
||||
try:
|
||||
|
||||
@@ -131,20 +131,22 @@ class vmmErrorDialog (gtk.MessageDialog):
|
||||
def ok_cancel(self, text1, text2=None):
|
||||
return self._show_warning(gtk.BUTTONS_OK_CANCEL, text1, text2)
|
||||
|
||||
def warn_chkbox(self, text1, text2=None, chktext=None):
|
||||
chkbox = vmmCheckDialog(self.parent, gtk.MESSAGE_WARNING)
|
||||
def warn_chkbox(self, text1, text2=None, chktext=None, buttons=None):
|
||||
chkbox = vmmCheckDialog(self.parent, gtk.MESSAGE_WARNING, buttons)
|
||||
return chkbox.show_chkbox(text1, text2, chktext)
|
||||
|
||||
def err_chkbox(self, text1, text2=None, chktext=None):
|
||||
chkbox = vmmCheckDialog(self.parent, gtk.MESSAGE_ERROR)
|
||||
def err_chkbox(self, text1, text2=None, chktext=None, buttons=None):
|
||||
chkbox = vmmCheckDialog(self.parent, gtk.MESSAGE_ERROR, buttons)
|
||||
return chkbox.show_chkbox(text1, text2, chktext)
|
||||
|
||||
class vmmCheckDialog (gtk.MessageDialog):
|
||||
def __init__ (self, parent=None, typ=gtk.MESSAGE_INFO):
|
||||
if typ == gtk.MESSAGE_WARNING:
|
||||
buttons = gtk.BUTTONS_OK_CANCEL
|
||||
else:
|
||||
buttons = gtk.BUTTONS_OK
|
||||
def __init__ (self, parent=None, typ=gtk.MESSAGE_INFO,
|
||||
buttons=None):
|
||||
if not buttons:
|
||||
if typ == gtk.MESSAGE_WARNING:
|
||||
buttons = gtk.BUTTONS_OK_CANCEL
|
||||
else:
|
||||
buttons = gtk.BUTTONS_OK
|
||||
|
||||
gtk.MessageDialog.__init__ (self, parent, 0, typ, buttons)
|
||||
|
||||
|
||||
@@ -48,6 +48,10 @@ class vmmPreferences(gobject.GObject):
|
||||
self.config.on_stats_enable_disk_poll_changed(self.refresh_disk_poll)
|
||||
self.config.on_stats_enable_net_poll_changed(self.refresh_net_poll)
|
||||
|
||||
self.config.on_confirm_forcepoweroff_changed(self.refresh_confirm_forcepoweroff)
|
||||
self.config.on_confirm_poweroff_changed(self.refresh_confirm_poweroff)
|
||||
self.config.on_confirm_pause_changed(self.refresh_confirm_pause)
|
||||
|
||||
self.refresh_view_system_tray()
|
||||
self.refresh_update_interval()
|
||||
self.refresh_history_length()
|
||||
@@ -58,6 +62,9 @@ class vmmPreferences(gobject.GObject):
|
||||
self.refresh_sound_remote()
|
||||
self.refresh_disk_poll()
|
||||
self.refresh_net_poll()
|
||||
self.refresh_confirm_forcepoweroff()
|
||||
self.refresh_confirm_poweroff()
|
||||
self.refresh_confirm_pause()
|
||||
|
||||
self.window.signal_autoconnect({
|
||||
"on_prefs_system_tray_toggled" : self.change_view_system_tray,
|
||||
@@ -73,6 +80,9 @@ class vmmPreferences(gobject.GObject):
|
||||
"on_prefs_sound_remote_toggled": self.change_remote_sound,
|
||||
"on_prefs_stats_enable_disk_toggled": self.change_disk_poll,
|
||||
"on_prefs_stats_enable_net_toggled": self.change_net_poll,
|
||||
"on_prefs_confirm_forcepoweroff_toggled": self.change_confirm_forcepoweroff,
|
||||
"on_prefs_confirm_poweroff_toggled": self.change_confirm_poweroff,
|
||||
"on_prefs_confirm_pause_toggled": self.change_confirm_pause,
|
||||
})
|
||||
|
||||
# XXX: Help docs useless/out of date
|
||||
@@ -127,6 +137,16 @@ class vmmPreferences(gobject.GObject):
|
||||
ignore4=None):
|
||||
self.window.get_widget("prefs-stats-enable-net").set_active(self.config.get_stats_enable_net_poll())
|
||||
|
||||
def refresh_confirm_forcepoweroff(self, ignore1=None, ignore2=None,
|
||||
ignore3=None, ignore4=None):
|
||||
self.window.get_widget("prefs-confirm-forcepoweroff").set_active(self.config.get_confirm_forcepoweroff())
|
||||
def refresh_confirm_poweroff(self, ignore1=None, ignore2=None,
|
||||
ignore3=None, ignore4=None):
|
||||
self.window.get_widget("prefs-confirm-poweroff").set_active(self.config.get_confirm_poweroff())
|
||||
def refresh_confirm_pause(self, ignore1=None, ignore2=None,
|
||||
ignore3=None, ignore4=None):
|
||||
self.window.get_widget("prefs-confirm-pause").set_active(self.config.get_confirm_pause())
|
||||
|
||||
def change_view_system_tray(self, src):
|
||||
self.config.set_view_system_tray(src.get_active())
|
||||
|
||||
@@ -152,6 +172,13 @@ class vmmPreferences(gobject.GObject):
|
||||
def change_net_poll(self, src):
|
||||
self.config.set_stats_enable_net_poll(src.get_active())
|
||||
|
||||
def change_confirm_forcepoweroff(self, src):
|
||||
self.config.set_confirm_forcepoweroff(src.get_active())
|
||||
def change_confirm_poweroff(self, src):
|
||||
self.config.set_confirm_poweroff(src.get_active())
|
||||
def change_confirm_pause(self, src):
|
||||
self.config.set_confirm_pause(src.get_active())
|
||||
|
||||
def show_help(self, src):
|
||||
# From the Preferences window, show the help document from
|
||||
# the Preferences page
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
<child>
|
||||
<widget class="GtkTable" id="table5">
|
||||
<property name="visible">True</property>
|
||||
<property name="n_rows">2</property>
|
||||
<property name="column_spacing">6</property>
|
||||
<property name="row_spacing">6</property>
|
||||
<child>
|
||||
@@ -51,9 +50,6 @@
|
||||
<property name="y_options">GTK_FILL</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
@@ -216,7 +212,7 @@
|
||||
<child>
|
||||
<widget class="GtkTable" id="table2">
|
||||
<property name="visible">True</property>
|
||||
<property name="n_rows">4</property>
|
||||
<property name="n_rows">2</property>
|
||||
<property name="n_columns">2</property>
|
||||
<property name="column_spacing">3</property>
|
||||
<property name="row_spacing">3</property>
|
||||
@@ -276,18 +272,6 @@
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
@@ -542,6 +526,147 @@ For all domains</property>
|
||||
<property name="type">tab</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox6">
|
||||
<property name="visible">True</property>
|
||||
<property name="border_width">12</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<widget class="GtkFrame" id="frame6">
|
||||
<property name="visible">True</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">none</property>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment1">
|
||||
<property name="visible">True</property>
|
||||
<property name="top_padding">6</property>
|
||||
<property name="left_padding">12</property>
|
||||
<child>
|
||||
<widget class="GtkTable" id="table6">
|
||||
<property name="visible">True</property>
|
||||
<property name="n_rows">3</property>
|
||||
<property name="n_columns">2</property>
|
||||
<property name="column_spacing">12</property>
|
||||
<property name="row_spacing">6</property>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label19">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">_Force Poweroff:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="mnemonic_widget">prefs-confirm-forcepoweroff</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="prefs-confirm-forcepoweroff">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_prefs_confirm_forcepoweroff_toggled"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label20">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Poweroff/_Reboot:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="mnemonic_widget">prefs-confirm-poweroff</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label21">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">_Pause:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="mnemonic_widget">prefs-confirm-pause</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="prefs-confirm-poweroff">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_prefs_confirm_poweroff_toggled"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="prefs-confirm-pause">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_prefs_confirm_pause_toggled"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label161">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes"><b>Confirmations</b></property>
|
||||
<property name="use_markup">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="type">label_item</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label18">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Feedback</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">3</property>
|
||||
<property name="tab_fill">False</property>
|
||||
<property name="type">tab</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
|
||||
Reference in New Issue
Block a user