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 + + + + + +