From dc0ee97b271c97f42be156b6c2fe23c38e47d479 Mon Sep 17 00:00:00 2001 From: donoban Date: Sat, 5 Dec 2020 12:28:36 +0100 Subject: [PATCH 1/7] Multiple file log dialog --- qubesmanager/log_dialog.py | 40 ++++++++++++++++------- qubesmanager/qube_manager.py | 62 +++++++++++++----------------------- ui/logdlg.ui | 3 ++ ui/qubemanager.ui | 11 ++++++- 4 files changed, 63 insertions(+), 53 deletions(-) diff --git a/qubesmanager/log_dialog.py b/qubesmanager/log_dialog.py index a5f07b9..f173d70 100644 --- a/qubesmanager/log_dialog.py +++ b/qubesmanager/log_dialog.py @@ -20,13 +20,12 @@ # # import sys +import os +from functools import partial from PyQt5 import QtWidgets # pylint: disable=import-error - +from qubesadmin import Qubes from . import ui_logdlg # pylint: disable=no-name-in-module from . import clipboard -import os - -from qubesadmin import Qubes # Display only this size of log LOG_DISPLAY_SIZE = 1024*1024 @@ -39,10 +38,9 @@ class LogDialog(ui_logdlg.Ui_LogDialog, QtWidgets.QDialog): super().__init__(parent) self.app = app - self.log_path = log_path + self.logfiles = log_path self.setupUi(self) - self.setWindowTitle(log_path) self.copy_to_qubes_clipboard.clicked.connect( self.copy_to_clipboard_triggered) @@ -52,8 +50,31 @@ class LogDialog(ui_logdlg.Ui_LogDialog, QtWidgets.QDialog): self.__init_log_text__() def __init_log_text__(self): + butts_in_row = 3 + count = 0 + for log_path in self.logfiles: + if os.path.exists(log_path): + button = QtWidgets.QPushButton(log_path) + button.clicked.connect(partial(self.set_current_log, log_path)) + self.buttonsLayout.addWidget(button, count / butts_in_row, count % butts_in_row) + count += 1 + + if count == 0: + QtWidgets.QMessageBox.warning( + self, + self.tr("Error"), + self.tr( + "No log files where found for current selection")) + else: + 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.setWindowTitle(log_path) self.displayed_text = "" - log = open(self.log_path) + log = open(log_path) log.seek(0, os.SEEK_END) if log.tell() > LOG_DISPLAY_SIZE: self.displayed_text = self.tr( @@ -64,11 +85,6 @@ class LogDialog(ui_logdlg.Ui_LogDialog, QtWidgets.QDialog): self.displayed_text += log.read() log.close() 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(): qubes_app = Qubes() diff --git a/qubesmanager/qube_manager.py b/qubesmanager/qube_manager.py index 91023d1..d2a8312 100644 --- a/qubesmanager/qube_manager.py +++ b/qubesmanager/qube_manager.py @@ -689,7 +689,7 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QMainWindow): self.context_menu.addAction(self.action_removevm) self.context_menu.addSeparator() - self.context_menu.addMenu(self.logs_menu) + self.context_menu.addAction(self.action_show_logs) self.context_menu.addSeparator() self.tools_context_menu = QMenu(self) @@ -702,7 +702,7 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QMainWindow): lambda pos: self.open_tools_context_menu(self.toolbar, pos)) self.action_menubar.toggled.connect(self.showhide_menubar) self.action_toolbar.toggled.connect(self.showhide_toolbar) - self.logs_menu.triggered.connect(self.show_log) + self.action_show_logs.triggered.connect(self.show_log) self.table.resizeColumnsToContents() @@ -1030,8 +1030,6 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QMainWindow): if not vm.updateable and vm.klass != 'AdminVM': self.action_updatevm.setEnabled(False) - self.update_logs_menu() - # noinspection PyArgumentList @pyqtSlot(name='on_action_createvm_triggered') def action_createvm_triggered(self): @@ -1428,48 +1426,32 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QMainWindow): def open_tools_context_menu(self, widget, 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&') def open_context_menu(self, point): self.context_menu.exec_(self.table.mapToGlobal( point + QPoint(10, 0))) - @pyqtSlot('QAction *') - def show_log(self, action): - log = str(action.data()) - log_dlg = log_dialog.LogDialog(self.qt_app, log) - log_dlg.exec_() + def show_log(self): + logfiles = [] + 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", + ]) + + log_dlg = log_dialog.LogDialog(self.qt_app, logfiles) + log_dlg.exec_() + except exc.QubesDaemonAccessError: + pass def main(): manager_utils.run_asynchronous(VmManagerWindow) diff --git a/ui/logdlg.ui b/ui/logdlg.ui index 06976f5..b1e69cd 100644 --- a/ui/logdlg.ui +++ b/ui/logdlg.ui @@ -14,6 +14,9 @@ Dialog + + + diff --git a/ui/qubemanager.ui b/ui/qubemanager.ui index 47fd249..24175db 100644 --- a/ui/qubemanager.ui +++ b/ui/qubemanager.ui @@ -297,7 +297,7 @@ Template - + @@ -869,6 +869,15 @@ Template Open a secure Xen console in the qube. Useful chiefly for debugging purposes: for normal operation, use "Run Terminal" from the Domains widget. + + + + :/log.png:/log.png + + + Logs + + From 4fa13d329591d355e2746f2fa011da06de150ade Mon Sep 17 00:00:00 2001 From: donoban Date: Sat, 5 Dec 2020 12:41:20 +0100 Subject: [PATCH 2/7] Pylint fixes --- qubesmanager/log_dialog.py | 10 ++++++---- qubesmanager/qube_manager.py | 2 -- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/qubesmanager/log_dialog.py b/qubesmanager/log_dialog.py index f173d70..9b770df 100644 --- a/qubesmanager/log_dialog.py +++ b/qubesmanager/log_dialog.py @@ -34,11 +34,12 @@ LOG_DISPLAY_SIZE = 1024*1024 class LogDialog(ui_logdlg.Ui_LogDialog, QtWidgets.QDialog): # pylint: disable=too-few-public-methods - def __init__(self, app, log_path, parent=None): + def __init__(self, app, logfiles, parent=None): super().__init__(parent) self.app = app - self.logfiles = log_path + self.logfiles = logfiles + self.displayed_text = "" self.setupUi(self) @@ -56,7 +57,8 @@ class LogDialog(ui_logdlg.Ui_LogDialog, QtWidgets.QDialog): if os.path.exists(log_path): button = QtWidgets.QPushButton(log_path) button.clicked.connect(partial(self.set_current_log, log_path)) - self.buttonsLayout.addWidget(button, count / butts_in_row, count % butts_in_row) + self.buttonsLayout.addWidget(button, + count / butts_in_row, count % butts_in_row) count += 1 if count == 0: @@ -72,8 +74,8 @@ class LogDialog(ui_logdlg.Ui_LogDialog, QtWidgets.QDialog): clipboard.copy_text_to_qubes_clipboard(self.displayed_text) def set_current_log(self, log_path): - self.setWindowTitle(log_path) self.displayed_text = "" + self.setWindowTitle(log_path) log = open(log_path) log.seek(0, os.SEEK_END) if log.tell() > LOG_DISPLAY_SIZE: diff --git a/qubesmanager/qube_manager.py b/qubesmanager/qube_manager.py index d2a8312..2515529 100644 --- a/qubesmanager/qube_manager.py +++ b/qubesmanager/qube_manager.py @@ -21,8 +21,6 @@ # with this program; if not, see . # # -import os -import os.path import subprocess from datetime import datetime, timedelta from functools import partial From b5e092fa8b2a823009d77317d2df855d3ace4a68 Mon Sep 17 00:00:00 2001 From: donob4n <35405566+donob4n@users.noreply.github.com> Date: Thu, 10 Dec 2020 09:49:41 +0100 Subject: [PATCH 3/7] Update qubesmanager/log_dialog.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Marek Marczykowski-Górecki --- qubesmanager/log_dialog.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qubesmanager/log_dialog.py b/qubesmanager/log_dialog.py index 9b770df..1ad6d41 100644 --- a/qubesmanager/log_dialog.py +++ b/qubesmanager/log_dialog.py @@ -51,7 +51,7 @@ class LogDialog(ui_logdlg.Ui_LogDialog, QtWidgets.QDialog): self.__init_log_text__() def __init_log_text__(self): - butts_in_row = 3 + btns_in_row = 3 count = 0 for log_path in self.logfiles: if os.path.exists(log_path): From 8dac54b7554102acf529065f4032e485927bb17d Mon Sep 17 00:00:00 2001 From: donoban Date: Thu, 10 Dec 2020 23:40:02 +0100 Subject: [PATCH 4/7] Removed unused logs_menu --- ui/qubemanager.ui | 9 --------- 1 file changed, 9 deletions(-) diff --git a/ui/qubemanager.ui b/ui/qubemanager.ui index e5f5043..bbed67c 100644 --- a/ui/qubemanager.ui +++ b/ui/qubemanager.ui @@ -350,15 +350,6 @@ Template &Qube - - - &Logs - - - - :/log.png:/log.png - - From 78d76eb70f735fce2b9ca4eb648d7f283567ff63 Mon Sep 17 00:00:00 2001 From: donoban Date: Thu, 10 Dec 2020 23:46:44 +0100 Subject: [PATCH 5/7] Fix Spanglish accident --- qubesmanager/log_dialog.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qubesmanager/log_dialog.py b/qubesmanager/log_dialog.py index 1ad6d41..18e8600 100644 --- a/qubesmanager/log_dialog.py +++ b/qubesmanager/log_dialog.py @@ -58,7 +58,7 @@ class LogDialog(ui_logdlg.Ui_LogDialog, QtWidgets.QDialog): button = QtWidgets.QPushButton(log_path) button.clicked.connect(partial(self.set_current_log, log_path)) self.buttonsLayout.addWidget(button, - count / butts_in_row, count % butts_in_row) + count / btns_in_row, count % btns_in_row) count += 1 if count == 0: From df0e4699a0bfc26b658c572fe05b82c42dd449e6 Mon Sep 17 00:00:00 2001 From: donoban Date: Fri, 11 Dec 2020 00:53:57 +0100 Subject: [PATCH 6/7] File checking and error dialog moved to qube_manager --- qubesmanager/log_dialog.py | 20 ++++++-------------- qubesmanager/qube_manager.py | 15 +++++++++++++-- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/qubesmanager/log_dialog.py b/qubesmanager/log_dialog.py index 18e8600..979b069 100644 --- a/qubesmanager/log_dialog.py +++ b/qubesmanager/log_dialog.py @@ -54,21 +54,13 @@ class LogDialog(ui_logdlg.Ui_LogDialog, QtWidgets.QDialog): btns_in_row = 3 count = 0 for log_path in self.logfiles: - if os.path.exists(log_path): - 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 + 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 - if count == 0: - QtWidgets.QMessageBox.warning( - self, - self.tr("Error"), - self.tr( - "No log files where found for current selection")) - else: - self.buttonsLayout.itemAt(0).widget().click() + self.buttonsLayout.itemAt(0).widget().click() def copy_to_clipboard_triggered(self): clipboard.copy_text_to_qubes_clipboard(self.displayed_text) diff --git a/qubesmanager/qube_manager.py b/qubesmanager/qube_manager.py index 35be98d..0edce50 100644 --- a/qubesmanager/qube_manager.py +++ b/qubesmanager/qube_manager.py @@ -24,6 +24,7 @@ import subprocess from datetime import datetime, timedelta from functools import partial +from os import path from qubesadmin import exc from qubesadmin import utils @@ -1526,8 +1527,18 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QMainWindow): "/var/log/qubes/qrexec." + vm.name + ".log", ]) - log_dlg = log_dialog.LogDialog(self.qt_app, logfiles) - log_dlg.exec_() + logfiles = list(filter(lambda x: path.exists(x), logfiles)) + + 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 From 2164b82c346533b36ec5d43dd6f5bcb3b9c7e7ad Mon Sep 17 00:00:00 2001 From: donoban Date: Fri, 11 Dec 2020 01:01:21 +0100 Subject: [PATCH 7/7] Changed filter to list comprehension (avoids pylint warning) --- qubesmanager/qube_manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qubesmanager/qube_manager.py b/qubesmanager/qube_manager.py index 0edce50..3bcbc20 100644 --- a/qubesmanager/qube_manager.py +++ b/qubesmanager/qube_manager.py @@ -1527,7 +1527,7 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QMainWindow): "/var/log/qubes/qrexec." + vm.name + ".log", ]) - logfiles = list(filter(lambda x: path.exists(x), logfiles)) + logfiles = [x for x in logfiles if path.exists(x)] if len(logfiles) > 0: log_dlg = log_dialog.LogDialog(self.qt_app, logfiles)