Merge branch 'master' of https://github.com/QubesOS/qubes-manager into template_menu

# Conflicts:
#	qubesmanager/qube_manager.py
#	ui/qubemanager.ui
This commit is contained in:
donoban 2020-12-12 14:08:41 +01:00
commit 9152218921
No known key found for this signature in database
GPG Key ID: 141310D8E3ED08A5
4 changed files with 69 additions and 65 deletions

View File

@ -20,13 +20,12 @@
# #
# #
import sys import sys
import os
from functools import partial
from PyQt5 import QtWidgets # pylint: disable=import-error from PyQt5 import QtWidgets # pylint: disable=import-error
from qubesadmin import Qubes
from . import ui_logdlg # pylint: disable=no-name-in-module from . import ui_logdlg # pylint: disable=no-name-in-module
from . import clipboard from . import clipboard
import os
from qubesadmin import Qubes
# Display only this size of log # Display only this size of log
LOG_DISPLAY_SIZE = 1024*1024 LOG_DISPLAY_SIZE = 1024*1024
@ -35,14 +34,14 @@ LOG_DISPLAY_SIZE = 1024*1024
class LogDialog(ui_logdlg.Ui_LogDialog, QtWidgets.QDialog): class LogDialog(ui_logdlg.Ui_LogDialog, QtWidgets.QDialog):
# pylint: disable=too-few-public-methods # pylint: disable=too-few-public-methods
def __init__(self, app, log_path, parent=None): def __init__(self, app, logfiles, parent=None):
super().__init__(parent) super().__init__(parent)
self.app = app self.app = app
self.log_path = log_path self.logfiles = logfiles
self.displayed_text = ""
self.setupUi(self) self.setupUi(self)
self.setWindowTitle(log_path)
self.copy_to_qubes_clipboard.clicked.connect( self.copy_to_qubes_clipboard.clicked.connect(
self.copy_to_clipboard_triggered) self.copy_to_clipboard_triggered)
@ -52,8 +51,24 @@ class LogDialog(ui_logdlg.Ui_LogDialog, QtWidgets.QDialog):
self.__init_log_text__() self.__init_log_text__()
def __init_log_text__(self): def __init_log_text__(self):
btns_in_row = 3
count = 0
for log_path in self.logfiles:
button = QtWidgets.QPushButton(log_path)
button.clicked.connect(partial(self.set_current_log, log_path))
self.buttonsLayout.addWidget(button,
count / btns_in_row, count % btns_in_row)
count += 1
self.buttonsLayout.itemAt(0).widget().click()
def copy_to_clipboard_triggered(self):
clipboard.copy_text_to_qubes_clipboard(self.displayed_text)
def set_current_log(self, log_path):
self.displayed_text = "" self.displayed_text = ""
log = open(self.log_path) self.setWindowTitle(log_path)
log = open(log_path)
log.seek(0, os.SEEK_END) log.seek(0, os.SEEK_END)
if log.tell() > LOG_DISPLAY_SIZE: if log.tell() > LOG_DISPLAY_SIZE:
self.displayed_text = self.tr( self.displayed_text = self.tr(
@ -64,11 +79,6 @@ class LogDialog(ui_logdlg.Ui_LogDialog, QtWidgets.QDialog):
self.displayed_text += log.read() self.displayed_text += log.read()
log.close() log.close()
self.log_text.setPlainText(self.displayed_text) self.log_text.setPlainText(self.displayed_text)
self.log_text.show()
def copy_to_clipboard_triggered(self):
clipboard.copy_text_to_qubes_clipboard(self.displayed_text)
def main(): def main():
qubes_app = Qubes() qubes_app = Qubes()

View File

@ -21,11 +21,10 @@
# with this program; if not, see <http://www.gnu.org/licenses/>. # with this program; if not, see <http://www.gnu.org/licenses/>.
# #
# #
import os
import os.path
import subprocess import subprocess
from datetime import datetime, timedelta from datetime import datetime, timedelta
from functools import partial from functools import partial
from os import path
from qubesadmin import exc from qubesadmin import exc
from qubesadmin import utils from qubesadmin import utils
@ -708,8 +707,8 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QMainWindow):
lambda pos: self.open_tools_context_menu(self.toolbar, pos)) lambda pos: self.open_tools_context_menu(self.toolbar, pos))
self.action_menubar.toggled.connect(self.showhide_menubar) self.action_menubar.toggled.connect(self.showhide_menubar)
self.action_toolbar.toggled.connect(self.showhide_toolbar) self.action_toolbar.toggled.connect(self.showhide_toolbar)
self.action_show_logs.triggered.connect(self.show_log)
self.action_compact_view.toggled.connect(self.set_compactview) self.action_compact_view.toggled.connect(self.set_compactview)
self.logs_menu.triggered.connect(self.show_log)
self.table.resizeColumnsToContents() self.table.resizeColumnsToContents()
@ -895,8 +894,7 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QMainWindow):
self.context_menu.addAction(self.action_clonevm) self.context_menu.addAction(self.action_clonevm)
self.context_menu.addAction(self.action_removevm) self.context_menu.addAction(self.action_removevm)
self.context_menu.addSeparator() self.context_menu.addSeparator()
self.context_menu.addMenu(self.logs_menu) self.context_menu.addAction(self.action_show_logs)
self.context_menu.addSeparator()
def save_showing(self): def save_showing(self):
self.manager_settings.setValue('show/running', self.manager_settings.setValue('show/running',
@ -1199,7 +1197,6 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QMainWindow):
if not vm.updateable and vm.klass != 'AdminVM': if not vm.updateable and vm.klass != 'AdminVM':
self.action_updatevm.setEnabled(False) self.action_updatevm.setEnabled(False)
self.update_logs_menu()
self.update_template_menu() self.update_template_menu()
self.update_network_menu() self.update_network_menu()
@ -1650,48 +1647,42 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QMainWindow):
def open_tools_context_menu(self, widget, point): def open_tools_context_menu(self, widget, point):
self.tools_context_menu.exec_(widget.mapToGlobal(point)) self.tools_context_menu.exec_(widget.mapToGlobal(point))
def update_logs_menu(self):
self.logs_menu.clear()
menu_empty = True
try:
vm_info = self.get_selected_vms()
if len(vm_info) == 1:
vm = vm_info[0].vm
if vm.klass == 'AdminVM':
logfiles = ["/var/log/xen/console/hypervisor.log"]
else:
logfiles = [
"/var/log/xen/console/guest-" + vm.name + ".log",
"/var/log/xen/console/guest-" + vm.name + "-dm.log",
"/var/log/qubes/guid." + vm.name + ".log",
"/var/log/qubes/qrexec." + vm.name + ".log",
]
for logfile in logfiles:
if os.path.exists(logfile):
action = self.logs_menu.addAction(QIcon(":/log.png"),
logfile)
action.setData(logfile)
menu_empty = False
self.logs_menu.setEnabled(not menu_empty)
except exc.QubesDaemonAccessError:
pass
@pyqtSlot('const QPoint&') @pyqtSlot('const QPoint&')
def open_context_menu(self, point): def open_context_menu(self, point):
self.context_menu.exec_(self.table.mapToGlobal( self.context_menu.exec_(self.table.mapToGlobal(
point + QPoint(10, 0))) point + QPoint(10, 0)))
@pyqtSlot('QAction *') def show_log(self):
def show_log(self, action): logfiles = []
log = str(action.data())
log_dlg = log_dialog.LogDialog(self.qt_app, log)
log_dlg.exec_()
try:
for vm_info in self.get_selected_vms():
vm = vm_info.vm
if vm.klass == 'AdminVM':
logfiles.append("/var/log/xen/console/hypervisor.log")
else:
logfiles.extend([
"/var/log/xen/console/guest-" + vm.name + ".log",
"/var/log/xen/console/guest-" + vm.name + "-dm.log",
"/var/log/qubes/guid." + vm.name + ".log",
"/var/log/qubes/qrexec." + vm.name + ".log",
])
logfiles = [x for x in logfiles if path.exists(x)]
if len(logfiles) > 0:
log_dlg = log_dialog.LogDialog(self.qt_app, logfiles)
log_dlg.exec_()
else:
QMessageBox.warning(
self,
self.tr("Error"),
self.tr(
"No log files where found for the current selection."))
except exc.QubesDaemonAccessError:
pass
def main(): def main():
manager_utils.run_asynchronous(VmManagerWindow) manager_utils.run_asynchronous(VmManagerWindow)

View File

@ -14,6 +14,9 @@
<string>Dialog</string> <string>Dialog</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="buttonsLayout"/>
</item>
<item> <item>
<widget class="QTextBrowser" name="log_text"> <widget class="QTextBrowser" name="log_text">
<property name="font"> <property name="font">

View File

@ -350,15 +350,6 @@ Template</string>
<property name="title"> <property name="title">
<string>&amp;Qube</string> <string>&amp;Qube</string>
</property> </property>
<widget class="QMenu" name="logs_menu">
<property name="title">
<string>&amp;Logs</string>
</property>
<property name="icon">
<iconset resource="../resources.qrc">
<normaloff>:/log.png</normaloff>:/log.png</iconset>
</property>
</widget>
<widget class="QMenu" name="template_menu"> <widget class="QMenu" name="template_menu">
<property name="title"> <property name="title">
<string>Template</string> <string>Template</string>
@ -397,7 +388,7 @@ Template</string>
<addaction name="action_open_console"/> <addaction name="action_open_console"/>
<addaction name="action_set_keyboard_layout"/> <addaction name="action_set_keyboard_layout"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="logs_menu"/> <addaction name="action_show_logs"/>
</widget> </widget>
<widget class="QMenu" name="menu_about"> <widget class="QMenu" name="menu_about">
<property name="title"> <property name="title">
@ -969,6 +960,15 @@ Template</string>
<string>Open a secure Xen console in the qube. Useful chiefly for debugging purposes: for normal operation, use &quot;Run Terminal&quot; from the Domains widget. </string> <string>Open a secure Xen console in the qube. Useful chiefly for debugging purposes: for normal operation, use &quot;Run Terminal&quot; from the Domains widget. </string>
</property> </property>
</action> </action>
<action name="action_show_logs">
<property name="icon">
<iconset>
<normaloff>:/log.png</normaloff>:/log.png</iconset>
</property>
<property name="text">
<string>Logs</string>
</property>
</action>
<action name="action_compact_view"> <action name="action_compact_view">
<property name="checkable"> <property name="checkable">
<bool>true</bool> <bool>true</bool>