Merge branch 'master' of git.qubes-os.org:/var/lib/qubes/git/aga/qubes-manager

This commit is contained in:
Joanna Rutkowska 2012-03-07 11:43:04 +01:00
commit 1cc9a3e859
5 changed files with 117 additions and 74 deletions

View File

@ -150,7 +150,7 @@
</column>
<column>
<property name="text">
<string>Upd</string>
<string>Up</string>
</property>
<property name="toolTip">
<string>Update info</string>

View File

@ -38,13 +38,6 @@
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Port</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
@ -133,38 +126,6 @@
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="tcp_port_lineedit">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="inputMethodHints">
<set>Qt::ImhDigitsOnly</set>
</property>
<property name="maxLength">
<number>5</number>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QLineEdit" name="udp_port_lineedit">
<property name="enabled">
<bool>false</bool>
</property>
<property name="inputMethodHints">
<set>Qt::ImhDigitsOnly</set>
</property>
<property name="maxLength">
<number>5</number>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">

View File

@ -81,12 +81,13 @@ class NewFwRuleDlg (QDialog, ui_newfwruledlg.Ui_NewFwRuleDlg):
self.set_ok_enabled(False)
self.addressComboBox.setValidator(QIPAddressValidator())
self.addressComboBox.editTextChanged.connect(self.address_editing_finished)
self.serviceComboBox.setValidator(QRegExpValidator(QRegExp("\*|[a-z][a-z0-9-]+|[0-9]+(-[0-9]+)?", Qt.CaseInsensitive), None))
self.serviceComboBox.setValidator(QRegExpValidator(QRegExp("[a-z][a-z0-9-]+|[0-9]+(-[0-9]+)?", Qt.CaseInsensitive), None))
self.serviceComboBox.setEnabled(False)
self.serviceComboBox.setInsertPolicy(QComboBox.InsertAtBottom)
self.populate_combos()
self.serviceComboBox.setInsertPolicy(QComboBox.InsertAtTop)
def populate_combos(self):
example_addresses = [
"", "www.example.com",
@ -100,7 +101,7 @@ class NewFwRuleDlg (QDialog, ui_newfwruledlg.Ui_NewFwRuleDlg):
'ssh', 'telnet', 'telnets', 'ntp', 'snmp',
'ldap', 'ldaps', 'irc', 'ircs', 'xmpp-client',
'syslog', 'printer', 'nfs', 'x11',
'*', '1024-1234'
'1024-1234'
]
for address in example_addresses:
self.addressComboBox.addItem(address)
@ -116,26 +117,25 @@ class NewFwRuleDlg (QDialog, ui_newfwruledlg.Ui_NewFwRuleDlg):
ok_button.setEnabled(on)
def on_tcp_radio_toggled(self, checked):
self.tcp_port_lineedit.setEnabled(checked)
self.udp_port_lineedit.setEnabled(not checked)
if checked:
self.serviceComboBox.setEnabled(True)
def on_udp_radio_toggled(self, checked):
self.tcp_port_lineedit.setEnabled(not checked)
self.udp_port_lineedit.setEnabled(checked)
if checked:
self.serviceComboBox.setEnabled(True)
def on_any_radio_toggled(self, checked):
self.tcp_port_lineedit.setEnabled(not checked)
self.udp_port_lineedit.setEnabled(not checked)
if checked:
self.serviceComboBox.setEnabled(False)
class QubesFirewallRuleItem(object):
def __init__(self, address = str(), netmask = 32, portBegin = 0, portEnd = None):
def __init__(self, address = str(), netmask = 32, portBegin = 0, portEnd = None, protocol = "any"):
self.__address = address
self.__netmask = netmask
self.__portBegin = portBegin
self.__portEnd = portEnd
self.__protocol = protocol
@property
def address(self):
@ -153,6 +153,10 @@ class QubesFirewallRuleItem(object):
def portEnd(self):
return self.__portEnd
@property
def protocol(self):
return self.__protocol
def hasChildren(self):
return False
@ -166,13 +170,15 @@ class QubesFirewallRulesModel(QAbstractItemModel):
0: lambda x: "*" if self.children[x].address == "0.0.0.0" and self.children[x].netmask == 0 \
else self.children[x].address + ("" if self.children[x].netmask == 32 \
else " /{0}".format(self.children[x].netmask)),
1: lambda x: "*" if self.children[x].portBegin == 0 \
1: lambda x: "any" if self.children[x].portBegin == 0 \
else "{0}-{1}".format(self.children[x].portBegin, self.children[x].portEnd) if self.children[x].portEnd is not None \
else self.get_service_name(self.children[x].portBegin),
2: lambda x: self.children[x].protocol,
}
self.__columnNames = {
0: "Address",
1: "Service",
2: "Protocol",
}
self.__services = list()
@ -182,7 +188,7 @@ class QubesFirewallRulesModel(QAbstractItemModel):
match = pattern.match(line)
if match is not None:
service = match.groupdict()
self.__services.append( (service["name"], int(service["port"]), service["protocol"]) )
self.__services.append( (service["name"], int(service["port"]),) )
f.close()
def sort(self, idx, order):
@ -193,6 +199,8 @@ class QubesFirewallRulesModel(QAbstractItemModel):
self.children.sort(key=attrgetter('address'), reverse = rev)
if idx==1:
self.children.sort(key=lambda x: self.get_service_name(attrgetter('portBegin')) if attrgetter('portEnd') == None else attrgetter('portBegin'), reverse = rev)
if idx==2:
self.children.sort(key=attrgetter('protocol'), reverse = rev)
def get_service_name(self, port):
@ -223,7 +231,7 @@ class QubesFirewallRulesModel(QAbstractItemModel):
for rule in conf["rules"]:
self.appendChild(QubesFirewallRuleItem(
rule["address"], rule["netmask"], rule["portBegin"], rule["portEnd"]
rule["address"], rule["netmask"], rule["portBegin"], rule["portEnd"], rule["proto"]
))
def get_vm_name(self):
@ -244,7 +252,8 @@ class QubesFirewallRulesModel(QAbstractItemModel):
"address": rule.address,
"netmask": rule.netmask,
"portBegin": rule.portBegin,
"portEnd": rule.portEnd
"portEnd": rule.portEnd,
"proto": rule.protocol,
}
)

View File

@ -210,7 +210,7 @@ class VmUsageBarWidget (QWidget):
self.value = value
def __lt__(self, other):
return self.value < other.value
return int(self.value) < int(other.value)
def __init__(self, min, max, format, update_func, vm, load, hue=210, parent = None):
super (VmUsageBarWidget, self).__init__(parent)
@ -527,9 +527,13 @@ class VmManagerWindow(Ui_VmManagerWindow, QMainWindow):
self.actionCPU_Graph.setChecked(False)
self.table.setColumnHidden( self.columns_indices["MEM Graph"], True)
self.actionMEM_Graph.setChecked(False)
self.table.setColumnWidth(self.columns_indices["Upd"], 50)
self.table.setColumnWidth(self.columns_indices["Upd"], 40)
self.table.horizontalHeader().setResizeMode(QHeaderView.Fixed)
self.table.sortItems(self.columns_indices["MEM"], Qt.DescendingOrder)
self.sort_by_mem = None
self.sort_by_cpu = None
self.context_menu = QMenu(self)
self.context_menu.addAction(self.action_settings)
@ -546,6 +550,7 @@ class VmManagerWindow(Ui_VmManagerWindow, QMainWindow):
self.blk_menu = QMenu("Block devices")
self.context_menu.addMenu(self.blk_menu)
self.connect(self.table.horizontalHeader(), SIGNAL("sortIndicatorChanged(int, Qt::SortOrder)"), self.sortIndicatorChanged)
self.connect(self.table, SIGNAL("customContextMenuRequested(const QPoint&)"), self.open_context_menu)
self.connect(self.blk_menu, SIGNAL("triggered(QAction *)"), self.attach_dettach_device_triggered)
@ -553,12 +558,23 @@ class VmManagerWindow(Ui_VmManagerWindow, QMainWindow):
self.centralwidget.layout().setContentsMargins(0,0,0,0)
self.layout().setContentsMargins(0,0,0,0)
self.action_toolbar = QAction("tool bar", None)
self.action_toolbar.setCheckable(True)
self.action_toolbar.setChecked(True)
self.action_menubar = QAction("menu bar", None)
self.action_menubar.setCheckable(True)
self.action_menubar.setChecked(True)
self.connect(self.action_menubar, SIGNAL("toggled(bool)"), self.showhide_menubar)
self.connect(self.action_toolbar, SIGNAL("toggled(bool)"), self.showhide_toolbar)
self.counter = 0
self.shutdown_monitor = {}
self.last_measure_results = {}
self.last_measure_time = time.time()
QTimer.singleShot (self.update_interval, self.update_table)
def show(self):
super(VmManagerWindow, self).show()
self.set_table_geom_height()
@ -584,10 +600,15 @@ class VmManagerWindow(Ui_VmManagerWindow, QMainWindow):
self.centralwidget.setMinimumHeight(minH)
self.centralwidget.setMaximumHeight(maxH)
mainwindow_to_add = self.menubar.height() +\
self.toolbar.height() + \
self.menubar.contentsMargins().top() + self.menubar.contentsMargins().bottom() +\
self.toolbar.contentsMargins().top() + self.toolbar.contentsMargins().bottom()
mainwindow_to_add = 0
if self.menubar.isVisible():
mainwindow_to_add += self.menubar.height() + self.menubar.contentsMargins().top() + self.menubar.contentsMargins().bottom()
if self.toolbar.isVisible():
mainwindow_to_add += self.toolbar.height() + self.toolbar.contentsMargins().top() + self.toolbar.contentsMargins().bottom()
# in case both toolbar and menubar are hidden there must be an option to get them back
if mainwindow_to_add == 0:
mainwindow_to_add = 10
maxH += mainwindow_to_add
minH += mainwindow_to_add
@ -620,6 +641,8 @@ class VmManagerWindow(Ui_VmManagerWindow, QMainWindow):
label_list = QubesVmLabels.values()
label_list.sort(key=lambda l: l.index)
for label in [label.name for label in label_list]:
for appvm in [vm for vm in vms_list if ((vm.is_appvm() or vm.is_disposablevm()) and vm.label.name == label)]:
vms_to_display.append(appvm)
@ -696,6 +719,9 @@ class VmManagerWindow(Ui_VmManagerWindow, QMainWindow):
blk_visible = False
vm_row.update(self.counter, blk_visible=blk_visible, cpu_load = cur_cpu_load)
if self.sort_by_cpu != None:
self.table.sortItems(self.columns_indices["CPU"], self.sort_by_cpu)
else:
for vm_row in self.vms_in_table.values():
if rows_with_blk != None:
@ -705,6 +731,10 @@ class VmManagerWindow(Ui_VmManagerWindow, QMainWindow):
blk_visible = False
vm_row.update(self.counter, blk_visible=blk_visible)
if self.sort_by_cpu != None:
self.table.sortItems(self.columns_indices["CPU"], self.sort_by_cpu)
elif self.sort_by_mem != None:
self.table.sortItems(self.columns_indices["MEM"], self.sort_by_mem)
self.table_selection_changed()
@ -729,6 +759,17 @@ class VmManagerWindow(Ui_VmManagerWindow, QMainWindow):
trayIcon.showMessage ("Qubes Manager", str, msecs=5000)
return res
def sortIndicatorChanged(self, column, order):
if column == self.columns_indices["CPU"] or column == self.columns_indices["CPU Graph"]:
self.sort_by_mem = None
self.sort_by_cpu = order
elif column == self.columns_indices["MEM"] or column == self.columns_indices["MEM Graph"]:
self.sort_by_cpu = None
self.sort_by_mem = order
else:
self.sort_by_cpu = None
self.sort_by_mem = None
def table_selection_changed (self):
vm = self.get_selected_vm()
@ -1093,6 +1134,14 @@ class VmManagerWindow(Ui_VmManagerWindow, QMainWindow):
backup_window.exec_()
def showhide_menubar(self, checked):
self.menuWidget().setVisible(checked)
self.set_table_geom_height()
def showhide_toolbar(self, checked):
self.toolbar.setVisible(checked)
self.set_table_geom_height()
def showhide_collumn(self, col_num, show):
self.table.setColumnHidden( col_num, not show)
@ -1120,6 +1169,13 @@ class VmManagerWindow(Ui_VmManagerWindow, QMainWindow):
self.showhide_collumn( self.columns_indices['MEM Graph'], checked)
def createPopupMenu(self):
menu = QMenu()
menu.addAction(self.action_toolbar)
menu.addAction(self.action_menubar)
return menu
@pyqtSlot('const QPoint&')
def open_context_menu(self, point):
vm = self.get_selected_vm()

View File

@ -288,8 +288,18 @@ class VMSettingsWindow(Ui_SettingsDialog, QDialog):
dialog.addressComboBox.setItemText(0, address)
dialog.addressComboBox.setCurrentIndex(0)
service = self.fw_model.get_column_string(1, row)
if service == "any":
service = ""
dialog.serviceComboBox.setItemText(0, service)
dialog.serviceComboBox.setCurrentIndex(0)
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)
self.run_rule_dialog(dialog, row)
def delete_rule_button_pressed(self):
@ -314,23 +324,30 @@ class VMSettingsWindow(Ui_SettingsDialog, QDialog):
address = "0.0.0.0"
netmask = 0
if service == "*":
service = "0"
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)
if dialog.any_radio.isChecked():
protocol = "any"
port = 0
else:
if dialog.tcp_radio.isChecked():
protocol = "tcp"
elif dialog.udp_radio.isChecked():
protocol = "udp"
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)
if port is not None:
if port2 is not None and port2 <= port:
QMessageBox.warning(None, "Invalid service ports range", "Port {0} is lower than port {1}.".format(port2, port))
else:
item = QubesFirewallRuleItem(address, netmask, port, port2)
item = QubesFirewallRuleItem(address, netmask, port, port2, protocol)
if row is not None:
self.fw_model.setChild(row, item)
else: