From e8cec85874803779d70e487c0b32c84a5d4556f8 Mon Sep 17 00:00:00 2001 From: Olivier MEDOC Date: Fri, 27 Sep 2013 09:19:38 +0200 Subject: [PATCH 1/2] backup: implemented restore functions using the new backup model --- qubesmanager/backup_utils.py | 26 +++- qubesmanager/restore.py | 20 ++- restoredlg.ui | 232 ++++++++++++++++++++++------------- 3 files changed, 184 insertions(+), 94 deletions(-) diff --git a/qubesmanager/backup_utils.py b/qubesmanager/backup_utils.py index 3b59825..89cd237 100644 --- a/qubesmanager/backup_utils.py +++ b/qubesmanager/backup_utils.py @@ -75,6 +75,20 @@ def umount_device(dev_mount_path): if button == QMessageBox.Ok: return dev_mount_path +def fill_appvms_list(dialog): + dialog.appvm_combobox.clear() + dialog.appvm_combobox.addItem("None") + + dialog.appvm_combobox.setCurrentIndex(0) #current selected is null "" + + for vm in dialog.qvm_collection.values(): + if vm.is_appvm() and vm.internal: + continue + if vm.is_template() and vm.installed_by_rpm: + continue + + if vm.is_running() and vm.qid != 0: + dialog.appvm_combobox.addItem(vm.name) def fill_devs_list(dialog): dialog.dev_combobox.clear() @@ -157,18 +171,22 @@ def select_path_button_clicked(dialog): file_dialog = QFileDialog() file_dialog.setReadOnly(True) - if dialog.dev_mount_path != None: + new_appvm = None + new_path = None + if dialog.appvm_combobox.currentText() != "None": #An existing appvm chosen + new_appvm = str(dialog.appvm_combobox.currentText()) + elif dialog.dev_mount_path != None: new_path = file_dialog.getExistingDirectory(dialog, "Select backup directory.", dialog.dev_mount_path) else: new_path = file_dialog.getExistingDirectory(dialog, "Select backup directory.", "~") - if new_path: + if new_path != None: dialog.dir_line_edit.setText(new_path) dialog.backup_dir = new_path + + if (new_path or new_appvm) and len(dialog.backup_dir) > 0: dialog.select_dir_page.emit(SIGNAL("completeChanged()")) - - def simulate_long_lasting_proces(period, progress_callback): for i in range(period): progress_callback((i*100)/period) diff --git a/qubesmanager/restore.py b/qubesmanager/restore.py index 4f240b6..e218627 100644 --- a/qubesmanager/restore.py +++ b/qubesmanager/restore.py @@ -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_base_dir import qubesmanager.resources_rc from pyinotify import WatchManager, Notifier, ThreadedNotifier, EventsCodes, ProcessEvent @@ -50,7 +51,7 @@ from backup_utils import * class RestoreVMsWindow(Ui_Restore, QWizard): - __pyqtSignals__ = ("restore_progress(int)",) + __pyqtSignals__ = ("restore_progress(int)","backup_progress(int)") def __init__(self, app, qvm_collection, blk_manager, parent=None): super(RestoreVMsWindow, self).__init__(parent) @@ -82,6 +83,7 @@ class RestoreVMsWindow(Ui_Restore, QWizard): self.connect(self, SIGNAL("currentIdChanged(int)"), self.current_page_changed) self.connect(self.dev_combobox, SIGNAL("activated(int)"), self.dev_combobox_activated) self.connect(self, SIGNAL("restore_progress(QString)"), self.commit_text_edit.append) + self.connect(self, SIGNAL("backup_progress(int)"), self.progress_bar.setValue) self.select_dir_page.isComplete = self.has_selected_dir self.select_vms_page.isComplete = self.has_selected_vms @@ -90,6 +92,7 @@ class RestoreVMsWindow(Ui_Restore, QWizard): self.select_vms_page.connect(self.select_vms_widget, SIGNAL("selected_changed()"), SIGNAL("completeChanged()")) fill_devs_list(self) + fill_appvms_list(self) self.__init_restore_options__() @@ -118,7 +121,13 @@ class RestoreVMsWindow(Ui_Restore, QWizard): self.select_vms_widget.selected_list.clear() self.select_vms_widget.available_list.clear() - self.vms_to_restore = qubesutils.backup_restore_prepare(str(self.backup_dir), self.restore_options, self.qvm_collection) + self.target_appvm = None + if self.appvm_combobox.currentText() != "None": #An existing appvm chosen + self.target_appvm = str(self.appvm_combobox.currentText()) + + self.restore_tmpdir, qubes_xml = qubesutils.backup_restore_header(str(self.backup_dir), str(self.passphrase_line_edit.text()), self.encryption_checkbox.isChecked(), appvm=self.target_appvm) + self.vms_to_restore = qubesutils.backup_restore_prepare(str(self.backup_dir),os.path.join(self.restore_tmpdir, qubes_xml), str(self.passphrase_line_edit.text()), options=self.restore_options, host_collection=self.qvm_collection, encrypt=self.encryption_checkbox.isChecked(), appvm=self.target_appvm) + for vmname in self.vms_to_restore: self.select_vms_widget.available_list.addItem(vmname) @@ -147,17 +156,20 @@ class RestoreVMsWindow(Ui_Restore, QWizard): def restore_error_output(self, s): self.emit(SIGNAL("restore_progress(QString)"), '{0}'.format(s)) - def restore_output(self, s): self.emit(SIGNAL("restore_progress(QString)"),'{0}'.format(s)) + def update_progress_bar(self, value): + self.emit(SIGNAL("backup_progress(int)"), value) def __do_restore__(self, thread_monitor): err_msg = [] self.qvm_collection.lock_db_for_writing() try: - qubesutils.backup_restore_do(str(self.backup_dir), self.vms_to_restore, self.qvm_collection, self.restore_output, self.restore_error_output) + qubesutils.backup_restore_do(str(self.backup_dir), self.restore_tmpdir, str(self.passphrase_line_edit.text()), self.vms_to_restore, self.qvm_collection, encrypted=self.encryption_checkbox.isChecked(), appvm=self.target_appvm, print_callback=self.restore_output, error_callback=self.restore_error_output, progress_callback +=self.update_progress_bar) except Exception as ex: + print "Exception:",ex err_msg.append(str(ex)) self.qvm_collection.unlock_db() diff --git a/restoredlg.ui b/restoredlg.ui index 24e0cb6..8810bf4 100644 --- a/restoredlg.ui +++ b/restoredlg.ui @@ -20,83 +20,21 @@ QWizard::NoBackButtonOnLastPage|QWizard::NoBackButtonOnStartPage - - - - - - 50 - false - + + + + + Qt::Vertical - - Backup source location + + + 20 + 215 + - - - - - - 50 - false - - - - Device - - - - - - - - 0 - 0 - - - - - dev1 - - - - - longdeviceblablabla - - - - - dev2 - - - - - dev3 - - - - - - - - Backup directory: - - - - - - - - - - ... - - - - - + - + @@ -138,18 +76,127 @@ - - - - Qt::Vertical + + + + + 50 + false + - - - 20 - 215 - + + Backup source location - + + + + + + 0 + 0 + + + + + dev1 + + + + + longdeviceblablabla + + + + + dev2 + + + + + dev3 + + + + + + + + + + + ... + + + + + + + Backup directory: + + + + + + + + 50 + false + + + + Device: + + + + + + + + + + AppVM: + + + + + + + + + + Security options + + + + + + + + + + + + + Encrypted backup: + + + + + + + <html><head/><body><p>Decryption / Verification<br/>passphrase:</p></body></html> + + + + + + + QLineEdit::Password + + + + + @@ -189,8 +236,8 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p></body></html> +</style></head><body style=" font-family:'Sans Serif'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p></body></html> @@ -217,6 +264,19 @@ p, li { white-space: pre-wrap; } + + + + 0 + + + false + + + + + + From baa3c6362c8e9f7a614c05359597caee61ecb732 Mon Sep 17 00:00:00 2001 From: Olivier MEDOC Date: Sat, 28 Sep 2013 12:33:56 +0200 Subject: [PATCH 2/2] backup: implemented backup functions using the new backup model --- backupdlg.ui | 79 +++++++++++++++++++++++++++++++++++------- qubesmanager/backup.py | 18 ++++++++-- 2 files changed, 81 insertions(+), 16 deletions(-) diff --git a/backupdlg.ui b/backupdlg.ui index f782343..9237243 100644 --- a/backupdlg.ui +++ b/backupdlg.ui @@ -148,21 +148,21 @@ - - + + Backup destination directory - + Device: - + @@ -192,20 +192,73 @@ - + + + + + + + ... + + + + + + + + + + Target AppVM: + + + + Backup directory: - - - - - + + + + + + + Backup security + + + + - ... + Encrypt backup: + + + + + + + <html><head/><body><p>Encryption / Verification<br/>passphrase:</p></body></html> + + + + + + + Qt::LeftToRight + + + + + + true + + + + + + + QLineEdit::Password @@ -238,8 +291,8 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p></body></html> +</style></head><body style=" font-family:'Sans Serif'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p></body></html> diff --git a/qubesmanager/backup.py b/qubesmanager/backup.py index 2bc24d7..126841c 100644 --- a/qubesmanager/backup.py +++ b/qubesmanager/backup.py @@ -79,7 +79,7 @@ class BackupVMsWindow(Ui_Backup, QWizard): self.setupUi(self) self.show_running_vms_warning(False) - self.dir_line_edit.setReadOnly(True) + self.dir_line_edit.setReadOnly(False) self.select_vms_widget = MultiSelectWidget(self) self.verticalLayout.insertWidget(1, self.select_vms_widget) @@ -103,6 +103,8 @@ class BackupVMsWindow(Ui_Backup, QWizard): self.__fill_vms_list__() fill_devs_list(self) + fill_appvms_list(self) + def show_running_vms_warning(self, show): self.running_vms_warning.setVisible(show) self.shutdown_running_vms_button.setVisible(show) @@ -261,10 +263,12 @@ class BackupVMsWindow(Ui_Backup, QWizard): def __do_backup__(self, thread_monitor): msg = [] + try: - qubesutils.backup_do(str(self.backup_dir), self.files_to_backup, self.update_progress_bar) + qubesutils.backup_do_copy(str(self.backup_dir), self.files_to_backup, str(self.passphrase_line_edit.text()), self.update_progress_bar, encrypt=self.encryption_checkbox.isChecked(), appvm=self.target_appvm) #simulate_long_lasting_proces(10, self.update_progress_bar) except Exception as ex: + print "Exception:",ex msg.append(str(ex)) if len(msg) > 0 : @@ -275,11 +279,19 @@ class BackupVMsWindow(Ui_Backup, QWizard): def current_page_changed(self, id): if self.currentPage() is self.confirm_page: + + self.target_appvm = None + if self.appvm_combobox.currentText() != "None": #An existing appvm chosen + self.target_appvm = str(self.appvm_combobox.currentText()) + + # FIXME: ensure that at least a non empty passphrase has been provided + del self.func_output[:] try: self.files_to_backup = qubesutils.backup_prepare(str(self.backup_dir), exclude_list = self.excluded, print_callback = self.gather_output) except Exception as ex: - QMessageBox.critical(None, "Error while prepering backup.", "ERROR: {0}".format(ex)) + print "Exception:",ex + QMessageBox.critical(None, "Error while preparing backup.", "ERROR: {0}".format(ex)) self.textEdit.setReadOnly(True) self.textEdit.setFontFamily("Monospace")