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>
# Copyright (C) 2012 Marek Marczykowski <marmarek@mimuw.edu.pl>
#
# 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.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
#
from qubes . qubes import QubesVmCollection
2012-02-13 13:50:30 +01:00
from qubes . qubes import QubesVmLabels
2012-01-31 11:17:09 +01:00
from qubes . qubes import QubesHost
2013-03-16 21:07:53 +01:00
from qubes . qubes import system_path
2012-01-31 11:17:09 +01:00
import subprocess
2012-03-14 11:54:50 +01:00
from copy import copy
2012-01-31 11:17:09 +01:00
from ui_settingsdlg import *
2012-02-09 19:47:21 +01:00
from appmenu_select import *
2012-02-10 00:30:45 +01:00
from firewall import *
2014-02-17 00:53:47 +01:00
from backup_utils import get_path_for_vm
2012-01-31 11:17:09 +01:00
class VMSettingsWindow ( Ui_SettingsDialog , QDialog ) :
2012-02-09 19:47:21 +01:00
tabs_indices = { " basic " : 0 ,
" advanced " : 1 ,
" firewall " : 2 ,
" devices " : 3 ,
" applications " : 4 ,
" services " : 5 , }
2012-02-13 13:50:30 +01:00
def __init__ ( self , vm , app , qvm_collection , 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 . app = app
2012-02-13 13:50:30 +01:00
self . qvm_collection = qvm_collection
2012-02-10 00:30:45 +01:00
self . vm = vm
2012-03-12 12:53:07 +01:00
if self . vm . template :
self . source_vm = self . vm . template
2012-02-10 00:30:45 +01:00
else :
self . source_vm = self . vm
2014-02-17 00:35:45 +01:00
2012-01-31 11:17:09 +01:00
self . setupUi ( self )
2012-07-22 01:47:36 +02:00
self . setWindowTitle ( " Settings: %s " % 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
self . connect ( self . buttonBox , SIGNAL ( " accepted() " ) , self . save_and_apply )
self . connect ( self . buttonBox , SIGNAL ( " rejected() " ) , self . reject )
2012-02-10 00:30:45 +01:00
self . tabWidget . currentChanged . connect ( self . current_tab_changed )
2012-03-08 15:40:02 +01:00
self . tabWidget . setTabEnabled ( self . tabs_indices [ " firewall " ] , vm . is_networked ( ) and not ( vm . is_netvm ( ) and not vm . is_proxyvm ( ) ) )
2012-02-13 13:50:30 +01:00
###### basic tab
self . __init_basic_tab__ ( )
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 )
2014-09-16 21:25:52 +02:00
self . connect ( self . init_mem , SIGNAL ( " editingFinished() " ) , self . check_mem_changes )
self . connect ( self . max_mem_size , SIGNAL ( " editingFinished() " ) , self . check_mem_changes )
2014-02-17 00:53:47 +01:00
self . drive_path_button . clicked . connect ( self . drive_path_button_pressed )
2012-03-12 21:08:32 +01:00
2012-02-10 00:30:45 +01:00
###### firewall tab
2012-03-08 15:40:02 +01:00
if self . tabWidget . isTabEnabled ( self . tabs_indices [ " firewall " ] ) :
2012-02-10 00:30:45 +01:00
2012-03-08 15:40:02 +01:00
model = QubesFirewallRulesModel ( )
model . set_vm ( vm )
self . set_fw_model ( model )
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__ ( )
2012-03-19 16:02:05 +01:00
self . connect ( self . dev_list , 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 " ] ) :
2012-02-13 13:50:30 +01:00
self . app_list = MultiSelectWidget ( self )
self . apps_layout . addWidget ( self . app_list )
self . AppListManager = AppmenuSelectManager ( self . vm , self . app_list )
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 ) :
thread_monitor = ThreadMonitor ( )
thread = threading . Thread ( target = self . __save_changes__ , args = ( thread_monitor , ) )
thread . daemon = True
thread . start ( )
2014-02-17 00:35:45 +01:00
2012-02-09 19:47:21 +01:00
progress = QProgressDialog ( " Applying settings to <b> {0} </b>... " . format ( self . vm . name ) , " " , 0 , 0 )
progress . setCancelButton ( None )
progress . setModal ( True )
progress . show ( )
while not thread_monitor . is_finished ( ) :
self . app . processEvents ( )
time . sleep ( 0.1 )
progress . hide ( )
2014-02-17 00:35:45 +01:00
2012-02-09 19:47:21 +01:00
if not thread_monitor . success :
2013-02-23 06:46:56 +01:00
QMessageBox . warning ( None , " Error while changing settings for {0} ! " . format ( self . vm . name ) ,
" ERROR: {0} " . format ( thread_monitor . error_msg ) )
2012-02-09 19:47:21 +01:00
self . done ( 0 )
def __save_changes__ ( self , thread_monitor ) :
2012-03-01 22:50:32 +01:00
2012-03-12 15:54:16 +01:00
self . qvm_collection . lock_db_for_writing ( )
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 :
ret . append ( ' Error while saving changes: ' + str ( ex ) )
2012-03-12 15:54:16 +01:00
if self . anything_changed == True :
self . qvm_collection . save ( )
self . qvm_collection . unlock_db ( )
2013-02-23 06:44:06 +01:00
try :
if self . tabWidget . isTabEnabled ( self . tabs_indices [ " firewall " ] ) :
self . fw_model . apply_rules ( self . policyAllowRadioButton . isChecked ( ) ,
self . dnsCheckBox . isChecked ( ) ,
self . icmpCheckBox . isChecked ( ) ,
2014-03-28 05:19:07 +01:00
self . yumproxyCheckBox . isChecked ( ) ,
self . tempFullAccess . isChecked ( ) ,
self . tempFullAccessTime . value ( ) )
2013-02-23 06:44:06 +01:00
except Exception as ex :
ret + = [ " Firewall tab: " , str ( ex ) ]
try :
if self . tabWidget . isTabEnabled ( self . tabs_indices [ " applications " ] ) :
self . AppListManager . save_appmenu_select_changes ( )
except Exception as ex :
ret + = [ " Applications tab: " , str ( ex ) ]
2012-03-12 15:54:16 +01:00
2013-02-23 06:44:06 +01:00
if len ( ret ) > 0 :
thread_monitor . set_error_msg ( ' \n ' . join ( ret ) )
2012-03-01 22:50:32 +01:00
2012-02-09 19:47:21 +01:00
thread_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 " ] :
2012-03-04 22:02:27 +01:00
if self . vm . netvm is not None and not self . vm . netvm . is_proxyvm ( ) :
2012-02-10 00:30:45 +01:00
QMessageBox . warning ( None , " VM configuration problem! " , " The ' {0} ' AppVM is not network connected to a FirewallVM!<p> " . format ( self . vm . name ) + \
" You may edit the ' {0} ' VM firewall rules, but these will not take any effect until you connect it to a working Firewall VM. " . format ( self . vm . name ) )
2012-02-13 13:50:30 +01:00
######### basic tab
def __init_basic_tab__ ( self ) :
self . vmname . setText ( self . vm . name )
2012-08-23 03:57:19 +02:00
self . vmname . setValidator ( QRegExpValidator ( QRegExp ( " [a-zA-Z0-9-]* " , Qt . CaseInsensitive ) , None ) )
2014-10-28 04:55:14 +01:00
self . vmname . setEnabled ( not self . vm . is_running ( ) )
2014-02-17 00:35:45 +01:00
2012-02-13 13:50:30 +01:00
#self.qvm_collection.lock_db_for_reading()
#self.qvm_collection.load()
#self.qvm_collection.unlock_db()
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 :
2012-04-27 11:54:53 +02:00
self . vmlabel . setVisible ( True )
self . label_list = QubesVmLabels . values ( )
self . label_list . sort ( key = lambda l : l . index )
self . label_idx = 0
for ( i , label ) in enumerate ( self . label_list ) :
if label == self . vm . label :
self . label_idx = i
self . vmlabel . insertItem ( i , label . name )
self . vmlabel . setItemIcon ( i , QIcon ( label . icon_path ) )
self . vmlabel . setCurrentIndex ( self . label_idx )
2014-10-28 04:55:14 +01:00
self . vmlabel . setEnabled ( not self . vm . is_running ( ) )
2012-02-13 13:50:30 +01:00
2012-03-12 12:53:07 +01:00
if not self . vm . is_template ( ) and self . vm . template is not None :
2012-02-13 13:50:30 +01:00
template_vm_list = [ vm for vm in self . qvm_collection . values ( ) if not vm . internal and vm . is_template ( ) ]
2012-03-12 22:06:43 +01:00
self . template_idx = - 1
2013-11-21 04:17:59 +01:00
i = 0
for vm in template_vm_list :
if not self . vm . is_template_compatible ( vm ) :
continue
2012-02-13 13:50:30 +01:00
text = vm . name
2012-03-12 13:52:42 +01:00
if vm is self . qvm_collection . get_default_template ( ) :
2012-02-13 13:50:30 +01:00
text + = " (default) "
2012-03-12 12:53:07 +01:00
if vm . qid == self . vm . template . qid :
2012-02-13 13:50:30 +01:00
self . template_idx = i
text + = " (current) "
self . template_name . insertItem ( i , text )
2013-11-21 04:17:59 +01:00
i + = 1
2012-02-13 13:50:30 +01:00
self . template_name . setCurrentIndex ( self . template_idx )
2015-04-05 21:03:41 +02:00
self . template_name . setEnabled ( not self . vm . is_running ( ) )
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
2012-03-08 15:40:02 +01:00
if ( not self . vm . is_netvm ( ) or self . vm . is_proxyvm ( ) ) :
2014-06-07 04:05:03 +02:00
netvm_list = [ vm for vm in self . qvm_collection . values ( ) if not vm . internal and vm . is_netvm ( ) and vm . qid != 0 ]
2012-03-08 15:40:02 +01:00
self . netvm_idx = - 1
2012-03-12 22:06:43 +01:00
2015-05-24 11:01:04 +02:00
default_netvm = self . qvm_collection . get_default_netvm ( )
if default_netvm is not None :
text = " default ( %s ) " % default_netvm . name
if self . vm . uses_default_netvm :
text + = " (current) "
self . netvm_idx = 0
self . netVM . insertItem ( 0 , text )
2014-02-17 00:35:45 +01:00
2012-02-13 13:50:30 +01:00
for ( i , vm ) in enumerate ( netvm_list ) :
text = vm . name
2012-03-12 22:06:43 +01:00
if self . vm . netvm is not None and vm . qid == self . vm . netvm . qid and not self . vm . uses_default_netvm :
self . netvm_idx = i + 1
2012-02-13 13:50:30 +01:00
text + = " (current) "
2012-03-12 22:06:43 +01:00
self . netVM . insertItem ( i + 1 , text )
2012-03-08 15:40:02 +01:00
none_text = " none "
if self . vm . netvm is None :
none_text + = " (current) "
2012-03-12 22:06:43 +01:00
self . netvm_idx = len ( netvm_list ) + 1
self . netVM . insertItem ( len ( netvm_list ) + 1 , none_text )
2012-02-13 13:50:30 +01:00
self . netVM . setCurrentIndex ( self . netvm_idx )
else :
self . netVM . setEnabled ( False )
2012-03-12 21:08:32 +01:00
self . netvm_idx = - 1
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 )
2012-04-24 14:27:28 +02:00
if hasattr ( self . vm , ' debug ' ) :
self . run_in_debug_mode . setVisible ( True )
self . run_in_debug_mode . setChecked ( self . vm . debug )
else :
self . run_in_debug_mode . setVisible ( False )
2014-05-17 19:21:00 +02:00
if hasattr ( self . vm , ' autostart ' ) :
self . autostart_vm . setVisible ( True )
self . autostart_vm . setChecked ( self . vm . autostart )
else :
self . autostart_vm . setVisible ( False )
2014-04-01 01:13:34 +02:00
if hasattr ( self . vm , ' seamless_gui_mode ' ) :
self . seamless_gui . setVisible ( True )
self . seamless_gui . setChecked ( self . vm . seamless_gui_mode )
else :
self . seamless_gui . setVisible ( False )
2012-03-07 20:42:18 +01:00
#type
self . type_label . setText ( self . vm . type )
#installed by rpm
text = " Yes " if self . vm . installed_by_rpm == True else " No "
self . rpm_label . setText ( text )
2012-03-09 08:43:42 +01:00
#networking info
if self . vm . is_networked ( ) :
2014-02-23 00:44:08 +01:00
self . networking_groupbox . setEnabled ( True )
2012-03-09 08:43:42 +01:00
self . ip_label . setText ( self . vm . ip if self . vm . ip is not None else " none " )
self . netmask_label . setText ( self . vm . netmask if self . vm . netmask is not None else " none " )
2012-12-10 16:13:14 +01:00
self . gateway_label . setText ( self . vm . netvm . gateway if self . vm . netvm is not None else " 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
self . priv_img_size = self . vm . get_private_img_sz ( ) / 1024 / 1024
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
2014-03-21 18:40:23 +01:00
self . root_img_size = self . vm . get_root_img_sz ( ) / 1024 / 1024
self . root_resize . setValue ( self . root_img_size )
self . root_resize . setMinimum ( self . root_img_size )
self . root_resize . setEnabled ( hasattr ( self . vm , ' resize_root_img ' ) and
not self . vm . template )
self . root_resize_label . setEnabled ( self . root_resize . isEnabled ( ) )
2012-02-13 13:50:30 +01:00
def __apply_basic_tab__ ( self ) :
msg = [ ]
# vmname changed
vmname = str ( self . vmname . text ( ) )
if self . vm . name != vmname :
2012-03-01 22:50:32 +01:00
if self . vm . is_running ( ) :
msg . append ( " Can ' t change name of a running VM. " )
elif self . qvm_collection . get_vm_by_name ( vmname ) is not None :
2012-03-12 15:54:16 +01:00
msg . append ( " Can ' t change VM name - a VM named <b> {0} </b> already exists in the system! " . format ( vmname ) )
2012-02-13 13:50:30 +01:00
else :
oldname = self . vm . name
try :
self . vm . set_name ( vmname )
2012-03-12 15:54:16 +01:00
self . anything_changed = True
2012-02-13 13:50:30 +01:00
except Exception as ex :
msg . append ( str ( ex ) )
2013-02-23 06:44:06 +01:00
2012-02-13 13:50:30 +01:00
#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 :
2014-07-05 14:57:47 +02:00
new_template_name = str ( self . template_name . currentText ( ) )
2013-02-23 06:44:06 +01:00
new_template_name = new_template_name . split ( ' ' ) [ 0 ]
template_vm = self . qvm_collection . get_vm_by_name ( new_template_name )
assert ( template_vm is not None and template_vm . qid in self . qvm_collection )
assert template_vm . is_template ( )
self . vm . template = template_vm
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 :
2014-07-05 14:57:47 +02:00
new_netvm_name = str ( self . netVM . currentText ( ) )
2013-02-23 06:44:06 +01:00
new_netvm_name = new_netvm_name . split ( ' ' ) [ 0 ]
2012-03-12 22:06:43 +01:00
2013-02-23 06:44:06 +01:00
uses_default_netvm = False
2012-03-12 22:06:43 +01:00
2013-02-23 06:44:06 +01:00
if new_netvm_name == " default " :
new_netvm_name = self . qvm_collection . get_default_netvm ( ) . name
uses_default_netvm = True
if new_netvm_name == " none " :
netvm = None
else :
netvm = self . qvm_collection . get_vm_by_name ( new_netvm_name )
assert ( netvm is None or ( netvm is not None and netvm . qid in self . qvm_collection and netvm . is_netvm ( ) ) )
self . vm . netvm = netvm
self . vm . uses_default_netvm = uses_default_netvm
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 ) )
#seamless_gui
2014-04-01 01:13:34 +02:00
try :
if self . seamless_gui . isVisible ( ) :
if self . vm . seamless_gui_mode != self . seamless_gui . isChecked ( ) :
self . vm . seamless_gui_mode = self . seamless_gui . 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 :
self . vm . resize_private_img ( priv_size * 1024 * 1024 )
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 :
self . vm . resize_root_img ( sys_size * 1024 * 1024 )
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 ( ) :
2014-09-16 21:25:52 +02:00
QMessageBox . warning ( None , " Warning! " , " Max memory can not be less than initial memory.<br>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 ( ) :
QMessageBox . warning ( None , " Warning! " , " Initial memory can not be less than one tenth Max memory.<br>Setting initial memory to the minimum allowed value. " )
self . init_mem . setValue ( self . max_mem_size . value ( ) / 10 )
2013-10-29 13:41:46 +01:00
2012-05-19 09:33:29 +02: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
2012-10-03 22:08:37 +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 ) )
2012-05-19 09:33:29 +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 ) )
2012-05-19 09:33:29 +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 )
2012-03-13 22:05:50 +01:00
self . vcpus . setMaximum ( QubesHost ( ) . no_cpus )
self . vcpus . setValue ( int ( self . vm . vcpus ) )
2012-12-12 16:32:08 +01:00
self . include_in_balancing . setEnabled ( True )
2012-03-30 21:46:23 +02:00
self . include_in_balancing . setChecked ( self . vm . services [ ' meminfo-writer ' ] == True )
2012-12-12 16:32:08 +01:00
if self . vm . type == " HVM " :
self . include_in_balancing . setChecked ( False )
self . include_in_balancing . setEnabled ( False )
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
#paths
self . dir_path . setText ( self . vm . dir_path )
self . config_path . setText ( self . vm . conf_file )
if self . vm . template is not None :
self . root_img_path . setText ( self . vm . template . root_img )
2012-04-24 19:14:12 +02:00
elif self . vm . root_img is not None :
self . root_img_path . setText ( self . vm . root_img )
2012-04-18 19:33:53 +02:00
else :
self . root_img_path . setText ( " n/a " )
2012-04-24 19:05:15 +02:00
if self . vm . volatile_img is not None :
self . volatile_img_path . setText ( self . vm . volatile_img )
else :
self . volatile_img_path . setText ( ' n/a ' )
2012-04-18 19:33:53 +02:00
self . private_img_path . setText ( self . vm . private_img )
2012-03-12 21:08:32 +01:00
#kernel
2012-04-18 19:33:53 +02:00
2012-04-24 15:02:19 +02:00
#in case VM is HVM
2012-04-18 19:33:53 +02:00
if not hasattr ( self . vm , " kernel " ) :
self . kernel_groupbox . setVisible ( False )
2012-03-12 21:08:32 +01:00
else :
2014-02-17 00:40:28 +01:00
self . kernel_groupbox . setVisible ( True )
# construct available kernels list
text = " default ( " + self . qvm_collection . get_default_kernel ( ) + " ) "
kernel_list = [ text ]
for k in os . listdir ( system_path [ " qubes_kernels_base_dir " ] ) :
kernel_list . append ( k )
kernel_list . append ( " none " )
self . kernel_idx = 0
# put available kernels to a combobox
for ( i , k ) in enumerate ( kernel_list ) :
text = k
# and mark the current choice
if ( text . startswith ( " default " ) and self . vm . uses_default_kernel ) or ( self . vm . kernel == k and not self . vm . uses_default_kernel ) or ( k == " none " and self . vm . kernel == None ) :
text + = " (current) "
self . kernel_idx = i
self . kernel . insertItem ( i , text )
self . kernel . setCurrentIndex ( self . kernel_idx )
#kernel opts
if self . vm . uses_default_kernelopts :
self . kernel_opts . setText ( self . vm . kernelopts + " (default) " )
else :
self . kernel_opts . setText ( self . vm . kernelopts )
2012-03-12 21:08:32 +01:00
2014-02-17 00:53:47 +01:00
if not hasattr ( self . vm , " drive " ) :
self . drive_groupbox . setVisible ( False )
else :
self . drive_groupbox . setVisible ( True )
self . drive_groupbox . setChecked ( self . vm . drive is not None )
self . drive_running_warning . setVisible ( self . vm . is_running ( ) )
self . drive_type . addItems ( [ " hd " , " cdrom " ] )
self . drive_type . setCurrentIndex ( 0 )
vm_list = [ vm for vm in self . qvm_collection . values ( ) if not vm
. internal and vm . qid != self . vm . qid ]
# default to dom0 (in case of nonexisting vm already set...)
self . drive_domain_idx = 0
for ( i , vm ) in enumerate ( sorted ( vm_list , key = lambda v : v . name ) ) :
if vm . qid == 0 :
self . drive_domain_idx = i
self . drive_domain . insertItem ( i , vm . name )
if self . vm . drive is not None :
( drv_type , drv_domain , drv_path ) = self . vm . drive . split ( " : " )
if drv_type == " cdrom " :
self . drive_type . setCurrentIndex ( 1 )
else :
self . drive_type . setCurrentIndex ( 0 )
for i in xrange ( self . drive_domain . count ( ) ) :
if drv_domain == self . drive_domain . itemText ( i ) :
self . drive_domain_idx = i
self . drive_path . setText ( drv_path )
self . drive_domain . setCurrentIndex ( self . drive_domain_idx )
2015-04-06 00:59:15 +02:00
if not hasattr ( self . vm , " dispvm_netvm " ) :
self . other_groupbox . setVisible ( False )
else :
self . other_groupbox . setVisible ( True )
netvm_list = [ vm for vm in self . qvm_collection . values ( ) if not vm . internal and vm . is_netvm ( ) and vm . qid != 0 ]
self . dispvm_netvm_idx = - 1
text = " default (same as VM own NetVM) "
if self . vm . uses_default_dispvm_netvm :
text + = " (current) "
self . dispvm_netvm_idx = 0
self . dispvm_netvm . insertItem ( 0 , text )
for ( i , vm ) in enumerate ( netvm_list ) :
text = vm . name
if self . vm . dispvm_netvm is not None and vm . qid == \
self . vm . dispvm_netvm . qid and not \
self . vm . uses_default_dispvm_netvm :
self . dispvm_netvm_idx = i + 1
text + = " (current) "
self . dispvm_netvm . insertItem ( i + 1 , text )
none_text = " none "
if self . vm . dispvm_netvm is None :
none_text + = " (current) "
self . dispvm_netvm_idx = len ( netvm_list ) + 1
self . dispvm_netvm . insertItem ( len ( netvm_list ) + 1 , none_text )
self . dispvm_netvm . setCurrentIndex ( self . dispvm_netvm_idx )
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 :
2014-07-05 14:57:47 +02:00
new_kernel = str ( self . kernel . currentText ( ) )
2014-02-17 00:40:28 +01:00
new_kernel = new_kernel . split ( ' ' ) [ 0 ]
if new_kernel == " default " :
kernel = self . qvm_collection . get_default_kernel ( )
self . vm . uses_default_kernel = True
elif new_kernel == " none " :
kernel = None
self . vm . uses_default_kernel = False
else :
kernel = new_kernel
self . vm . uses_default_kernel = False
self . vm . kernel = kernel
self . anything_changed = True
except Exception as ex :
msg . append ( str ( ex ) )
2013-02-23 06:44:06 +01:00
2014-02-17 00:53:47 +01:00
if hasattr ( self . vm , " drive " ) and self . drive_groupbox . isVisible ( ) :
try :
if not self . drive_groupbox . isChecked ( ) :
if self . vm . drive != None :
self . vm . drive = None
self . anything_changed = True
else :
new_domain = str ( self . drive_domain . currentText ( ) )
if self . drive_domain . currentIndex ( ) == self . drive_domain_idx :
# strip "(current)"
new_domain = new_domain . split ( ' ' ) [ 0 ]
drive = " %s : %s : %s " % (
str ( self . drive_type . currentText ( ) ) ,
new_domain ,
str ( self . drive_path . text ( ) )
)
if self . vm . drive != drive :
self . vm . drive = drive
self . anything_changed = True
except Exception as ex :
msg . append ( str ( ex ) )
2012-03-12 21:08:32 +01:00
2015-04-06 00:59:15 +02:00
#vm dispvm_netvm changed
try :
print self . dispvm_netvm . currentIndex ( )
if self . dispvm_netvm . currentIndex ( ) != self . dispvm_netvm_idx :
new_dispvm_netvm_name = str ( self . dispvm_netvm . currentText ( ) )
new_dispvm_netvm_name = new_dispvm_netvm_name . split ( ' ' ) [ 0 ]
uses_default_dispvm_netvm = False
if new_dispvm_netvm_name == " default " :
uses_default_dispvm_netvm = True
if new_dispvm_netvm_name == " none " :
dispvm_netvm = None
else :
dispvm_netvm = self . qvm_collection . get_vm_by_name (
new_dispvm_netvm_name )
assert ( dispvm_netvm is None or ( dispvm_netvm . qid in
self . qvm_collection and dispvm_netvm . is_netvm ( ) ) )
if uses_default_dispvm_netvm :
self . vm . uses_default_dispvm_netvm = True
else :
self . vm . uses_default_dispvm_netvm = False
self . vm . dispvm_netvm = dispvm_netvm
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
2014-02-17 00:53:47 +01:00
def drive_path_button_pressed ( self ) :
2014-07-05 14:57:47 +02:00
if str ( self . drive_domain . currentText ( ) ) in [ " dom0 " , " dom0 (current) " ] :
2014-02-17 00:53:47 +01:00
file_dialog = QFileDialog ( )
file_dialog . setReadOnly ( True )
new_path = file_dialog . getOpenFileName ( self , " Select drive image " ,
str ( self . drive_path . text ( ) ) )
else :
drv_domain = str ( self . drive_domain . currentText ( ) )
if drv_domain . count ( " (current) " ) > 0 :
drv_domain = drv_domain . split ( ' ' ) [ 0 ]
backend_vm = self . qvm_collection . get_vm_by_name ( drv_domain )
if backend_vm :
new_path = get_path_for_vm ( backend_vm , " qubes.SelectFile " )
2014-09-09 21:59:54 +02:00
if new_path :
self . drive_path . setText ( new_path )
2014-02-17 00:53:47 +01:00
2012-03-13 20:06:41 +01:00
######## devices tab
def __init_devices_tab__ ( self ) :
self . dev_list = 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 = [ ]
2014-05-16 19:16:16 +02:00
lspci = subprocess . Popen ( [ " /usr/sbin/lspci " , ] , stdout = subprocess . PIPE )
2012-03-13 20:06:41 +01:00
for dev in lspci . stdout :
devs . append ( ( dev . rstrip ( ) , dev . split ( ' ' ) [ 0 ] ) )
class DevListWidgetItem ( QListWidgetItem ) :
def __init__ ( self , name , slot , parent = None ) :
super ( DevListWidgetItem , self ) . __init__ ( name , parent )
self . slot = slot
2014-11-01 19:57:17 +01:00
self . Type
2012-03-13 20:06:41 +01:00
for d in devs :
if d [ 1 ] in self . vm . pcidevs :
self . dev_list . selected_list . addItem ( DevListWidgetItem ( d [ 0 ] , d [ 1 ] ) )
else :
self . dev_list . available_list . addItem ( DevListWidgetItem ( d [ 0 ] , d [ 1 ] ) )
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
sth_changed = False
added = [ ]
2013-02-23 06:44:06 +01:00
try :
2012-03-13 20:06:41 +01:00
for i in range ( self . dev_list . selected_list . count ( ) ) :
2013-02-23 06:44:06 +01:00
item = self . dev_list . selected_list . item ( i )
if item . slot not in self . vm . pcidevs :
added . append ( item )
if self . dev_list . selected_list . count ( ) - len ( added ) < len ( self . vm . pcidevs ) : #sth removed
2014-02-23 00:44:08 +01:00
sth_changed = True
2013-02-23 06:44:06 +01:00
elif len ( added ) > 0 :
2014-02-23 00:44:08 +01:00
sth_changed = True
2013-02-23 06:44:06 +01:00
if sth_changed == True :
pcidevs = [ ]
for i in range ( self . dev_list . selected_list . count ( ) ) :
slot = self . dev_list . selected_list . item ( i ) . slot
pcidevs . append ( slot )
self . vm . pcidevs = pcidevs
self . anything_changed = True
except Exception as ex :
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 :
if state == QtCore . Qt . Checked :
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
######## services tab
def __init_services_tab__ ( self ) :
for srv in self . vm . services :
item = QListWidgetItem ( srv )
if self . vm . services [ srv ] == True :
item . setCheckState ( QtCore . Qt . Checked )
else :
item . setCheckState ( QtCore . Qt . Unchecked )
self . services_list . addItem ( item )
2013-02-23 06:44:06 +01:00
2012-03-30 21:46:23 +02:00
self . connect ( self . services_list , SIGNAL ( " itemClicked(QListWidgetItem *) " ) , self . services_item_clicked )
2012-03-14 11:54:50 +01:00
self . new_srv_dict = copy ( self . vm . services )
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 :
QMessageBox . information ( None , " " , " Service already on the list! " )
else :
item = QListWidgetItem ( srv )
item . setCheckState ( QtCore . Qt . Checked )
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 ' :
2012-10-03 22:08:37 +02:00
QMessageBox . information ( None , " Service can not be removed " , " 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 ' :
if item . checkState ( ) == QtCore . Qt . Checked :
if not self . include_in_balancing . isChecked ( ) :
self . include_in_balancing . setChecked ( True )
elif item . checkState ( ) == QtCore . Qt . Unchecked :
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 :
for r in range ( self . services_list . count ( ) ) :
item = self . services_list . item ( r )
self . new_srv_dict [ str ( item . text ( ) ) ] = ( item . checkState ( ) == QtCore . Qt . Checked )
2012-03-30 21:46:23 +02:00
2013-02-23 06:44:06 +01:00
balancing_was_checked = ( self . vm . services [ ' meminfo-writer ' ] == True )
balancing_is_checked = self . include_in_balancing . isChecked ( )
meminfo_writer_checked = ( self . new_srv_dict [ ' meminfo-writer ' ] == True )
if balancing_is_checked != meminfo_writer_checked :
if balancing_is_checked != balancing_was_checked :
self . new_srv_dict [ ' meminfo-writer ' ] = balancing_is_checked
if self . new_srv_dict != self . vm . services :
self . vm . services = self . new_srv_dict
self . anything_changed = True
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 )
self . rulesTreeView . header ( ) . setResizeMode ( QHeaderView . ResizeToContents )
self . rulesTreeView . header ( ) . setResizeMode ( 0 , QHeaderView . Stretch )
self . set_allow ( model . allow )
self . dnsCheckBox . setChecked ( model . allowDns )
self . icmpCheckBox . setChecked ( model . allowIcmp )
2012-06-05 20:29:57 +02:00
self . yumproxyCheckBox . setChecked ( model . allowYumProxy )
2014-03-28 05:19:07 +01:00
if model . tempFullAccessExpireTime :
self . tempFullAccess . setChecked ( True )
self . tempFullAccessTime . setValue (
( model . tempFullAccessExpireTime -
int ( datetime . datetime . now ( ) . strftime ( " %s " ) ) ) / 60 )
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 ) :
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 ) :
dialog = NewFwRuleDlg ( )
self . run_rule_dialog ( dialog )
def edit_rule_button_pressed ( self ) :
dialog = NewFwRuleDlg ( )
dialog . set_ok_enabled ( True )
selected = self . rulesTreeView . selectedIndexes ( )
if len ( selected ) > 0 :
row = self . rulesTreeView . selectedIndexes ( ) . pop ( ) . row ( )
address = self . fw_model . get_column_string ( 0 , row ) . replace ( ' ' , ' ' )
dialog . addressComboBox . setItemText ( 0 , address )
dialog . addressComboBox . setCurrentIndex ( 0 )
service = self . fw_model . get_column_string ( 1 , row )
2012-03-04 17:36:25 +01:00
if service == " any " :
service = " "
2012-02-10 00:30:45 +01:00
dialog . serviceComboBox . setItemText ( 0 , service )
dialog . serviceComboBox . setCurrentIndex ( 0 )
2012-03-04 17:36:25 +01:00
protocol = self . fw_model . get_column_string ( 2 , row )
if protocol == " tcp " :
dialog . tcp_radio . setChecked ( True )
elif protocol == " udp " :
dialog . udp_radio . setChecked ( True )
else :
dialog . any_radio . setChecked ( True )
2012-02-10 00:30:45 +01:00
self . run_rule_dialog ( dialog , row )
def delete_rule_button_pressed ( self ) :
for i in set ( [ index . row ( ) for index in self . rulesTreeView . selectedIndexes ( ) ] ) :
self . fw_model . removeChild ( i )
def run_rule_dialog ( self , dialog , row = None ) :
if dialog . exec_ ( ) :
address = str ( dialog . addressComboBox . currentText ( ) )
service = str ( dialog . serviceComboBox . currentText ( ) )
port = None
port2 = None
unmask = address . split ( " / " , 1 )
if len ( unmask ) == 2 :
address = unmask [ 0 ]
netmask = int ( unmask [ 1 ] )
else :
netmask = 32
if address == " * " :
address = " 0.0.0.0 "
netmask = 0
2012-03-04 17:36:25 +01:00
if dialog . any_radio . isChecked ( ) :
protocol = " any "
port = 0
else :
if dialog . tcp_radio . isChecked ( ) :
protocol = " tcp "
elif dialog . udp_radio . isChecked ( ) :
protocol = " udp "
2014-03-28 05:15:52 +01:00
else :
protocol = " any "
2014-02-17 00:35:45 +01:00
2012-03-04 17:36:25 +01:00
try :
range = service . split ( " - " , 1 )
if len ( range ) == 2 :
port = int ( range [ 0 ] )
port2 = int ( range [ 1 ] )
else :
port = int ( service )
except ( TypeError , ValueError ) as ex :
port = self . fw_model . get_service_port ( service )
2012-02-10 00:30:45 +01:00
if port is not None :
if port2 is not None and port2 < = port :
2016-06-21 02:03:32 +02:00
QMessageBox . warning ( None , " Invalid service ports range " ,
" Port {0} is lower than port {1} . " . format ( port2 , port ) )
2012-02-10 00:30:45 +01:00
else :
2014-03-28 05:15:52 +01:00
item = { " address " : address ,
" netmask " : netmask ,
" portBegin " : port ,
" portEnd " : port2 ,
" proto " : protocol ,
}
2012-02-10 00:30:45 +01:00
if row is not None :
self . fw_model . setChild ( row , item )
else :
self . fw_model . appendChild ( item )
else :
2016-06-21 02:03:32 +02:00
QMessageBox . warning ( None , " Invalid service name " ,
" Service ' {0} ' is unknown. " . format ( service ) )
2012-02-10 00:30:45 +01:00
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>
def handle_exception ( exc_type , exc_value , exc_traceback ) :
import sys
import os . path
import traceback
filename , line , dummy , dummy = traceback . extract_tb ( exc_traceback ) . pop ( )
filename = os . path . basename ( filename )
error = " %s : %s " % ( exc_type . __name__ , exc_value )
2012-03-14 14:00:49 +01:00
strace = " "
stacktrace = traceback . extract_tb ( exc_traceback )
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
msg_box = QMessageBox ( )
msg_box . setDetailedText ( strace )
msg_box . setIcon ( QMessageBox . Critical )
msg_box . setWindowTitle ( " Houston, we have a problem... " )
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
def main ( ) :
global qubes_host
qubes_host = QubesHost ( )
global app
app = QApplication ( sys . argv )
app . setOrganizationName ( " The Qubes Project " )
app . setOrganizationDomain ( " http://qubes-os.org " )
app . setApplicationName ( " Qubes VM Settings " )
sys . excepthook = handle_exception
qvm_collection = QubesVmCollection ( )
qvm_collection . lock_db_for_reading ( )
qvm_collection . load ( )
qvm_collection . unlock_db ( )
vm = None
2012-04-25 14:25:26 +02:00
tab = " basic "
2012-01-31 11:17:09 +01:00
if len ( sys . argv ) > 1 :
vm = qvm_collection . get_vm_by_name ( sys . argv [ 1 ] )
if vm is None or vm . qid not in qvm_collection :
QMessageBox . critical ( None , " Qubes VM Settings Error " ,
" A VM with the name ' {0} ' does not exist in the system. " . format ( sys . argv [ 1 ] ) )
sys . exit ( 1 )
2012-04-25 14:25:26 +02:00
if len ( sys . argv ) > 2 :
tab_arg = sys . argv [ 2 ]
2012-04-25 15:08:21 +02:00
print tab_arg
2012-04-25 14:25:26 +02:00
if tab_arg in VMSettingsWindow . tabs_indices :
tab = tab_arg
else : QMessageBox . warning ( None , " Qubes VM Settings Error " ,
" There is no such tab as ' {0} ' . Opening default tab instead. " . format ( tab_arg ) )
2012-01-31 11:17:09 +01:00
else :
vms_list = [ vm . name for vm in qvm_collection . values ( ) if ( vm . is_appvm ( ) or vm . is_template ( ) ) ]
vmname = QInputDialog . getItem ( None , " Select VM " , " Select VM: " , vms_list , editable = False )
if not vmname [ 1 ] :
sys . exit ( 1 )
vm = qvm_collection . get_vm_by_name ( vmname [ 0 ] )
2012-02-09 19:47:21 +01:00
2012-01-31 11:17:09 +01:00
global settings_window
2012-04-25 15:08:21 +02:00
settings_window = VMSettingsWindow ( vm , app , qvm_collection , tab )
2012-01-31 11:17:09 +01:00
settings_window . show ( )
app . exec_ ( )
app . exit ( )
if __name__ == " __main__ " :
main ( )
2012-05-19 09:33:29 +02:00
# vim:sw=4:et: