Merge branch 'master' of git.qubes-os.org:/var/lib/qubes/git/aga/qubes-manager
This commit is contained in:
commit
7dfbde248c
@ -17,7 +17,7 @@
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>System defaults</string>
|
||||
@ -37,7 +37,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="updateVMcombo"/>
|
||||
<widget class="QComboBox" name="update_vm_combo"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
@ -47,7 +47,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="clockVMcombo"/>
|
||||
<widget class="QComboBox" name="clock_vm_combo"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
@ -57,7 +57,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="defaultNetVMcombo"/>
|
||||
<widget class="QComboBox" name="default_netvm_combo"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
@ -73,7 +73,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="defaultTemplateVMCombo"/>
|
||||
<widget class="QComboBox" name="default_template_combo"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
@ -81,81 +81,78 @@
|
||||
<item row="0" column="1">
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Default memory settings</string>
|
||||
</property>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>11</x>
|
||||
<y>26</y>
|
||||
<width>134</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Minimal VM's memory:</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>11</x>
|
||||
<y>57</y>
|
||||
<width>139</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>dom0 memory margin:</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QSpinBox" name="minVMmem">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>156</x>
|
||||
<y>26</y>
|
||||
<width>121</width>
|
||||
<height>25</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> MB</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>999999999</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>10</number>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QSpinBox" name="dom0memMargin">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>156</x>
|
||||
<y>57</y>
|
||||
<width>121</width>
|
||||
<height>25</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> MB</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>999999999</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>50</number>
|
||||
</property>
|
||||
</widget>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Minimal VM's memory:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QSpinBox" name="min_vm_mem">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> MB</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>999999999</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>10</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>dom0 memory margin:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QSpinBox" name="dom0_mem_margin">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> MB</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>999999999</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>50</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="dispvm_in_memory">
|
||||
<property name="text">
|
||||
<string>Keep dispVM in memory</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Kernel</string>
|
||||
@ -169,7 +166,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="comboBox_5"/>
|
||||
<widget class="QComboBox" name="default_kernel_combo"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
@ -30,6 +30,7 @@ from qubes.qubes import QubesVmCollection
|
||||
from qubes.qubes import QubesException
|
||||
from qubes.qubes import QubesDaemonPidfile
|
||||
from qubes.qubes import QubesHost
|
||||
from qubes.qubes import qubes_kernels_base_dir
|
||||
|
||||
import qubesmanager.resources_rc
|
||||
|
||||
@ -42,18 +43,183 @@ from operator import itemgetter
|
||||
|
||||
from ui_globalsettingsdlg import *
|
||||
|
||||
dont_keep_dvm_in_memory_path = '/var/lib/qubes/dvmdata/dont_use_shm'
|
||||
|
||||
|
||||
class GlobalSettingsWindow(Ui_GlobalSettings, QDialog):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
def __init__(self, app, qvm_collection, parent=None):
|
||||
super(GlobalSettingsWindow, self).__init__(parent)
|
||||
|
||||
self.app = app
|
||||
self.qvm_collection = qvm_collection
|
||||
|
||||
self.setupUi(self)
|
||||
|
||||
self.connect(self.buttonBox, SIGNAL("accepted()"), self.save_and_apply)
|
||||
self.connect(self.buttonBox, SIGNAL("rejected()"), self.reject)
|
||||
|
||||
self.__init_system_defaults__()
|
||||
self.__init_kernel_defaults__()
|
||||
self.__init_mem_defaults__()
|
||||
|
||||
|
||||
def __init_system_defaults__(self):
|
||||
#updatevm and clockvm
|
||||
all_vms = [vm for vm in self.qvm_collection.values() if not vm.internal]
|
||||
self.updatevm_idx = -1
|
||||
|
||||
current_update_vm = self.qvm_collection.get_updatevm_vm()
|
||||
for (i, vm) in enumerate(all_vms):
|
||||
text = vm.name
|
||||
if vm is current_update_vm:
|
||||
self.updatevm_idx = i
|
||||
text += " (current)"
|
||||
self.update_vm_combo.insertItem(i, text)
|
||||
self.update_vm_combo.insertItem(len(all_vms), "none")
|
||||
if current_update_vm is None:
|
||||
self.updatevm_idx = len(all_vms)
|
||||
self.update_vm_combo.setCurrentIndex(self.updatevm_idx)
|
||||
|
||||
#clockvm
|
||||
self.clockvm_idx = -1
|
||||
|
||||
current_clock_vm = self.qvm_collection.get_clockvm_vm()
|
||||
for (i, vm) in enumerate(all_vms):
|
||||
text = vm.name
|
||||
if vm is current_clock_vm:
|
||||
self.clockvm_idx = i
|
||||
text += " (current)"
|
||||
self.clock_vm_combo.insertItem(i, text)
|
||||
self.clock_vm_combo.insertItem(len(all_vms), "none")
|
||||
if current_clock_vm is None:
|
||||
self.clockvm_idx = len(all_vms)
|
||||
self.clock_vm_combo.setCurrentIndex(self.clockvm_idx)
|
||||
|
||||
#default netvm
|
||||
netvms = [vm for vm in all_vms if vm.is_netvm()]
|
||||
self.netvm_idx = -1
|
||||
|
||||
current_netvm = self.qvm_collection.get_default_netvm()
|
||||
for (i, vm) in enumerate(netvms):
|
||||
text = vm.name
|
||||
if vm is current_netvm:
|
||||
self.netvm_idx = i
|
||||
text += " (current)"
|
||||
self.default_netvm_combo.insertItem(i, text)
|
||||
if current_netvm is not None:
|
||||
self.default_netvm_combo.setCurrentIndex(self.netvm_idx)
|
||||
|
||||
#default template
|
||||
templates = [vm for vm in all_vms if vm.is_template()]
|
||||
self.template_idx = -1
|
||||
|
||||
current_template = self.qvm_collection.get_default_template()
|
||||
for (i, vm) in enumerate(templates):
|
||||
text = vm.name
|
||||
if vm is current_template:
|
||||
self.template_idx = i
|
||||
text += " (current)"
|
||||
self.default_template_combo.insertItem(i, text)
|
||||
if current_template is not None:
|
||||
self.default_template_combo.setCurrentIndex(self.template_idx)
|
||||
|
||||
def __apply_system_defaults__(self):
|
||||
#upatevm
|
||||
if self.update_vm_combo.currentIndex() != self.updatevm_idx:
|
||||
updatevm_name = self.update_vm_combo.currentText()
|
||||
updatevm_name = updatevm_name.split(' ')[0]
|
||||
updatevm = self.qvm_collection.get_vm_by_name(updatevm_name)
|
||||
|
||||
self.qvm_collection.set_updatevm_vm(updatevm)
|
||||
self.anything_changed = True
|
||||
|
||||
#clockvm
|
||||
if self.clock_vm_combo.currentIndex() != self.clockvm_idx:
|
||||
clockvm_name = self.clock_vm_combo.currentText()
|
||||
clockvm_name = clockvm_name.split(' ')[0]
|
||||
clockvm = self.qvm_collection.get_vm_by_name(clockvm_name)
|
||||
|
||||
self.qvm_collection.set_clockvm_vm(clockvm)
|
||||
self.anything_changed = True
|
||||
|
||||
#default netvm
|
||||
if self.default_netvm_combo.currentIndex() != self.netvm_idx:
|
||||
name = self.default_netvm_combo.currentText()
|
||||
name = name.split(' ')[0]
|
||||
vm = self.qvm_collection.get_vm_by_name(name)
|
||||
|
||||
self.qvm_collection.set_default_netvm(vm)
|
||||
self.anything_changed = True
|
||||
|
||||
#default template
|
||||
if self.default_template_combo.currentIndex() != self.template_idx:
|
||||
name = self.default_template_combo.currentText()
|
||||
name = name.split(' ')[0]
|
||||
vm = self.qvm_collection.get_vm_by_name(name)
|
||||
|
||||
self.qvm_collection.set_default_template(vm)
|
||||
self.anything_changed = True
|
||||
|
||||
|
||||
def __init_kernel_defaults__(self):
|
||||
kernel_list = []
|
||||
for k in os.listdir(qubes_kernels_base_dir):
|
||||
kernel_list.append(k)
|
||||
|
||||
self.kernel_idx = 0
|
||||
|
||||
for (i, k) in enumerate(kernel_list):
|
||||
text = k
|
||||
if k == self.qvm_collection.get_default_kernel():
|
||||
text += " (current)"
|
||||
self.kernel_idx = i
|
||||
self.default_kernel_combo.insertItem(i,text)
|
||||
self.default_kernel_combo.setCurrentIndex(self.kernel_idx)
|
||||
|
||||
def __apply_kernel_defaults__(self):
|
||||
if self.default_kernel_combo.currentIndex() != self.kernel_idx:
|
||||
kernel = self.default_kernel_combo.currentText()
|
||||
kernel = kernel.split(' ')[0]
|
||||
|
||||
self.qvm_collection.set_default_kernel(kernel)
|
||||
self.anything_changed = True
|
||||
|
||||
|
||||
def __init_mem_defaults__(self):
|
||||
|
||||
#keep dispvm in memory
|
||||
exists = os.path.exists(dont_keep_dvm_in_memory_path)
|
||||
self.dispvm_in_memory.setChecked( not exists)
|
||||
|
||||
|
||||
def __apply_mem_defaults__(self):
|
||||
|
||||
#keep dispvm in memory
|
||||
was_checked = not os.path.exists(dont_keep_dvm_in_memory_path)
|
||||
if was_checked != self.dispvm_in_memory.isChecked():
|
||||
if was_checked:
|
||||
#touch file
|
||||
open(dont_keep_dvm_in_memory_path, 'w').close()
|
||||
else:
|
||||
#rm file
|
||||
os.remove(dont_keep_dvm_in_memory_path)
|
||||
self.anything_changed = True
|
||||
|
||||
def reject(self):
|
||||
self.done(0)
|
||||
|
||||
def save_and_apply(self):
|
||||
pass
|
||||
self.qvm_collection.lock_db_for_writing()
|
||||
|
||||
self.anything_changed = False
|
||||
self.__apply_system_defaults__()
|
||||
self.__apply_kernel_defaults__()
|
||||
self.__apply_mem_defaults__()
|
||||
|
||||
if self.anything_changed == True:
|
||||
self.qvm_collection.save()
|
||||
self.qvm_collection.unlock_db()
|
||||
|
||||
# Bases on the original code by:
|
||||
# Copyright (c) 2002-2007 Pascal Varet <p.varet@gmail.com>
|
||||
|
@ -1119,7 +1119,7 @@ class VmManagerWindow(Ui_VmManagerWindow, QMainWindow):
|
||||
|
||||
@pyqtSlot(name='on_action_global_settings_triggered')
|
||||
def action_global_settings_triggered(self):
|
||||
global_settings_window = GlobalSettingsWindow()
|
||||
global_settings_window = GlobalSettingsWindow(app, self.qvm_collection)
|
||||
global_settings_window.exec_()
|
||||
|
||||
|
||||
@ -1382,14 +1382,28 @@ def handle_exception( exc_type, exc_value, exc_traceback ):
|
||||
filename = os.path.basename( filename )
|
||||
error = "%s: %s" % ( exc_type.__name__, exc_value )
|
||||
|
||||
QMessageBox.critical(None, "Houston, we have a problem...",
|
||||
"Whoops. A critical error has occured. This is most likely a bug "
|
||||
"in Qubes Manager.<br><br>"
|
||||
"<b><i>%s</i></b>" % error +
|
||||
"at <b>line %d</b> of file <b>%s</b>.<br/><br/>"
|
||||
% ( line, filename ))
|
||||
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 ))
|
||||
|
||||
msg_box.exec_()
|
||||
|
||||
#sys.exit(1)
|
||||
|
||||
def main():
|
||||
|
||||
|
@ -34,6 +34,7 @@ from qubes.qubes import qubes_appmenu_remove_cmd
|
||||
from qubes.qubes import QubesDaemonPidfile
|
||||
from qubes.qubes import QubesHost
|
||||
from qubes.qubes import qrexec_client_path
|
||||
from qubes.qubes import qubes_kernels_base_dir
|
||||
|
||||
import qubesmanager.resources_rc
|
||||
|
||||
@ -43,6 +44,7 @@ import subprocess
|
||||
import time
|
||||
import threading
|
||||
from operator import itemgetter
|
||||
from copy import copy
|
||||
|
||||
from ui_settingsdlg import *
|
||||
from multiselectwidget import *
|
||||
@ -86,6 +88,9 @@ class VMSettingsWindow(Ui_SettingsDialog, QDialog):
|
||||
###### basic tab
|
||||
self.__init_basic_tab__()
|
||||
|
||||
###### advanced tab
|
||||
self.__init_advanced_tab__()
|
||||
|
||||
###### firewall tab
|
||||
if self.tabWidget.isTabEnabled(self.tabs_indices["firewall"]):
|
||||
|
||||
@ -98,9 +103,13 @@ class VMSettingsWindow(Ui_SettingsDialog, QDialog):
|
||||
self.deleteRuleButton.clicked.connect(self.delete_rule_button_pressed)
|
||||
|
||||
####### devices tab
|
||||
self.dev_list = MultiSelectWidget(self)
|
||||
self.devices_layout.addWidget(self.dev_list)
|
||||
self.__init_devices_tab__()
|
||||
|
||||
####### services tab
|
||||
self.__init_services_tab__()
|
||||
self.add_srv_button.clicked.connect(self.__add_service__)
|
||||
self.remove_srv_button.clicked.connect(self.__remove_service__)
|
||||
|
||||
####### apps tab
|
||||
if self.tabWidget.isTabEnabled(self.tabs_indices["applications"]):
|
||||
self.app_list = MultiSelectWidget(self)
|
||||
@ -142,6 +151,9 @@ class VMSettingsWindow(Ui_SettingsDialog, QDialog):
|
||||
self.anything_changed = False
|
||||
|
||||
ret = self.__apply_basic_tab__()
|
||||
self.__apply_advanced_tab__()
|
||||
self.__apply_devices_tab__()
|
||||
self.__apply_services_tab__()
|
||||
|
||||
if len(ret) > 0 :
|
||||
thread_monitor.set_error_msg('\n'.join(ret))
|
||||
@ -189,7 +201,8 @@ class VMSettingsWindow(Ui_SettingsDialog, QDialog):
|
||||
|
||||
if not self.vm.is_template() and self.vm.template is not None:
|
||||
template_vm_list = [vm for vm in self.qvm_collection.values() if not vm.internal and vm.is_template()]
|
||||
self.template_idx = 0
|
||||
self.template_idx = -1
|
||||
|
||||
for (i, vm) in enumerate(template_vm_list):
|
||||
text = vm.name
|
||||
if vm is self.qvm_collection.get_default_template():
|
||||
@ -201,27 +214,36 @@ class VMSettingsWindow(Ui_SettingsDialog, QDialog):
|
||||
self.template_name.setCurrentIndex(self.template_idx)
|
||||
else:
|
||||
self.template_name.setEnabled(False)
|
||||
self.template_idx = -1
|
||||
|
||||
|
||||
if (not self.vm.is_netvm() or self.vm.is_proxyvm()):
|
||||
netvm_list = [vm for vm in self.qvm_collection.values() if not vm.internal and vm.is_netvm()]
|
||||
self.netvm_idx = -1
|
||||
|
||||
text = "default ("+self.qvm_collection.get_default_netvm().name+")"
|
||||
if self.vm.uses_default_netvm:
|
||||
text += " (current)"
|
||||
self.netvm_idx = 0
|
||||
self.netVM.insertItem(0, text)
|
||||
|
||||
for (i, vm) in enumerate(netvm_list):
|
||||
text = vm.name
|
||||
if vm is self.qvm_collection.get_default_netvm():
|
||||
text += " (default)"
|
||||
if self.vm.netvm is not None and vm.qid == self.vm.netvm.qid:
|
||||
self.netvm_idx = i
|
||||
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
|
||||
text += " (current)"
|
||||
self.netVM.insertItem(i, text)
|
||||
self.netVM.insertItem(i+1, text)
|
||||
|
||||
none_text = "none"
|
||||
if self.vm.netvm is None:
|
||||
none_text += " (current)"
|
||||
self.netvm_idx = len(netvm_list)
|
||||
self.netVM.insertItem(len(netvm_list), none_text)
|
||||
self.netvm_idx = len(netvm_list)+1
|
||||
self.netVM.insertItem(len(netvm_list)+1, none_text)
|
||||
|
||||
self.netVM.setCurrentIndex(self.netvm_idx)
|
||||
else:
|
||||
self.netVM.setEnabled(False)
|
||||
self.netvm_idx = -1
|
||||
|
||||
self.include_in_backups.setChecked(self.vm.include_in_backups)
|
||||
|
||||
@ -241,13 +263,11 @@ class VMSettingsWindow(Ui_SettingsDialog, QDialog):
|
||||
else:
|
||||
self.networking_groupbox.setEnabled(False);
|
||||
|
||||
#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)
|
||||
|
||||
#max priv size
|
||||
self.priv_size.setValue(int(self.vm.memory))
|
||||
self.priv_size.setMaximum(QubesHost().memory_total/1024)
|
||||
|
||||
#self.vmname.selectAll()
|
||||
#self.vmname.setFocus()
|
||||
|
||||
def __apply_basic_tab__(self):
|
||||
msg = []
|
||||
@ -262,9 +282,7 @@ class VMSettingsWindow(Ui_SettingsDialog, QDialog):
|
||||
else:
|
||||
oldname = self.vm.name
|
||||
try:
|
||||
self.vm.pre_rename(vmname)
|
||||
self.vm.set_name(vmname)
|
||||
self.vm.post_rename(oldname)
|
||||
self.anything_changed = True
|
||||
except Exception as ex:
|
||||
msg.append(str(ex))
|
||||
@ -289,25 +307,218 @@ class VMSettingsWindow(Ui_SettingsDialog, QDialog):
|
||||
if self.netVM.currentIndex() != self.netvm_idx:
|
||||
new_netvm_name = self.netVM.currentText()
|
||||
new_netvm_name = new_netvm_name.split(' ')[0]
|
||||
netvm = self.qvm_collection.get_vm_by_name(new_netvm_name)
|
||||
assert (netvm is not None and netvm.qid in self.qvm_collection)
|
||||
assert netvm.is_netvm()
|
||||
self.vm.uses_default_netvm = (self.vm is self.qvm_collection.get_default_netvm())
|
||||
|
||||
uses_default_netvm = False
|
||||
|
||||
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
|
||||
|
||||
#include in backups
|
||||
if self.vm.include_in_backups != self.include_in_backups.isChecked():
|
||||
self.vm.include_in_backups = self.include_in_backups.isChecked()
|
||||
|
||||
#max priv size
|
||||
priv_size = self.priv_size.value()
|
||||
if self.vm.memory != priv_size:
|
||||
self.vm.memory = priv_size
|
||||
self.anything_changed = True
|
||||
#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))
|
||||
|
||||
|
||||
return msg
|
||||
|
||||
|
||||
|
||||
######### advanced tab
|
||||
|
||||
def __init_advanced_tab__(self):
|
||||
|
||||
#mem/cpu
|
||||
self.init_mem.setValue(int(self.vm.memory))
|
||||
self.init_mem.setMaximum(int(self.vm.maxmem))
|
||||
|
||||
self.max_mem_size.setValue(int(self.vm.maxmem))
|
||||
self.max_mem_size.setMaximum(QubesHost().memory_total/1024)
|
||||
|
||||
self.vcpus.setMinimum(1);
|
||||
self.vcpus.setMaximum(QubesHost().no_cpus)
|
||||
self.vcpus.setValue(int(self.vm.vcpus))
|
||||
|
||||
self.include_in_balancing.setChecked('meminfo-writer' in self.vm.services and self.vm.services['meminfo-writer']==True)
|
||||
|
||||
#kernel
|
||||
if self.vm.template is not None:
|
||||
text = self.vm.kernel
|
||||
self.kernel.insertItem(0, text)
|
||||
self.kernel.setEnabled(False)
|
||||
self.kernel_idx = 0
|
||||
else:
|
||||
text = "default (" + self.qvm_collection.get_default_kernel() +")"
|
||||
kernel_list = [text]
|
||||
for k in os.listdir(qubes_kernels_base_dir):
|
||||
kernel_list.append(k)
|
||||
kernel_list.append("none")
|
||||
|
||||
self.kernel_idx = 0
|
||||
|
||||
for (i, k) in enumerate(kernel_list):
|
||||
text = k
|
||||
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)
|
||||
|
||||
|
||||
|
||||
#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)
|
||||
else:
|
||||
self.root_img_path.setText("n/a")
|
||||
self.volatile_img_path.setText(self.vm.volatile_img)
|
||||
self.private_img_path.setText(self.vm.private_img)
|
||||
|
||||
def __apply_advanced_tab__(self):
|
||||
|
||||
#mem/cpu
|
||||
if self.init_mem.value() != int(self.vm.memory):
|
||||
self.vm.memory = self.init_mem.value()
|
||||
self.anything_changed = True
|
||||
|
||||
if self.max_mem_size.value() != int(self.vm.maxmem):
|
||||
self.vm.maxmem = self.max_mem_size.value()
|
||||
self.anything_changed = True
|
||||
|
||||
if self.vcpus.value() != int(self.vm.vcpus):
|
||||
self.vm.vcpus = self.vcpus.value()
|
||||
self.anything_changed = True
|
||||
|
||||
balancing_was_checked = ('meminfo-writer' in self.vm.services and self.vm.services['meminfo-writer']==True)
|
||||
if self.include_in_balancing.isChecked() != balancing_was_checked:
|
||||
self.new_srv_dict['meminfo-writer'] = self.include_in_balancing.isChecked()
|
||||
self.anything_changed = True
|
||||
|
||||
#kernel changed
|
||||
if self.kernel.currentIndex() != self.kernel_idx:
|
||||
new_kernel = self.kernel.currentText()
|
||||
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
|
||||
|
||||
######## devices tab
|
||||
def __init_devices_tab__(self):
|
||||
self.dev_list = MultiSelectWidget(self)
|
||||
self.devices_layout.addWidget(self.dev_list)
|
||||
|
||||
devs = []
|
||||
lspci = subprocess.Popen(["lspci",], stdout = subprocess.PIPE)
|
||||
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
|
||||
|
||||
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]))
|
||||
|
||||
|
||||
def __apply_devices_tab__(self):
|
||||
sth_changed = False
|
||||
added = []
|
||||
|
||||
for i in range(self.dev_list.selected_list.count()):
|
||||
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
|
||||
sth_changed = True;
|
||||
elif len(added) > 0:
|
||||
sth_changed = True;
|
||||
|
||||
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
|
||||
|
||||
|
||||
######## 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)
|
||||
self.new_srv_dict = copy(self.vm.services)
|
||||
|
||||
def __add_service__(self):
|
||||
srv = str(self.service_line_edit.text()).strip()
|
||||
if srv != "" and srv not in self.new_srv_dict:
|
||||
item = QListWidgetItem(srv)
|
||||
item.setCheckState(QtCore.Qt.Checked)
|
||||
self.services_list.addItem(item)
|
||||
self.new_srv_dict[srv] = True
|
||||
|
||||
def __remove_service__(self):
|
||||
row = self.services_list.currentRow()
|
||||
if row:
|
||||
item = self.services_list.takeItem(row)
|
||||
print item.text()
|
||||
del self.new_srv_dict[str(item.text())]
|
||||
|
||||
def __apply_services_tab__(self):
|
||||
new_dict = {}
|
||||
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)
|
||||
|
||||
if self.new_srv_dict != self.vm.services:
|
||||
self.vm.services = self.new_srv_dict
|
||||
self.anything_changed = True
|
||||
|
||||
|
||||
######### firewall tab related
|
||||
|
||||
def set_fw_model(self, model):
|
||||
@ -420,12 +631,27 @@ def handle_exception( exc_type, exc_value, exc_traceback ):
|
||||
filename = os.path.basename( filename )
|
||||
error = "%s: %s" % ( exc_type.__name__, exc_value )
|
||||
|
||||
QMessageBox.critical(None, "Houston, we have a problem...",
|
||||
"Whoops. A critical error has occured. This is most likely a bug "
|
||||
"in Qubes VM Settings application.<br><br>"
|
||||
"<b><i>%s</i></b>" % error +
|
||||
"at <b>line %d</b> of file <b>%s</b>.<br/><br/>"
|
||||
% ( line, filename ))
|
||||
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 ))
|
||||
|
||||
msg_box.exec_()
|
||||
|
||||
|
||||
def main():
|
||||
|
133
settingsdlg.ui
133
settingsdlg.ui
@ -122,8 +122,8 @@
|
||||
<widget class="QLabel" name="type_label">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
@ -142,8 +142,8 @@
|
||||
<widget class="QLabel" name="rpm_label">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
@ -163,8 +163,15 @@
|
||||
<string>Disk storage</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Private storage max. size:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QSpinBox" name="priv_size">
|
||||
<widget class="QSpinBox" name="max_priv_storage">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
@ -172,16 +179,16 @@
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>256</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>10000</number>
|
||||
<number>1048576</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>256</number>
|
||||
<number>1024</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>256</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@ -192,13 +199,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Private storage max. size:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
@ -232,8 +232,8 @@
|
||||
<widget class="QLabel" name="ip_label">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
@ -252,8 +252,8 @@
|
||||
<widget class="QLabel" name="netmask_label">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
@ -272,8 +272,8 @@
|
||||
<widget class="QLabel" name="gateway_label">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
@ -288,7 +288,7 @@
|
||||
</widget>
|
||||
<widget class="QWidget" name="advanced_tab">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="title">
|
||||
<string>Advanced</string>
|
||||
@ -296,35 +296,50 @@
|
||||
<layout class="QGridLayout" name="gridLayout_9">
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Memory/CPU</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_15">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Initial memory:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="mem_size">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>xx</string>
|
||||
<widget class="QSpinBox" name="init_mem">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>256</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>10000</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>256</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>256</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="label_16">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>MB</string>
|
||||
</property>
|
||||
@ -340,7 +355,7 @@
|
||||
<item row="1" column="1">
|
||||
<widget class="QSpinBox" name="max_mem_size">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
@ -376,7 +391,7 @@
|
||||
<item row="2" column="1">
|
||||
<widget class="QSpinBox" name="vcpus">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
@ -388,6 +403,9 @@
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="include_in_balancing">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Include in memory balancing</string>
|
||||
</property>
|
||||
@ -398,6 +416,9 @@
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QGroupBox" name="groupBox_10">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Kernel</string>
|
||||
</property>
|
||||
@ -423,8 +444,8 @@
|
||||
<widget class="QLabel" name="kernel_opts">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
@ -437,6 +458,9 @@
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QGroupBox" name="groupBox_11">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Paths</string>
|
||||
</property>
|
||||
@ -700,7 +724,7 @@
|
||||
</widget>
|
||||
<widget class="QWidget" name="devices_tab">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="title">
|
||||
<string>Devices</string>
|
||||
@ -727,17 +751,17 @@
|
||||
</widget>
|
||||
<widget class="QWidget" name="services_tab">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="title">
|
||||
<string>Services</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLineEdit" name="service_lineEdit"/>
|
||||
<widget class="QLineEdit" name="service_line_edit"/>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QPushButton" name="add_button">
|
||||
<widget class="QPushButton" name="add_srv_button">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
@ -754,32 +778,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" rowspan="2">
|
||||
<widget class="QListWidget" name="services_list">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>ntpd</string>
|
||||
</property>
|
||||
<property name="checkState">
|
||||
<enum>Checked</enum>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>cupsd</string>
|
||||
</property>
|
||||
<property name="checkState">
|
||||
<enum>Checked</enum>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>meminfo</string>
|
||||
</property>
|
||||
<property name="checkState">
|
||||
<enum>Checked</enum>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
<widget class="QListWidget" name="services_list"/>
|
||||
</item>
|
||||
<item row="6" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_7">
|
||||
@ -803,7 +802,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QPushButton" name="remove_button">
|
||||
<widget class="QPushButton" name="remove_srv_button">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
|
Loading…
Reference in New Issue
Block a user