diff --git a/backupdlg.ui b/backupdlg.ui index 15e5c6f..590c77b 100644 --- a/backupdlg.ui +++ b/backupdlg.ui @@ -155,64 +155,27 @@ Backup destination directory - - - - Device: - - - - - - - - 0 - 0 - - - - - dev1 - - - - - longdeviceblablabla - - - - - dev2 - - - - - dev3 - - - - - + - + ... - + - + Target AppVM: - + Backup directory or VM command: diff --git a/qubesmanager/backup.py b/qubesmanager/backup.py index da7d84f..b660603 100644 --- a/qubesmanager/backup.py +++ b/qubesmanager/backup.py @@ -66,7 +66,6 @@ class BackupVMsWindow(Ui_Backup, QWizard): self.blk_manager = blk_manager self.shutdown_vm_func = shutdown_vm_func - self.dev_mount_path = None self.func_output = [] self.selected_vms = [] self.tmpdir_to_remove = None @@ -92,13 +91,8 @@ class BackupVMsWindow(Ui_Backup, QWizard): self.connect(self.select_vms_widget, SIGNAL("items_added(PyQt_PyObject)"), self.vms_added) self.refresh_button.clicked.connect(self.check_running) self.shutdown_running_vms_button.clicked.connect(self.shutdown_all_running_selected) - self.connect(self.dev_combobox, SIGNAL("activated(int)"), self.dev_combobox_activated) self.connect(self, SIGNAL("backup_progress(int)"), self.progress_bar.setValue) self.dir_line_edit.connect(self.dir_line_edit, SIGNAL("textChanged(QString)"), self.backup_location_changed) - self.connect(self.dev_combobox, SIGNAL("activated(int)"), - self.update_device_appvm_enabled) - self.connect(self.appvm_combobox, SIGNAL("activated(int)"), - self.update_device_appvm_enabled) self.select_vms_page.isComplete = self.has_selected_vms self.select_dir_page.isComplete = self.has_selected_dir_and_pass @@ -119,7 +113,6 @@ class BackupVMsWindow(Ui_Backup, QWizard): self.total_size = 0 self.__fill_vms_list__() - fill_devs_list(self) fill_appvms_list(self) self.load_settings() @@ -130,12 +123,6 @@ class BackupVMsWindow(Ui_Backup, QWizard): dest_vm_idx = self.appvm_combobox.findText(dest_vm_name.toString()) if dest_vm_idx > -1: self.appvm_combobox.setCurrentIndex(dest_vm_idx) - else: - dest_blk_name = main.manager_window.manager_settings.value( - 'backup/device', defaultValue="") - dest_blk_idx = self.dev_combobox.findText(dest_blk_name.toString()) - if dest_blk_idx > -1: - self.dev_combobox.setCurrentIndex(dest_blk_idx) if main.manager_window.manager_settings.contains('backup/path'): dest_path = main.manager_window.manager_settings.value( @@ -150,8 +137,6 @@ class BackupVMsWindow(Ui_Backup, QWizard): def save_settings(self): main.manager_window.manager_settings.setValue( 'backup/vmname', self.appvm_combobox.currentText()) - main.manager_window.manager_settings.setValue( - 'backup/device', self.dev_combobox.currentText()) main.manager_window.manager_settings.setValue( 'backup/path', self.dir_line_edit.text()) main.manager_window.manager_settings.setValue( @@ -274,12 +259,6 @@ class BackupVMsWindow(Ui_Backup, QWizard): vms.append(item.vm) return (names, vms) - def dev_combobox_activated(self, idx): - dev_combobox_activated(self, idx) - - def update_device_appvm_enabled(self, idx): - update_device_appvm_enabled(self, idx) - @pyqtSlot(name='on_select_path_button_clicked') def select_path_button_clicked(self): select_path_button_clicked(self) @@ -402,18 +381,7 @@ class BackupVMsWindow(Ui_Backup, QWizard): else: self.progress_bar.setValue(100) self.progress_status.setText("Backup finished.") - if self.dev_mount_path is not None: - self.progress_status.setText( - "Backup finished. You can disconnect your backup " - "device") - else: - self.progress_status.setText("Backup finished.") - if self.dev_mount_path is not None: - umount_device(self.dev_mount_path) - detach_device(self, str(self.dev_combobox.itemData( - self.dev_combobox.currentIndex()).toString())) - self.dev_mount_path = None - elif self.showFileDialog.isChecked(): + if self.showFileDialog.isChecked(): orig_text = self.progress_status.text self.progress_status.setText( orig_text + " Please unmount your backup volume and cancel " diff --git a/qubesmanager/backup_utils.py b/qubesmanager/backup_utils.py index 534e2f0..8bffe1e 100644 --- a/qubesmanager/backup_utils.py +++ b/qubesmanager/backup_utils.py @@ -36,61 +36,6 @@ from string import replace path_re = re.compile(r"[a-zA-Z0-9/:.,_+=() -]*") path_max_len = 512 -mount_for_backup_path = '/usr/libexec/qubes-manager/mount_for_backup.sh' - -def check_if_mounted(dev_path): - mounts_file = open("/proc/mounts") - for m in list(mounts_file): - if m.startswith(dev_path): - return m.split(" ")[1] - return None - - -def mount_device(dev_path): - try: - mount_dir_name = "backup" + replace(str(datetime.now()),' ', '-').split(".")[0] - pmount_cmd = [mount_for_backup_path, dev_path, mount_dir_name] - res = subprocess.check_call(pmount_cmd) - except Exception as ex: - QMessageBox.warning (None, "Error mounting selected device!", "Could not mount {0}.

ERROR: {1}".format(dev_path, ex)) - return None - if res == 0: - dev_mount_path = "/media/"+mount_dir_name - return dev_mount_path - return None - -def umount_device(dev_mount_path): - while True: - try: - pumount_cmd = ["/usr/bin/sudo", "/usr/bin/pumount", "--luks-force", dev_mount_path] - res = subprocess.check_call(pumount_cmd) - if res == 0: - dev_mount_path = None - return dev_mount_path - except Exception as ex: - title = "Error unmounting backup device!" - text = "Could not unmount {0}.
\ - Please retry or unmount it manually using
pumount {0}.

\ - ERROR: {1}".format(dev_mount_path, ex) - button = QMessageBox.warning (None, title, text, QMessageBox.Ok | QMessageBox.Retry, QMessageBox.Retry) - if button == QMessageBox.Ok: - return dev_mount_path - -def detach_device(dialog, dev_name): - """ Detach device from dom0, if device was attached from some VM""" - if not dev_name.startswith(dialog.vm.name+":"): - with dialog.blk_manager.blk_lock: - dialog.blk_manager.detach_device(dialog.vm, dev_name) - dialog.blk_manager.update() - else: - # umount/LUKS remove do not trigger udev event on underlying device, - # so trigger it manually - to publish back as available device - subprocess.call(["/usr/bin/sudo", "/bin/udevadm", "trigger", "--action=change", - "--subsystem-match=block", - "--sysname-match=%s" % dev_name.split(":")[1]]) - with dialog.blk_manager.blk_lock: - dialog.blk_manager.update() - def fill_appvms_list(dialog): dialog.appvm_combobox.clear() @@ -107,100 +52,10 @@ def fill_appvms_list(dialog): if vm.is_running() and vm.qid != 0: dialog.appvm_combobox.addItem(vm.name) -def fill_devs_list(dialog): - dialog.dev_combobox.clear() - dialog.dev_combobox.addItem("None") - - dialog.blk_manager.blk_lock.acquire() - for a in dialog.blk_manager.attached_devs: - if dialog.blk_manager.attached_devs[a]['attached_to']['vm'] == dialog.vm.name : - att = a + " " + unicode(dialog.blk_manager.attached_devs[a]['size']) + " " + dialog.blk_manager.attached_devs[a]['desc'] - dialog.dev_combobox.addItem(att, QVariant(a)) - for a in dialog.blk_manager.free_devs: - att = a + " " + unicode(dialog.blk_manager.free_devs[a]['size']) + " " + dialog.blk_manager.free_devs[a]['desc'] - dialog.dev_combobox.addItem(att, QVariant(a)) - dialog.blk_manager.blk_lock.release() - - dialog.dev_combobox.setCurrentIndex(0) #current selected is null "" - dialog.prev_dev_idx = 0 - dialog.dir_line_edit.clear() - enable_dir_line_edit(dialog, True) - - def enable_dir_line_edit(dialog, boolean): dialog.dir_line_edit.setEnabled(boolean) dialog.select_path_button.setEnabled(boolean) -def update_device_appvm_enabled(dialog, idx): - # Only one of those can be used - dialog.dev_combobox.setEnabled(dialog.appvm_combobox.currentIndex() == 0) - dialog.appvm_combobox.setEnabled(dialog.dev_combobox.currentIndex() == 0) - -def dev_combobox_activated(dialog, idx): - if idx == dialog.prev_dev_idx: #nothing has changed - return - #there was a change - - dialog.dir_line_edit.setText("") - - # umount old device if any - if dialog.dev_mount_path != None: - dialog.dev_mount_path = umount_device(dialog.dev_mount_path) - if dialog.dev_mount_path != None: - dialog.dev_combobox.setCurrentIndex(dialog.prev_dev_idx) - return - else: - detach_device(dialog, - str(dialog.dev_combobox.itemData(dialog.prev_dev_idx).toString())) - - # then attach new one - if dialog.dev_combobox.currentIndex() != 0: #An existing device chosen - dev_name = str(dialog.dev_combobox.itemData(idx).toString()) - - if dev_name.startswith(dialog.vm.name+":"): - # originally attached to dom0 - dev_path = "/dev/"+dev_name.split(":")[1] - else: - try: - with dialog.blk_manager.blk_lock: - if dev_name in dialog.blk_manager.free_devs: - #attach it to dom0, then treat it as an attached device - dialog.blk_manager.attach_device(dialog.vm, dev_name) - dialog.blk_manager.update() - - if dev_name in dialog.blk_manager.attached_devs: #is attached to dom0 - assert dialog.blk_manager.attached_devs[dev_name]['attached_to']['vm'] == dialog.vm.name - dev_path = "/dev/" + dialog.blk_manager.attached_devs[dev_name]['attached_to']['frontend'] - else: - raise QubesException("device not attached?!") - except QubesException as ex: - QMessageBox.warning (None, "Error attaching selected device!", - "Could not attach {0}.

ERROR: {1}".format(dev_name, ex)) - dialog.dev_combobox.setCurrentIndex(0) #if couldn't mount - set current device to "None" - dialog.prev_dev_idx = 0 - return - - #check if device mounted - dialog.dev_mount_path = check_if_mounted(dev_path) - if dialog.dev_mount_path == None: - dialog.dev_mount_path = mount_device(dev_path) - if dialog.dev_mount_path == None: - dialog.dev_combobox.setCurrentIndex(0) #if couldn't mount - set current device to "None" - dialog.prev_dev_idx = 0 - detach_device(dialog, - str(dialog.dev_combobox.itemData(idx).toString())) - return - - dialog.prev_dev_idx = idx - - if hasattr(dialog, 'selected_vms'): - # backup window - if dialog.dev_mount_path != None: - # Initialize path with root of mounted device - dialog.dir_line_edit.setText(dialog.dev_mount_path) - dialog.select_dir_page.emit(SIGNAL("completeChanged()")) - - def get_path_for_vm(vm, service_name): if not vm: return None @@ -234,8 +89,6 @@ def select_path_button_clicked(dialog, select_file = False): if vm: new_path = get_path_for_vm(vm, "qubes.SelectFile" if select_file else "qubes.SelectDirectory") - elif dialog.dev_mount_path != None: - new_path = file_dialog_function(dialog, "Select backup location.", dialog.dev_mount_path) else: new_path = file_dialog_function(dialog, "Select backup location.", backup_location if backup_location @@ -258,5 +111,4 @@ def simulate_long_lasting_proces(period, progress_callback): time.sleep(1) progress_callback(100) - return 0 - + return 0 \ No newline at end of file diff --git a/qubesmanager/restore.py b/qubesmanager/restore.py index 0d0ba02..fa34933 100644 --- a/qubesmanager/restore.py +++ b/qubesmanager/restore.py @@ -62,7 +62,6 @@ class RestoreVMsWindow(Ui_Restore, QWizard): self.qvm_collection = qvm_collection self.blk_manager = blk_manager - self.dev_mount_path = None self.restore_options = None self.vms_to_restore = None self.func_output = [] @@ -83,14 +82,9 @@ class RestoreVMsWindow(Ui_Restore, QWizard): self.select_vms_layout.insertWidget(1, self.select_vms_widget) 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.dir_line_edit.connect(self.dir_line_edit, SIGNAL("textChanged(QString)"), self.backup_location_changed) - self.connect(self.dev_combobox, SIGNAL("activated(int)"), - self.update_device_appvm_enabled) - self.connect(self.appvm_combobox, SIGNAL("activated(int)"), - self.update_device_appvm_enabled) self.connect(self.verify_only, SIGNAL("stateChanged(int)"), self.on_verify_only_toogled) @@ -101,17 +95,9 @@ class RestoreVMsWindow(Ui_Restore, QWizard): #this causes to run isComplete() twice, I don't know why 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__() - - def dev_combobox_activated(self, idx): - dev_combobox_activated(self, idx) - - def update_device_appvm_enabled(self, idx): - update_device_appvm_enabled(self, idx) - @pyqtSlot(name='on_select_path_button_clicked') def select_path_button_clicked(self): select_path_button_clicked(self, True) @@ -288,12 +274,7 @@ class RestoreVMsWindow(Ui_Restore, QWizard): QMessageBox.warning (None, "Backup error!", "ERROR: {1}" .format(self.vm.name, self.thread_monitor.error_msg)) - if self.dev_mount_path != None: - umount_device(self.dev_mount_path) - self.dev_mount_path = None - detach_device(self, str(self.dev_combobox.itemData( - self.dev_combobox.currentIndex()).toString())) - elif self.showFileDialog.isChecked(): + if self.showFileDialog.isChecked(): self.emit(SIGNAL("restore_progress(QString)"), '{0}'.format( "Please unmount your backup volume and cancel " @@ -304,9 +285,9 @@ class RestoreVMsWindow(Ui_Restore, QWizard): else: file_dialog = QFileDialog() file_dialog.setReadOnly(True) - file_dialog.getExistingDirectory(self, - "Detach backup device", - self.dev_mount_path) + file_dialog.getExistingDirectory( + self, "Detach backup device", + os.path.dirname(unicode(self.dir_line_edit.text()))) self.progress_bar.setValue(100) self.button(self.FinishButton).setEnabled(True) self.button(self.CancelButton).setEnabled(False) @@ -330,10 +311,6 @@ class RestoreVMsWindow(Ui_Restore, QWizard): .format("Aborting the operation...")) self.button(self.CancelButton).setDisabled(True) else: - if self.dev_mount_path != None: - umount_device(self.dev_mount_path) - detach_device(self, str(self.dev_combobox.itemData( - self.dev_combobox.currentIndex()).toString())) self.done(0) def has_selected_dir(self): diff --git a/restoredlg.ui b/restoredlg.ui index 051a9a6..e6b20e0 100644 --- a/restoredlg.ui +++ b/restoredlg.ui @@ -94,47 +94,17 @@ Backup source location
- - - - - 0 - 0 - - - - - dev1 - - - - - longdeviceblablabla - - - - - dev2 - - - - - dev3 - - - - - + - + ... - + @@ -153,23 +123,10 @@ - - - - - 50 - false - - - - Device: - - - - + - + AppVM: