2013-01-23 15:55:14 +01:00
#!/usr/bin/python2
2012-01-31 11:17:09 +01:00
#
# The Qubes OS Project, http://www.qubes-os.org
#
# Copyright (C) 2012 Agnieszka Kostrzewa <agnieszka.kostrzewa@gmail.com>
2017-06-26 17:54:35 +02:00
# Copyright (C) 2012 Marek Marczykowski-Górecki
# <marmarek@invisiblethingslab.com>
# Copyright (C) 2017 Wojtek Porczyk <woju@invisiblethingslab.com>
2012-01-31 11:17:09 +01:00
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
2017-11-06 21:06:30 +01:00
# You should have received a copy of the GNU Lesser General Public License along
# with this program; if not, see <http://www.gnu.org/licenses/>.
2012-01-31 11:17:09 +01:00
#
#
2017-06-26 17:54:35 +02:00
import collections
import copy
2017-06-28 13:41:10 +02:00
import os
2017-07-12 14:35:59 +02:00
import os . path
2012-01-31 11:17:09 +01:00
import subprocess
2017-07-12 14:35:59 +02:00
import sys
import threading
import time
import traceback
2017-06-26 17:54:35 +02:00
import qubesadmin
import qubesadmin . tools
2017-07-12 14:08:34 +02:00
from . import utils
2017-07-12 14:09:07 +02:00
from . import multiselectwidget
2017-07-12 14:35:59 +02:00
from . import thread_monitor
2012-01-31 11:17:09 +01:00
2017-07-12 14:09:07 +02:00
from . appmenu_select import AppmenuSelectManager
2017-06-28 12:25:28 +02:00
from . backup_utils import get_path_for_vm
2017-11-06 20:36:09 +01:00
from . import firewall
2012-01-31 11:17:09 +01:00
2017-11-06 20:36:09 +01:00
from . import ui_settingsdlg
2017-09-08 22:43:43 +02:00
from . bootfromdevice import main as bootfromdevice
2017-07-12 14:35:59 +02:00
2017-11-06 20:36:09 +01:00
class VMSettingsWindow ( ui_settingsdlg . Ui_SettingsDialog , firewall . QDialog ) :
2017-06-26 17:54:35 +02:00
tabs_indices = collections . OrderedDict ( (
( ' basic ' , 0 ) ,
( ' advanced ' , 1 ) ,
( ' firewall ' , 2 ) ,
( ' devices ' , 3 ) ,
( ' applications ' , 4 ) ,
( ' services ' , 5 ) ,
) )
def __init__ ( self , vm , qapp , init_page = " basic " , parent = None ) :
2012-01-31 11:17:09 +01:00
super ( VMSettingsWindow , self ) . __init__ ( parent )
2012-02-10 00:30:45 +01:00
self . vm = vm
2017-06-26 17:54:35 +02:00
self . qapp = qapp
2017-07-28 16:47:11 +02:00
try :
2012-03-12 12:53:07 +01:00
self . source_vm = self . vm . template
2017-07-28 16:47:11 +02:00
except AttributeError :
2012-02-10 00:30:45 +01:00
self . source_vm = self . vm
2014-02-17 00:35:45 +01:00
2012-01-31 11:17:09 +01:00
self . setupUi ( self )
2017-06-28 12:25:28 +02:00
self . setWindowTitle ( self . tr ( " Settings: {vm} " ) . format ( vm = self . vm . name ) )
2012-02-09 19:47:21 +01:00
if init_page in self . tabs_indices :
idx = self . tabs_indices [ init_page ]
assert ( idx in range ( self . tabWidget . count ( ) ) )
self . tabWidget . setCurrentIndex ( idx )
2012-01-31 11:17:09 +01:00
2017-11-06 20:36:09 +01:00
self . connect ( self . buttonBox , firewall . SIGNAL ( " accepted() " ) , self . save_and_apply )
self . connect ( self . buttonBox , firewall . SIGNAL ( " rejected() " ) , self . reject )
2012-01-31 11:17:09 +01:00
2012-02-10 00:30:45 +01:00
self . tabWidget . currentChanged . connect ( self . current_tab_changed )
2017-10-13 18:04:49 +02:00
self . tabWidget . setTabEnabled ( self . tabs_indices [ " firewall " ] ,
vm . netvm is not None and not vm . provides_network )
2012-03-08 15:40:02 +01:00
2012-02-13 13:50:30 +01:00
###### basic tab
self . __init_basic_tab__ ( )
2017-07-29 12:49:02 +02:00
self . rename_vm_button . clicked . connect ( self . rename_vm )
2017-11-03 22:20:34 +01:00
self . delete_vm_button . clicked . connect ( self . remove_vm )
2017-11-03 23:50:04 +01:00
self . clone_vm_button . clicked . connect ( self . clone_vm )
2012-02-13 13:50:30 +01:00
2012-03-12 21:08:32 +01:00
###### advanced tab
self . __init_advanced_tab__ ( )
2012-03-19 16:02:05 +01:00
self . include_in_balancing . stateChanged . connect ( self . include_in_balancing_state_changed )
2017-11-06 20:36:09 +01:00
self . connect ( self . init_mem , firewall . SIGNAL ( " editingFinished() " ) , self . check_mem_changes )
self . connect ( self . max_mem_size , firewall . SIGNAL ( " editingFinished() " ) , self . check_mem_changes )
2017-09-08 22:43:43 +02:00
self . bootFromDeviceButton . clicked . connect ( self . boot_from_cdrom_button_pressed )
2012-03-12 21:08:32 +01:00
2012-02-10 00:30:45 +01:00
###### firewall tab
2017-07-12 14:47:37 +02:00
if self . tabWidget . isTabEnabled ( self . tabs_indices [ ' firewall ' ] ) :
2017-11-06 20:36:09 +01:00
model = firewall . QubesFirewallRulesModel ( )
2017-10-13 18:04:49 +02:00
try :
model . set_vm ( vm )
self . set_fw_model ( model )
self . firewallModifiedOutsidelabel . setVisible ( False )
2017-11-06 20:36:09 +01:00
except firewall . FirewallModifiedOutsideError as ex :
2017-10-13 18:04:49 +02:00
self . disable_all_fw_conf ( )
2012-02-10 00:30:45 +01:00
2012-03-08 15:40:02 +01:00
self . newRuleButton . clicked . connect ( self . new_rule_button_pressed )
self . editRuleButton . clicked . connect ( self . edit_rule_button_pressed )
self . deleteRuleButton . clicked . connect ( self . delete_rule_button_pressed )
2014-03-28 05:19:07 +01:00
self . policyDenyRadioButton . clicked . connect ( self . policy_changed )
self . policyAllowRadioButton . clicked . connect ( self . policy_changed )
2012-02-10 00:30:45 +01:00
####### devices tab
2012-03-13 20:06:41 +01:00
self . __init_devices_tab__ ( )
2017-11-06 20:36:09 +01:00
self . connect ( self . dev_list , firewall . SIGNAL ( " selected_changed() " ) , self . devices_selection_changed )
2014-02-17 00:35:45 +01:00
2012-03-14 11:54:50 +01:00
####### services tab
self . __init_services_tab__ ( )
self . add_srv_button . clicked . connect ( self . __add_service__ )
self . remove_srv_button . clicked . connect ( self . __remove_service__ )
2012-02-10 00:30:45 +01:00
####### apps tab
2012-03-08 15:40:02 +01:00
if self . tabWidget . isTabEnabled ( self . tabs_indices [ " applications " ] ) :
2017-07-12 14:09:07 +02:00
self . app_list = multiselectwidget . MultiSelectWidget ( self )
2012-02-13 13:50:30 +01:00
self . apps_layout . addWidget ( self . app_list )
self . AppListManager = AppmenuSelectManager ( self . vm , self . app_list )
2017-07-28 16:47:11 +02:00
self . refresh_apps_button . clicked . connect ( self . refresh_apps_button_pressed )
2012-01-31 11:17:09 +01:00
def reject ( self ) :
self . done ( 0 )
2012-02-09 19:47:21 +01:00
#needed not to close the dialog before applying changes
def accept ( self ) :
2012-01-31 11:17:09 +01:00
pass
2012-02-09 19:47:21 +01:00
def save_and_apply ( self ) :
2017-07-12 14:35:59 +02:00
t_monitor = thread_monitor . ThreadMonitor ( )
thread = threading . Thread ( target = self . __save_changes__ , args = ( t_monitor , ) )
2012-02-09 19:47:21 +01:00
thread . daemon = True
thread . start ( )
2014-02-17 00:35:45 +01:00
2017-11-06 20:36:09 +01:00
progress = firewall . QProgressDialog (
2017-06-28 12:25:28 +02:00
self . tr ( " Applying settings to <b> {0} </b>... " ) . format ( self . vm . name ) , " " , 0 , 0 )
2012-02-09 19:47:21 +01:00
progress . setCancelButton ( None )
progress . setModal ( True )
progress . show ( )
2017-07-12 14:35:59 +02:00
while not t_monitor . is_finished ( ) :
2017-06-26 17:54:35 +02:00
self . qapp . processEvents ( )
2012-02-09 19:47:21 +01:00
time . sleep ( 0.1 )
progress . hide ( )
2014-02-17 00:35:45 +01:00
2017-07-12 14:35:59 +02:00
if not t_monitor . success :
2017-11-06 20:36:09 +01:00
firewall . QMessageBox . warning ( None ,
self . tr ( " Error while changing settings for {0} ! " ) . format ( self . vm . name ) ,
self . tr ( " ERROR: {0} " ) . format ( t_monitor . error_msg ) )
2012-02-09 19:47:21 +01:00
self . done ( 0 )
2017-07-12 14:35:59 +02:00
def __save_changes__ ( self , t_monitor ) :
2012-03-01 22:50:32 +01:00
2012-03-12 15:54:16 +01:00
self . anything_changed = False
2014-02-17 00:35:45 +01:00
2013-02-23 06:44:06 +01:00
ret = [ ]
try :
ret_tmp = self . __apply_basic_tab__ ( )
if len ( ret_tmp ) > 0 :
ret + = [ " Basic tab: " ] + ret_tmp
ret_tmp = self . __apply_advanced_tab__ ( )
if len ( ret_tmp ) > 0 :
ret + = [ " Advanced tab: " ] + ret_tmp
ret_tmp = self . __apply_devices_tab__ ( )
if len ( ret_tmp ) > 0 :
ret + = [ " Devices tab: " ] + ret_tmp
ret_tmp = self . __apply_services_tab__ ( )
if len ( ret_tmp ) > 0 :
ret + = [ " Sevices tab: " ] + ret_tmp
except Exception as ex :
2017-01-22 05:42:38 +01:00
ret . append ( self . tr ( ' Error while saving changes: ' ) + str ( ex ) )
2012-03-12 15:54:16 +01:00
2013-02-23 06:44:06 +01:00
try :
2017-10-13 18:04:49 +02:00
if self . policyAllowRadioButton . isEnabled ( ) :
2013-02-23 06:44:06 +01:00
self . fw_model . apply_rules ( self . policyAllowRadioButton . isChecked ( ) ,
2014-03-28 05:19:07 +01:00
self . tempFullAccess . isChecked ( ) ,
self . tempFullAccessTime . value ( ) )
2017-04-24 01:59:00 +02:00
if self . fw_model . fw_changed :
# might modified vm.services
self . anything_changed = True
2013-02-23 06:44:06 +01:00
except Exception as ex :
2017-01-22 05:42:38 +01:00
ret + = [ self . tr ( " Firewall tab: " ) , str ( ex ) ]
2013-02-23 06:44:06 +01:00
try :
if self . tabWidget . isTabEnabled ( self . tabs_indices [ " applications " ] ) :
self . AppListManager . save_appmenu_select_changes ( )
except Exception as ex :
2017-01-22 05:42:38 +01:00
ret + = [ self . tr ( " Applications tab: " ) , str ( ex ) ]
2012-03-12 15:54:16 +01:00
2013-02-23 06:44:06 +01:00
if len ( ret ) > 0 :
2017-07-12 14:35:59 +02:00
t_monitor . set_error_msg ( ' \n ' . join ( ret ) )
2012-03-01 22:50:32 +01:00
2017-07-12 14:08:34 +02:00
utils . debug ( ' \n ' . join ( ret ) )
2012-02-09 19:47:21 +01:00
2017-07-12 14:35:59 +02:00
t_monitor . set_finished ( )
2012-03-01 22:50:32 +01:00
2012-02-10 00:30:45 +01:00
def current_tab_changed ( self , idx ) :
if idx == self . tabs_indices [ " firewall " ] :
2017-07-16 10:50:07 +02:00
netvm = self . vm . netvm
if netvm is not None and \
not netvm . features . check_with_template ( ' qubes-firewall ' , False ) :
2017-11-06 20:36:09 +01:00
firewall . QMessageBox . warning ( None ,
self . tr ( " VM configuration problem! " ) ,
self . tr ( " The ' {vm} ' AppVM is network connected to "
2017-07-16 10:50:07 +02:00
" ' {netvm} ' , which does not support firewall!<br/> "
" You may edit the ' {vm} ' VM firewall rules, but these "
" will not take any effect until you connect it to "
" a working Firewall VM. " ) . format (
vm = self . vm . name , netvm = netvm . name ) )
2012-02-10 00:30:45 +01:00
2012-02-13 13:50:30 +01:00
######### basic tab
2017-06-26 17:54:35 +02:00
# TODO LISTENERS
2017-07-12 14:08:34 +02:00
# - vm start/shutdown -> setEnabled on fields: template labels
2017-06-26 17:54:35 +02:00
# - vm create/delete -> choices lists, whole window deactiv (if self.vm)
# - property-set -> individual fields
# TODO INTERACTIONS
# netvm -> networking_groupbox
# hvm -> include_in_balancing
2017-07-12 14:08:34 +02:00
# TODO REMOVE
# other_groupbox
2017-06-26 17:54:35 +02:00
2012-02-13 13:50:30 +01:00
def __init_basic_tab__ ( self ) :
self . vmname . setText ( self . vm . name )
2017-11-06 20:36:09 +01:00
self . vmname . setValidator ( firewall . QRegExpValidator ( firewall . QRegExp ( " [a-zA-Z0-9-]* " , firewall . Qt . CaseInsensitive ) , None ) )
2017-06-26 17:54:35 +02:00
self . vmname . setEnabled ( False )
2017-07-29 12:49:02 +02:00
self . rename_vm_button . setEnabled ( not self . vm . is_running ( ) )
2017-11-03 22:20:34 +01:00
self . delete_vm_button . setEnabled ( not self . vm . is_running ( ) )
if self . vm . is_running ( ) :
self . delete_vm_button . setText ( self . tr ( ' Delete VM '
' (cannot delete a running VM) ' ) )
2014-02-17 00:35:45 +01:00
2012-04-27 11:54:53 +02:00
if self . vm . qid == 0 :
self . vmlabel . setVisible ( False )
2014-02-17 00:35:45 +01:00
else :
2017-07-12 14:08:34 +02:00
self . label_list , self . label_idx = utils . prepare_label_choice (
self . vmlabel ,
self . vm , ' label ' ,
None ,
allow_default = False
)
2012-04-27 11:54:53 +02:00
self . vmlabel . setVisible ( True )
2017-07-12 14:08:34 +02:00
self . vmlabel . setEnabled ( not self . vm . is_running ( ) )
2012-02-13 13:50:30 +01:00
2017-10-07 00:22:41 +02:00
if self . vm . klass == ' AppVM ' :
2017-07-12 14:08:34 +02:00
self . template_list , self . template_idx = utils . prepare_vm_choice (
self . template_name ,
self . vm , ' template ' ,
self . vm . app . default_template ,
2017-10-07 00:22:41 +02:00
( lambda vm : vm . klass == ' TemplateVM ' ) ,
2017-07-12 14:08:34 +02:00
allow_default = True , allow_none = False )
2012-02-13 13:50:30 +01:00
else :
self . template_name . setEnabled ( False )
2012-03-12 21:08:32 +01:00
self . template_idx = - 1
2012-02-13 13:50:30 +01:00
2017-07-12 14:08:34 +02:00
self . netvm_list , self . netvm_idx = utils . prepare_vm_choice (
self . netVM ,
self . vm , ' netvm ' ,
self . vm . app . default_netvm ,
( lambda vm : vm . provides_network ) ,
allow_default = True , allow_none = True )
2012-02-13 13:50:30 +01:00
2012-03-07 20:42:18 +01:00
self . include_in_backups . setChecked ( self . vm . include_in_backups )
2017-06-26 17:54:35 +02:00
try :
2012-04-24 14:27:28 +02:00
self . run_in_debug_mode . setChecked ( self . vm . debug )
2017-06-26 17:54:35 +02:00
self . run_in_debug_mode . setVisible ( True )
except AttributeError :
2012-04-24 14:27:28 +02:00
self . run_in_debug_mode . setVisible ( False )
2017-06-26 17:54:35 +02:00
try :
2014-05-17 19:21:00 +02:00
self . autostart_vm . setChecked ( self . vm . autostart )
2017-06-26 17:54:35 +02:00
self . autostart_vm . setVisible ( True )
except AttributeError :
2014-05-17 19:21:00 +02:00
self . autostart_vm . setVisible ( False )
2012-03-07 20:42:18 +01:00
#type
2017-10-16 03:10:19 +02:00
self . type_label . setText ( self . vm . klass )
2012-03-07 20:42:18 +01:00
#installed by rpm
2017-06-26 17:54:35 +02:00
self . rpm_label . setText ( ' Yes ' if self . vm . installed_by_rpm else ' No ' )
2012-03-07 20:42:18 +01:00
2012-03-09 08:43:42 +01:00
#networking info
2017-06-26 17:54:35 +02:00
if self . vm . netvm :
2014-02-23 00:44:08 +01:00
self . networking_groupbox . setEnabled ( True )
2017-07-12 14:47:37 +02:00
self . ip_label . setText ( self . vm . ip or " none " )
self . netmask_label . setText ( self . vm . visible_netmask or " none " )
self . gateway_label . setText ( self . vm . visible_gateway or " none " )
2012-03-09 08:43:42 +01:00
else :
2014-02-23 00:44:08 +01:00
self . networking_groupbox . setEnabled ( False )
2012-03-09 08:43:42 +01:00
2012-03-14 12:51:11 +01:00
#max priv storage
2017-07-30 18:56:35 +02:00
self . priv_img_size = self . vm . volumes [ ' private ' ] . size / / 1024 * * 2
2017-07-12 14:50:40 +02:00
self . max_priv_storage . setMinimum ( self . priv_img_size )
self . max_priv_storage . setValue ( self . priv_img_size )
2012-03-09 08:43:42 +01:00
2017-07-30 18:56:35 +02:00
self . root_img_size = self . vm . volumes [ ' root ' ] . size / / 1024 * * 2
2017-07-12 14:50:40 +02:00
self . root_resize . setValue ( self . root_img_size )
self . root_resize . setMinimum ( self . root_img_size )
2017-07-30 18:56:35 +02:00
self . root_resize . setEnabled ( self . vm . volumes [ ' root ' ] . save_on_stop )
2017-07-12 14:50:40 +02:00
self . root_resize_label . setEnabled ( self . root_resize . isEnabled ( ) )
2012-02-13 13:50:30 +01:00
def __apply_basic_tab__ ( self ) :
msg = [ ]
#vm label changed
2013-02-23 06:44:06 +01:00
try :
if self . vmlabel . isVisible ( ) :
if self . vmlabel . currentIndex ( ) != self . label_idx :
label = self . label_list [ self . vmlabel . currentIndex ( ) ]
self . vm . label = label
self . anything_changed = True
except Exception as ex :
msg . append ( str ( ex ) )
2012-02-13 13:50:30 +01:00
2012-03-07 17:03:19 +01:00
#vm template changed
2013-02-23 06:44:06 +01:00
try :
if self . template_name . currentIndex ( ) != self . template_idx :
2017-06-26 17:54:35 +02:00
self . vm . template = \
self . template_list [ self . template_name . currentIndex ( ) ]
2013-02-23 06:44:06 +01:00
self . anything_changed = True
except Exception as ex :
msg . append ( str ( ex ) )
2012-02-13 13:50:30 +01:00
2012-03-07 18:15:59 +01:00
#vm netvm changed
2013-02-23 06:44:06 +01:00
try :
if self . netVM . currentIndex ( ) != self . netvm_idx :
2017-06-26 17:54:35 +02:00
self . vm . netvm = self . netvm_list [ self . netVM . currentIndex ( ) ]
2013-02-23 06:44:06 +01:00
self . anything_changed = True
except Exception as ex :
msg . append ( str ( ex ) )
2012-03-07 20:42:18 +01:00
#include in backups
2013-02-23 06:44:06 +01:00
try :
if self . vm . include_in_backups != self . include_in_backups . isChecked ( ) :
self . vm . include_in_backups = self . include_in_backups . isChecked ( )
self . anything_changed = True
except Exception as ex :
msg . append ( str ( ex ) )
2012-04-24 14:27:28 +02:00
#run_in_debug_mode
2013-02-23 06:44:06 +01:00
try :
if self . run_in_debug_mode . isVisible ( ) :
if self . vm . debug != self . run_in_debug_mode . isChecked ( ) :
self . vm . debug = self . run_in_debug_mode . isChecked ( )
self . anything_changed = True
except Exception as ex :
msg . append ( str ( ex ) )
2012-03-07 18:15:59 +01:00
2014-05-17 19:21:00 +02:00
#autostart_vm
try :
if self . autostart_vm . isVisible ( ) :
if self . vm . autostart != self . autostart_vm . isChecked ( ) :
self . vm . autostart = self . autostart_vm . isChecked ( )
self . anything_changed = True
except Exception as ex :
msg . append ( str ( ex ) )
2012-03-14 12:51:11 +01:00
#max priv storage
priv_size = self . max_priv_storage . value ( )
if self . priv_img_size != priv_size :
try :
2017-07-30 18:56:35 +02:00
self . vm . volumes [ ' private ' ] . resize ( priv_size * 1024 * * 2 )
2012-03-14 12:51:11 +01:00
self . anything_changed = True
except Exception as ex :
msg . append ( str ( ex ) )
2014-03-21 18:40:23 +01:00
#max sys storage
sys_size = self . root_resize . value ( )
if self . root_img_size != sys_size :
try :
2017-10-08 16:57:08 +02:00
self . vm . volumes [ ' root ' ] . resize ( sys_size * 1024 * * 2 )
2014-03-21 18:40:23 +01:00
self . anything_changed = True
except Exception as ex :
msg . append ( str ( ex ) )
2012-03-07 21:21:14 +01:00
2012-03-07 18:15:59 +01:00
return msg
2012-03-12 21:08:32 +01:00
2014-09-16 21:25:52 +02:00
def check_mem_changes ( self ) :
2013-10-29 13:41:46 +01:00
if self . max_mem_size . value ( ) < self . init_mem . value ( ) :
2017-11-06 20:36:09 +01:00
firewall . QMessageBox . warning ( None ,
self . tr ( " Warning! " ) ,
self . tr ( " Max memory can not be less than initial memory.<br> "
2017-01-22 05:42:38 +01:00
" Setting max memory to equal initial memory. " ) )
2013-10-29 13:41:46 +01:00
self . max_mem_size . setValue ( self . init_mem . value ( ) )
2014-09-16 21:25:52 +02:00
# Linux specific limit: init memory must not be below max_mem_size/10.79 in order to allow scaling up to max_mem_size (or else "add_memory() failed: -17" problem)
if self . init_mem . value ( ) * 10 < self . max_mem_size . value ( ) :
2017-11-06 20:36:09 +01:00
firewall . QMessageBox . warning ( None ,
self . tr ( " Warning! " ) ,
self . tr ( " Initial memory can not be less than one tenth "
2017-01-22 05:42:38 +01:00
" Max memory.<br>Setting initial memory to the minimum "
" allowed value. " ) )
2014-09-16 21:25:52 +02:00
self . init_mem . setValue ( self . max_mem_size . value ( ) / 10 )
2017-11-03 23:50:04 +01:00
def _run_in_thread ( self , func , * args ) :
t_monitor = thread_monitor . ThreadMonitor ( )
thread = threading . Thread ( target = func , args = ( t_monitor , * args , ) )
thread . daemon = True
thread . start ( )
while not t_monitor . is_finished ( ) :
self . qapp . processEvents ( )
time . sleep ( 0.1 )
if not t_monitor . success :
2017-11-06 20:36:09 +01:00
firewall . QMessageBox . warning ( None ,
self . tr ( " Error! " ) ,
self . tr ( " ERROR: {} " ) . format (
2017-11-03 23:50:04 +01:00
t_monitor . error_msg ) )
2017-07-29 12:49:02 +02:00
def _rename_vm ( self , t_monitor , name ) :
try :
self . vm . app . clone_vm ( self . vm , name )
del self . vm . app . domains [ self . vm . name ]
except Exception as ex :
t_monitor . set_error_msg ( str ( ex ) )
t_monitor . set_finished ( )
def rename_vm ( self ) :
2017-11-06 20:36:09 +01:00
new_vm_name , ok = firewall . QInputDialog . getText ( self ,
self . tr ( ' Rename VM ' ) ,
self . tr ( ' New name: (WARNING: '
2017-11-03 23:50:04 +01:00
' all other changes will be discarded) ' ) )
2017-07-29 12:49:02 +02:00
if ok :
2017-11-03 23:50:04 +01:00
self . _run_in_thread ( self . _rename_vm , new_vm_name )
2017-07-29 12:49:02 +02:00
self . done ( 0 )
2012-05-19 09:33:29 +02:00
2017-11-03 22:20:34 +01:00
def _remove_vm ( self , t_monitor ) :
try :
del self . vm . app . domains [ self . vm . name ]
except Exception as ex :
t_monitor . set_error_msg ( str ( ex ) )
t_monitor . set_finished ( )
def remove_vm ( self ) :
2017-11-06 20:36:09 +01:00
answer , ok = firewall . QInputDialog . getText (
2017-11-06 19:45:36 +01:00
self ,
self . tr ( ' Delete VM ' ) ,
self . tr ( ' Are you absolutely sure you want to delete this VM? '
' <br/> All VM settings and data will be irrevocably '
' deleted. <br/> If you are sure, please enter this '
2017-11-03 22:20:34 +01:00
' VM \' s name below. ' ) )
if ok and answer == self . vm . name :
2017-11-03 23:50:04 +01:00
self . _run_in_thread ( self . _remove_vm )
2017-11-03 22:20:34 +01:00
self . done ( 0 )
2017-11-06 19:45:36 +01:00
elif ok :
2017-11-06 20:36:09 +01:00
firewall . QMessageBox . warning (
2017-11-06 19:45:36 +01:00
None ,
self . tr ( " Removal cancelled " ) ,
self . tr ( " The VM will not be removed. " ) )
2017-11-03 22:20:34 +01:00
2017-11-03 23:50:04 +01:00
def _clone_vm ( self , t_monitor , name ) :
try :
self . vm . app . clone_vm ( self . vm , name )
except Exception as ex :
t_monitor . set_error_msg ( str ( ex ) )
t_monitor . set_finished ( )
def clone_vm ( self ) :
2017-11-06 20:36:09 +01:00
cloned_vm_name , ok = firewall . QInputDialog . getText (
2017-11-06 19:45:36 +01:00
self ,
self . tr ( ' Clone VM ' ) ,
self . tr ( ' Name for the cloned VM: ' ) )
2017-11-03 23:50:04 +01:00
if ok :
self . _run_in_thread ( self . _clone_vm , cloned_vm_name )
2017-11-06 20:36:09 +01:00
firewall . QMessageBox . warning (
2017-11-06 19:45:36 +01:00
None ,
self . tr ( " Success " ) ,
self . tr ( " The VM was cloned successfully. " ) )
2017-11-03 23:50:04 +01:00
2012-03-12 21:08:32 +01:00
######### advanced tab
def __init_advanced_tab__ ( self ) :
2012-03-13 22:05:50 +01:00
#mem/cpu
2017-06-26 17:54:35 +02:00
# qubes_memory = QubesHost().memory_total/1024
2012-05-19 09:33:29 +02:00
2012-03-14 12:51:11 +01:00
self . init_mem . setValue ( int ( self . vm . memory ) )
2017-06-26 17:54:35 +02:00
# self.init_mem.setMaximum(qubes_memory)
2012-03-13 22:05:50 +01:00
self . max_mem_size . setValue ( int ( self . vm . maxmem ) )
2017-06-26 17:54:35 +02:00
# self.max_mem_size.setMaximum(qubes_memory)
2012-03-13 22:05:50 +01:00
2014-02-23 00:44:08 +01:00
self . vcpus . setMinimum ( 1 )
2017-06-26 17:54:35 +02:00
# self.vcpus.setMaximum(QubesHost().no_cpus)
2012-03-13 22:05:50 +01:00
self . vcpus . setValue ( int ( self . vm . vcpus ) )
2017-07-14 02:19:24 +02:00
self . include_in_balancing . setEnabled ( True )
self . include_in_balancing . setChecked (
2017-10-16 03:10:47 +02:00
bool ( self . vm . features . get ( ' service.meminfo-writer ' , True ) ) )
2013-10-29 13:41:46 +01:00
self . max_mem_size . setEnabled ( self . include_in_balancing . isChecked ( ) )
2012-04-18 19:33:53 +02:00
2012-04-24 15:02:19 +02:00
#in case VM is HVM
2017-07-12 14:08:34 +02:00
if hasattr ( self . vm , " kernel " ) :
2014-02-17 00:40:28 +01:00
self . kernel_groupbox . setVisible ( True )
2017-07-12 14:08:34 +02:00
self . kernel_list , self . kernel_idx = utils . prepare_kernel_choice (
self . kernel , self . vm , ' kernel ' ,
self . vm . app . default_kernel ,
allow_default = True , allow_none = True )
else :
self . kernel_groupbox . setVisible ( False )
2012-03-12 21:08:32 +01:00
2017-07-12 14:47:37 +02:00
self . other_groupbox . setVisible ( False )
2017-07-14 02:19:24 +02:00
if not hasattr ( self . vm , ' default_dispvm ' ) :
self . other_groupbox . setVisible ( False )
else :
self . other_groupbox . setVisible ( True )
self . default_dispvm_list , self . default_dispvm_idx = \
utils . prepare_vm_choice (
self . default_dispvm ,
self . vm , ' default_dispvm ' ,
self . vm . app . default_dispvm ,
2017-10-07 00:22:41 +02:00
( lambda vm : vm . klass == ' DispVM ' ) ,
2017-07-14 02:19:24 +02:00
allow_default = True , allow_none = True )
2015-04-06 00:59:15 +02:00
2012-03-12 21:08:32 +01:00
def __apply_advanced_tab__ ( self ) :
2013-02-23 06:44:06 +01:00
msg = [ ]
2012-03-12 21:08:32 +01:00
2012-03-13 22:05:50 +01:00
#mem/cpu
2013-02-23 06:44:06 +01:00
try :
if self . init_mem . value ( ) != int ( self . vm . memory ) :
self . vm . memory = self . init_mem . value ( )
self . anything_changed = True
2012-03-14 12:51:11 +01:00
2013-02-23 06:44:06 +01:00
if self . max_mem_size . value ( ) != int ( self . vm . maxmem ) :
self . vm . maxmem = self . max_mem_size . value ( )
self . anything_changed = True
2012-03-13 22:05:50 +01:00
2013-02-23 06:44:06 +01:00
if self . vcpus . value ( ) != int ( self . vm . vcpus ) :
self . vm . vcpus = self . vcpus . value ( )
self . anything_changed = True
except Exception as ex :
msg . append ( str ( ex ) )
2012-03-13 22:05:50 +01:00
2012-03-30 21:46:23 +02:00
#include_in_memory_balancing applied in services tab
2012-04-18 19:33:53 +02:00
#in case VM is not Linux
2014-02-17 00:40:28 +01:00
if hasattr ( self . vm , " kernel " ) and self . kernel_groupbox . isVisible ( ) :
try :
if self . kernel . currentIndex ( ) != self . kernel_idx :
2017-10-07 00:23:37 +02:00
self . vm . kernel = self . kernel_list [ self . kernel . currentIndex ( ) ]
2014-02-17 00:40:28 +01:00
self . anything_changed = True
except Exception as ex :
msg . append ( str ( ex ) )
2013-02-23 06:44:06 +01:00
2017-07-14 02:19:24 +02:00
#vm default_dispvm changed
try :
if self . default_dispvm . currentIndex ( ) != self . default_dispvm_idx :
self . vm . default_dispvm = \
self . default_dispvm_list [ self . default_dispvm . currentIndex ( ) ]
self . anything_changed = True
except Exception as ex :
msg . append ( str ( ex ) )
2013-02-23 06:44:06 +01:00
return msg
2012-03-12 21:08:32 +01:00
2017-09-08 22:43:43 +02:00
def boot_from_cdrom_button_pressed ( self ) :
self . save_and_apply ( )
subprocess . check_call ( [ ' qubes-vm-boot-from-device ' , self . vm . name ] )
2012-03-13 20:06:41 +01:00
######## devices tab
def __init_devices_tab__ ( self ) :
2017-07-12 14:52:56 +02:00
self . dev_list = multiselectwidget . MultiSelectWidget ( self )
2014-11-01 19:57:17 +01:00
self . dev_list . add_all_button . setVisible ( False )
2012-03-13 20:06:41 +01:00
self . devices_layout . addWidget ( self . dev_list )
2014-02-17 00:35:45 +01:00
2012-03-13 20:06:41 +01:00
devs = [ ]
2017-07-12 14:52:56 +02:00
lspci = subprocess . check_output ( [ ' /usr/sbin/lspci ' ] ) . decode ( )
for dev in lspci . splitlines ( ) :
devs . append ( ( dev . rstrip ( ) , dev . split ( ' ' ) [ 0 ] ) )
2012-03-13 20:06:41 +01:00
2017-11-06 20:36:09 +01:00
class DevListWidgetItem ( firewall . QListWidgetItem ) :
2017-07-12 14:52:56 +02:00
def __init__ ( self , name , ident , parent = None ) :
2012-03-13 20:06:41 +01:00
super ( DevListWidgetItem , self ) . __init__ ( name , parent )
2017-07-12 14:52:56 +02:00
self . ident = ident
2014-11-01 19:57:17 +01:00
self . Type
2012-03-13 20:06:41 +01:00
2017-07-12 14:52:56 +02:00
persistent = [ ass . ident . replace ( ' _ ' , ' : ' )
for ass in self . vm . devices [ ' pci ' ] . persistent ( ) ]
for name , ident in devs :
if ident in persistent :
self . dev_list . selected_list . addItem (
DevListWidgetItem ( name , ident ) )
2012-03-13 20:06:41 +01:00
else :
2017-07-12 14:52:56 +02:00
self . dev_list . available_list . addItem (
DevListWidgetItem ( name , ident ) )
2012-03-13 20:06:41 +01:00
2012-03-19 21:07:27 +01:00
if self . dev_list . selected_list . count ( ) > 0 and self . include_in_balancing . isChecked ( ) :
self . dmm_warning_adv . show ( )
self . dmm_warning_dev . show ( )
else :
self . dmm_warning_adv . hide ( )
self . dmm_warning_dev . hide ( )
2012-04-17 13:15:18 +02:00
if self . vm . is_running ( ) :
self . dev_list . setEnabled ( False )
self . turn_off_vm_to_modify_devs . setVisible ( True )
else :
self . dev_list . setEnabled ( True )
self . turn_off_vm_to_modify_devs . setVisible ( False )
2012-03-13 20:06:41 +01:00
def __apply_devices_tab__ ( self ) :
2013-02-23 06:44:06 +01:00
msg = [ ]
2012-03-13 20:06:41 +01:00
2013-02-23 06:44:06 +01:00
try :
2017-07-12 14:52:56 +02:00
old = [ ass . ident . replace ( ' _ ' , ' : ' )
for ass in self . vm . devices [ ' pci ' ] . persistent ( ) ]
new = [ self . dev_list . selected_list . item ( i ) . ident
for i in range ( self . dev_list . selected_list . count ( ) ) ]
for ident in new :
if ident not in old :
2017-11-06 20:36:09 +01:00
ass = firewall . qubesadmin . devices . DeviceAssignment (
2017-07-12 14:52:56 +02:00
self . vm . app . domains [ ' dom0 ' ] ,
ident . replace ( ' : ' , ' _ ' ) ,
persistent = True )
self . vm . devices [ ' pci ' ] . attach ( ass )
for ass in self . vm . devices [ ' pci ' ] . assignments ( persistent = True ) :
if ass . ident . replace ( ' _ ' , ' : ' ) not in new :
self . vm . devices [ ' pci ' ] . detach ( ass )
self . anything_changed = True
2013-02-23 06:44:06 +01:00
except Exception as ex :
2017-07-12 14:08:34 +02:00
if utils . is_debug ( ) :
traceback . print_exc ( )
2013-02-23 06:44:06 +01:00
msg . append ( str ( ex ) )
return msg
2012-03-13 20:06:41 +01:00
2012-03-19 16:02:05 +01:00
def include_in_balancing_state_changed ( self , state ) :
2012-03-30 21:46:23 +02:00
for r in range ( self . services_list . count ( ) ) :
item = self . services_list . item ( r )
if str ( item . text ( ) ) == ' meminfo-writer ' :
item . setCheckState ( state )
2014-02-23 00:44:08 +01:00
break
2012-03-30 21:46:23 +02:00
2012-03-19 21:07:27 +01:00
if self . dev_list . selected_list . count ( ) > 0 :
2017-11-06 20:36:09 +01:00
if state == ui_settingsdlg . QtCore . Qt . Checked :
2012-03-19 21:07:27 +01:00
self . dmm_warning_adv . show ( )
self . dmm_warning_dev . show ( )
else :
self . dmm_warning_adv . hide ( )
self . dmm_warning_dev . hide ( )
2013-10-29 13:39:14 +01:00
self . max_mem_size . setEnabled ( self . include_in_balancing . isChecked ( ) )
2012-03-30 21:46:23 +02:00
2012-03-19 16:02:05 +01:00
def devices_selection_changed ( self ) :
2012-03-19 21:07:27 +01:00
if self . include_in_balancing . isChecked ( ) :
if self . dev_list . selected_list . count ( ) > 0 :
self . dmm_warning_adv . show ( )
self . dmm_warning_dev . show ( )
else :
self . dmm_warning_adv . hide ( )
self . dmm_warning_dev . hide ( )
2012-03-14 11:54:50 +01:00
2017-07-28 16:47:11 +02:00
######## applications tab
def refresh_apps_in_vm ( self , t_monitor ) :
try :
target_vm = self . vm . template
except AttributeError :
target_vm = self . vm
if not target_vm . is_running ( ) :
not_running = True
target_vm . start ( )
else :
not_running = False
subprocess . check_call ( [ ' qvm-sync-appmenus ' , target_vm . name ] )
if not_running :
target_vm . shutdown ( )
t_monitor . set_finished ( )
def refresh_apps_button_pressed ( self ) :
self . refresh_apps_button . setEnabled ( False )
self . refresh_apps_button . setText ( self . tr ( ' Refresh in progress... ' ) )
t_monitor = thread_monitor . ThreadMonitor ( )
thread = threading . Thread ( target = self . refresh_apps_in_vm , args = ( t_monitor , ) )
thread . daemon = True
thread . start ( )
while not t_monitor . is_finished ( ) :
self . qapp . processEvents ( )
time . sleep ( 0.1 )
self . AppListManager = AppmenuSelectManager ( self . vm , self . app_list )
self . refresh_apps_button . setEnabled ( True )
self . refresh_apps_button . setText ( self . tr ( ' Refresh Applications ' ) )
2012-03-14 11:54:50 +01:00
######## services tab
def __init_services_tab__ ( self ) :
2017-07-12 14:52:05 +02:00
self . new_srv_dict = { }
for feature in self . vm . features :
if not feature . startswith ( ' service. ' ) :
continue
service = feature [ len ( ' service. ' ) : ]
2017-11-06 20:36:09 +01:00
item = firewall . QListWidgetItem ( service )
item . setCheckState ( ui_settingsdlg . QtCore . Qt . Checked
if self . vm . features [ feature ] else ui_settingsdlg . QtCore . Qt . Unchecked )
2012-03-14 11:54:50 +01:00
self . services_list . addItem ( item )
2017-07-12 14:52:05 +02:00
self . new_srv_dict [ service ] = self . vm . features [ feature ]
2013-02-23 06:44:06 +01:00
2017-11-06 20:36:09 +01:00
self . connect ( self . services_list , firewall . SIGNAL ( " itemClicked(QListWidgetItem *) " ) , self . services_item_clicked )
2012-03-14 11:54:50 +01:00
def __add_service__ ( self ) :
srv = str ( self . service_line_edit . text ( ) ) . strip ( )
2012-03-30 21:46:23 +02:00
if srv != " " :
if srv in self . new_srv_dict :
2017-11-06 20:36:09 +01:00
firewall . QMessageBox . information ( None , ' ' ,
self . tr ( ' Service already on the list! ' ) )
2012-03-30 21:46:23 +02:00
else :
2017-11-06 20:36:09 +01:00
item = firewall . QListWidgetItem ( srv )
item . setCheckState ( ui_settingsdlg . QtCore . Qt . Checked )
2012-03-30 21:46:23 +02:00
self . services_list . addItem ( item )
self . new_srv_dict [ srv ] = True
2012-03-14 11:54:50 +01:00
def __remove_service__ ( self ) :
2012-03-30 21:46:23 +02:00
item = self . services_list . currentItem ( )
2014-09-04 21:59:05 +02:00
if not item :
return
2014-02-17 00:35:45 +01:00
if str ( item . text ( ) ) == ' meminfo-writer ' :
2017-11-06 20:36:09 +01:00
firewall . QMessageBox . information ( None ,
self . tr ( ' Service can not be removed ' ) ,
self . tr ( ' Service meminfo-writer can not be removed from the list. ' ) )
2014-09-04 21:59:05 +02:00
return
row = self . services_list . currentRow ( )
item = self . services_list . takeItem ( row )
del self . new_srv_dict [ str ( item . text ( ) ) ]
2012-03-14 11:54:50 +01:00
2012-03-30 21:46:23 +02:00
def services_item_clicked ( self , item ) :
if str ( item . text ( ) ) == ' meminfo-writer ' :
2017-11-06 20:36:09 +01:00
if item . checkState ( ) == ui_settingsdlg . QtCore . Qt . Checked :
2012-03-30 21:46:23 +02:00
if not self . include_in_balancing . isChecked ( ) :
self . include_in_balancing . setChecked ( True )
2017-11-06 20:36:09 +01:00
elif item . checkState ( ) == ui_settingsdlg . QtCore . Qt . Unchecked :
2012-03-30 21:46:23 +02:00
if self . include_in_balancing . isChecked ( ) :
self . include_in_balancing . setChecked ( False )
2012-03-14 11:54:50 +01:00
def __apply_services_tab__ ( self ) :
2013-02-23 06:44:06 +01:00
msg = [ ]
2012-03-30 21:46:23 +02:00
2013-02-23 06:44:06 +01:00
try :
2017-07-12 14:52:05 +02:00
for r in range ( self . services_list . count ( ) ) :
2013-02-23 06:44:06 +01:00
item = self . services_list . item ( r )
2017-11-06 20:36:09 +01:00
self . new_srv_dict [ str ( item . text ( ) ) ] = ( item . checkState ( ) == ui_settingsdlg . QtCore . Qt . Checked )
2012-03-30 21:46:23 +02:00
2017-07-12 14:52:05 +02:00
balancing_was_checked = self . vm . features . get ( ' service.meminfo-writer ' , True )
balancing_is_checked = self . include_in_balancing . isChecked ( )
meminfo_writer_checked = self . new_srv_dict . get ( ' meminfo-writer ' , True )
2013-02-23 06:44:06 +01:00
if balancing_is_checked != meminfo_writer_checked :
if balancing_is_checked != balancing_was_checked :
self . new_srv_dict [ ' meminfo-writer ' ] = balancing_is_checked
2017-07-12 14:52:05 +02:00
for service , v in self . new_srv_dict . items ( ) :
feature = ' service. ' + service
if v != self . vm . features . get ( feature , object ( ) ) :
self . vm . features [ feature ] = v
self . anything_changed = True
for feature in self . vm . features :
if not feature . startswith ( ' service. ' ) :
continue
service = feature [ len ( ' service. ' ) : ]
if service not in self . new_srv_dict :
del self . vm . features [ feature ]
2013-02-23 06:44:06 +01:00
except Exception as ex :
msg . append ( str ( ex ) )
return msg
2012-03-14 11:54:50 +01:00
2012-02-10 00:30:45 +01:00
######### firewall tab related
def set_fw_model ( self , model ) :
self . fw_model = model
self . rulesTreeView . setModel ( model )
2017-11-06 20:36:09 +01:00
self . rulesTreeView . header ( ) . setResizeMode ( firewall . QHeaderView . ResizeToContents )
self . rulesTreeView . header ( ) . setResizeMode ( 0 , firewall . QHeaderView . Stretch )
2012-02-10 00:30:45 +01:00
self . set_allow ( model . allow )
2014-03-28 05:19:07 +01:00
if model . tempFullAccessExpireTime :
self . tempFullAccess . setChecked ( True )
self . tempFullAccessTime . setValue (
( model . tempFullAccessExpireTime -
2017-11-06 20:36:09 +01:00
int ( firewall . datetime . datetime . now ( ) . strftime ( " %s " ) ) ) / 60 )
2012-02-10 00:30:45 +01:00
2017-10-13 18:04:49 +02:00
def disable_all_fw_conf ( self ) :
self . firewallModifiedOutsidelabel . setVisible ( True )
self . policyAllowRadioButton . setEnabled ( False )
self . policyDenyRadioButton . setEnabled ( False )
self . rulesTreeView . setEnabled ( False )
self . newRuleButton . setEnabled ( False )
self . editRuleButton . setEnabled ( False )
self . deleteRuleButton . setEnabled ( False )
self . firewalRulesLabel . setEnabled ( False )
self . tempFullAccessWidget . setEnabled ( False )
2012-02-10 00:30:45 +01:00
def set_allow ( self , allow ) :
self . policyAllowRadioButton . setChecked ( allow )
self . policyDenyRadioButton . setChecked ( not allow )
2014-03-28 05:19:07 +01:00
self . policy_changed ( allow )
def policy_changed ( self , checked ) :
2017-10-13 18:04:49 +02:00
self . rulesTreeView . setEnabled ( self . policyDenyRadioButton . isChecked ( ) )
self . newRuleButton . setEnabled ( self . policyDenyRadioButton . isChecked ( ) )
self . editRuleButton . setEnabled ( self . policyDenyRadioButton . isChecked ( ) )
self . deleteRuleButton . setEnabled ( self . policyDenyRadioButton . isChecked ( ) )
self . firewalRulesLabel . setEnabled (
self . policyDenyRadioButton . isChecked ( ) )
self . tempFullAccessWidget . setEnabled (
self . policyDenyRadioButton . isChecked ( ) )
2014-02-17 00:35:45 +01:00
2012-02-10 00:30:45 +01:00
def new_rule_button_pressed ( self ) :
2017-11-06 20:36:09 +01:00
dialog = firewall . NewFwRuleDlg ( )
2017-10-13 18:04:49 +02:00
self . fw_model . run_rule_dialog ( dialog )
2012-02-10 00:30:45 +01:00
def edit_rule_button_pressed ( self ) :
2017-10-13 18:04:49 +02:00
2012-02-10 00:30:45 +01:00
selected = self . rulesTreeView . selectedIndexes ( )
2017-10-13 18:04:49 +02:00
2012-02-10 00:30:45 +01:00
if len ( selected ) > 0 :
2017-11-06 20:36:09 +01:00
dialog = firewall . NewFwRuleDlg ( )
2017-10-13 18:04:49 +02:00
dialog . set_ok_enabled ( True )
2012-02-10 00:30:45 +01:00
row = self . rulesTreeView . selectedIndexes ( ) . pop ( ) . row ( )
2017-10-13 18:04:49 +02:00
self . fw_model . populate_edit_dialog ( dialog , row )
self . fw_model . run_rule_dialog ( dialog , row )
2012-02-10 00:30:45 +01:00
def delete_rule_button_pressed ( self ) :
2017-10-13 18:04:49 +02:00
for i in set ( [ index . row ( ) for index
in self . rulesTreeView . selectedIndexes ( ) ] ) :
2012-02-10 00:30:45 +01:00
self . fw_model . removeChild ( i )
2012-02-09 19:47:21 +01:00
2012-01-31 11:17:09 +01:00
# Bases on the original code by:
# Copyright (c) 2002-2007 Pascal Varet <p.varet@gmail.com>
2017-06-26 17:54:35 +02:00
def handle_exception ( exc_type , exc_value , exc_traceback ) :
2012-01-31 11:17:09 +01:00
2017-06-26 17:54:35 +02:00
filename , line , dummy , dummy = traceback . extract_tb ( exc_traceback ) . pop ( )
2017-11-06 20:36:09 +01:00
filename = firewall . os . path . basename ( filename )
2017-06-26 17:54:35 +02:00
error = " %s : %s " % ( exc_type . __name__ , exc_value )
2012-01-31 11:17:09 +01:00
2012-03-14 14:00:49 +01:00
strace = " "
2017-06-26 17:54:35 +02:00
stacktrace = traceback . extract_tb ( exc_traceback )
2012-03-14 14:00:49 +01:00
while len ( stacktrace ) > 0 :
( filename , line , func , txt ) = stacktrace . pop ( )
strace + = " ---- \n "
strace + = " line: %s \n " % txt
strace + = " func: %s \n " % func
strace + = " line no.: %d \n " % line
strace + = " file: %s \n " % filename
2017-11-06 20:36:09 +01:00
msg_box = firewall . QMessageBox ( )
2012-03-14 14:00:49 +01:00
msg_box . setDetailedText ( strace )
2017-11-06 20:36:09 +01:00
msg_box . setIcon ( firewall . QMessageBox . Critical )
2017-06-26 17:54:35 +02:00
msg_box . setWindowTitle ( " Houston, we have a problem... " )
2012-03-14 14:00:49 +01:00
msg_box . setText ( " Whoops. A critical error has occured. This is most likely a bug "
" in Qubes Manager.<br><br> "
" <b><i> %s </i></b> " % error +
" <br/>at line <b> %d </b><br/>of file %s .<br/><br/> "
% ( line , filename ) )
2014-02-17 00:35:45 +01:00
2012-03-14 14:00:49 +01:00
msg_box . exec_ ( )
2012-01-31 11:17:09 +01:00
2017-11-06 20:36:09 +01:00
parser = firewall . qubesadmin . tools . QubesArgumentParser ( vmname_nargs = 1 )
2017-06-28 13:41:10 +02:00
2017-06-26 17:54:35 +02:00
parser . add_argument ( ' --tab ' , metavar = ' TAB ' ,
action = ' store ' ,
choices = VMSettingsWindow . tabs_indices . keys ( ) )
2017-06-28 13:41:10 +02:00
parser . set_defaults (
tab = ' basic ' ,
)
2012-01-31 11:17:09 +01:00
2017-06-26 17:54:35 +02:00
def main ( args = None ) :
global settings_window
2012-01-31 11:17:09 +01:00
2017-06-26 17:54:35 +02:00
args = parser . parse_args ( args )
vm = args . domains . pop ( )
2012-01-31 11:17:09 +01:00
2017-11-06 20:36:09 +01:00
qapp = firewall . QApplication ( firewall . sys . argv )
2017-06-26 17:54:35 +02:00
qapp . setOrganizationName ( ' Invisible Things Lab ' )
qapp . setOrganizationDomain ( " https://www.qubes-os.org/ " )
qapp . setApplicationName ( " Qubes VM Settings " )
2012-02-09 19:47:21 +01:00
2017-07-12 14:08:34 +02:00
if not utils . is_debug ( ) :
2017-11-06 20:36:09 +01:00
firewall . sys . excepthook = handle_exception
2012-01-31 11:17:09 +01:00
2017-06-26 17:54:35 +02:00
settings_window = VMSettingsWindow ( vm , qapp , args . tab )
2012-01-31 11:17:09 +01:00
settings_window . show ( )
2017-06-26 17:54:35 +02:00
qapp . exec_ ( )
qapp . exit ( )
2012-01-31 11:17:09 +01:00
if __name__ == " __main__ " :
main ( )
2012-05-19 09:33:29 +02:00
# vim:sw=4:et: