Added optional saving of default backup profile
Added checkbox for saving default backup profile. Removed useless "should I encrypt" checkbox (yes, you have to encrypt).
This commit is contained in:
parent
9d73ceb99d
commit
7bcde2158e
@ -145,21 +145,20 @@ class BackupVMsWindow(ui_backupdlg.Ui_Backup, multiselectwidget.QtGui.QWizard):
|
|||||||
self.passphrase_line_edit.setText(profile_data['passphrase_text'])
|
self.passphrase_line_edit.setText(profile_data['passphrase_text'])
|
||||||
self.passphrase_line_edit_verify.setText(
|
self.passphrase_line_edit_verify.setText(
|
||||||
profile_data['passphrase_text'])
|
profile_data['passphrase_text'])
|
||||||
# TODO: make a checkbox for saving the profile
|
|
||||||
# TODO: warn that unknown data will be overwritten
|
|
||||||
|
|
||||||
if 'include' in profile_data:
|
if 'include' in profile_data:
|
||||||
return profile_data['include']
|
return profile_data['include']
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def save_settings(self):
|
def save_settings(self, use_temp):
|
||||||
settings = {'destination_vm': self.appvm_combobox.currentText(),
|
settings = {'destination_vm': self.appvm_combobox.currentText(),
|
||||||
'destination_path': self.dir_line_edit.text(),
|
'destination_path': self.dir_line_edit.text(),
|
||||||
'include': [vm.name for vm in self.selected_vms],
|
'include': [vm.name for vm in self.selected_vms],
|
||||||
'passphrase_text': self.passphrase_line_edit.text()}
|
'passphrase_text': self.passphrase_line_edit.text()}
|
||||||
# TODO: add compression when it is added
|
# TODO: add compression when it is added
|
||||||
backup_utils.write_backup_profile(settings)
|
|
||||||
|
backup_utils.write_backup_profile(settings, use_temp)
|
||||||
|
|
||||||
class VmListItem(QtGui.QListWidgetItem):
|
class VmListItem(QtGui.QListWidgetItem):
|
||||||
def __init__(self, vm):
|
def __init__(self, vm):
|
||||||
@ -267,9 +266,9 @@ class BackupVMsWindow(ui_backupdlg.Ui_Backup, multiselectwidget.QtGui.QWizard):
|
|||||||
self.appvm_combobox.currentText()]
|
self.appvm_combobox.currentText()]
|
||||||
if not vm.is_running():
|
if not vm.is_running():
|
||||||
vm.start()
|
vm.start()
|
||||||
self.qvm_collection.qubesd_call('dom0',
|
self.qvm_collection.qubesd_call(
|
||||||
'admin.backup.Execute',
|
'dom0', 'admin.backup.Execute',
|
||||||
'qubes-manager-backup')
|
backup_utils.get_profile_name(True))
|
||||||
except exc.QubesException as err:
|
except exc.QubesException as err:
|
||||||
# TODO fixme
|
# TODO fixme
|
||||||
print('\nBackup error: {}'.format(err), file=sys.stderr)
|
print('\nBackup error: {}'.format(err), file=sys.stderr)
|
||||||
@ -288,15 +287,20 @@ class BackupVMsWindow(ui_backupdlg.Ui_Backup, multiselectwidget.QtGui.QWizard):
|
|||||||
old_sigchld_handler = signal.signal(signal.SIGCHLD, signal.SIG_DFL)
|
old_sigchld_handler = signal.signal(signal.SIGCHLD, signal.SIG_DFL)
|
||||||
if self.currentPage() is self.confirm_page:
|
if self.currentPage() is self.confirm_page:
|
||||||
|
|
||||||
self.save_settings()
|
self.save_settings(True)
|
||||||
backup_summary = self.qvm_collection.qubesd_call(
|
backup_summary = self.qvm_collection.qubesd_call(
|
||||||
'dom0', 'admin.backup.Info', 'qubes-manager-backup')
|
'dom0', 'admin.backup.Info',
|
||||||
|
backup_utils.get_profile_name(True))
|
||||||
|
|
||||||
self.textEdit.setReadOnly(True)
|
self.textEdit.setReadOnly(True)
|
||||||
self.textEdit.setFontFamily("Monospace")
|
self.textEdit.setFontFamily("Monospace")
|
||||||
self.textEdit.setText(backup_summary.decode())
|
self.textEdit.setText(backup_summary.decode())
|
||||||
|
|
||||||
elif self.currentPage() is self.commit_page:
|
elif self.currentPage() is self.commit_page:
|
||||||
|
|
||||||
|
if self.save_profile_checkbox.isChecked():
|
||||||
|
self.save_settings(False)
|
||||||
|
|
||||||
self.button(self.FinishButton).setDisabled(True)
|
self.button(self.FinishButton).setDisabled(True)
|
||||||
self.showFileDialog.setEnabled(
|
self.showFileDialog.setEnabled(
|
||||||
self.appvm_combobox.currentIndex() != 0)
|
self.appvm_combobox.currentIndex() != 0)
|
||||||
|
@ -30,10 +30,6 @@ import yaml
|
|||||||
path_re = re.compile(r"[a-zA-Z0-9/:.,_+=() -]*")
|
path_re = re.compile(r"[a-zA-Z0-9/:.,_+=() -]*")
|
||||||
path_max_len = 512
|
path_max_len = 512
|
||||||
|
|
||||||
# TODO: replace it with a more dynamic approach: allowing user to turn on or off
|
|
||||||
# profile saving
|
|
||||||
backup_profile_path = '/etc/qubes/backup/qubes-manager-backup.conf'
|
|
||||||
|
|
||||||
|
|
||||||
def fill_appvms_list(dialog):
|
def fill_appvms_list(dialog):
|
||||||
dialog.appvm_combobox.clear()
|
dialog.appvm_combobox.clear()
|
||||||
@ -90,20 +86,16 @@ def select_path_button_clicked(dialog, select_file=False):
|
|||||||
dialog.select_dir_page.emit(QtCore.SIGNAL("completeChanged()"))
|
dialog.select_dir_page.emit(QtCore.SIGNAL("completeChanged()"))
|
||||||
|
|
||||||
|
|
||||||
def load_backup_profile():
|
def load_backup_profile(use_temp=False):
|
||||||
with open(backup_profile_path) as profile_file:
|
|
||||||
|
path = get_profile_path(use_temp)
|
||||||
|
|
||||||
|
with open(path) as profile_file:
|
||||||
profile_data = yaml.safe_load(profile_file)
|
profile_data = yaml.safe_load(profile_file)
|
||||||
return profile_data
|
return profile_data
|
||||||
|
|
||||||
|
|
||||||
def write_backup_profile(args):
|
def write_backup_profile(args, use_temp=False):
|
||||||
'''Format limited backup profile (for GUI purposes and print it to
|
|
||||||
*output_stream* (a file or stdout)
|
|
||||||
|
|
||||||
:param output_stream: file-like object ro print the profile to
|
|
||||||
:param args: dictionary with arguments
|
|
||||||
:param passphrase: passphrase to use
|
|
||||||
'''
|
|
||||||
|
|
||||||
acceptable_fields = ['include', 'passphrase_text', 'compression',
|
acceptable_fields = ['include', 'passphrase_text', 'compression',
|
||||||
'destination_vm', 'destination_path']
|
'destination_vm', 'destination_path']
|
||||||
@ -111,6 +103,20 @@ def write_backup_profile(args):
|
|||||||
profile_data = {key: value for key, value in args.items()
|
profile_data = {key: value for key, value in args.items()
|
||||||
if key in acceptable_fields}
|
if key in acceptable_fields}
|
||||||
|
|
||||||
|
path = get_profile_path(use_temp)
|
||||||
|
|
||||||
# TODO add compression parameter to GUI issue#943
|
# TODO add compression parameter to GUI issue#943
|
||||||
with open(backup_profile_path, 'w') as profile_file:
|
with open(path, 'w') as profile_file:
|
||||||
yaml.safe_dump(profile_data, profile_file)
|
yaml.safe_dump(profile_data, profile_file)
|
||||||
|
|
||||||
|
|
||||||
|
def get_profile_name(use_temp):
|
||||||
|
backup_profile_name = 'qubes-manager-backup'
|
||||||
|
temp_backup_profile_name = 'qubes-manager-backup-tmp'
|
||||||
|
|
||||||
|
return temp_backup_profile_name if use_temp else backup_profile_name
|
||||||
|
|
||||||
|
|
||||||
|
def get_profile_path(use_temp):
|
||||||
|
path = '/etc/qubes/backup/' + get_profile_name(use_temp) + '.conf'
|
||||||
|
return path
|
||||||
|
122
ui/backupdlg.ui
122
ui/backupdlg.ui
@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>650</width>
|
<width>737</width>
|
||||||
<height>399</height>
|
<height>420</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@ -137,6 +137,12 @@
|
|||||||
<layout class="QGridLayout" name="gridLayout_5">
|
<layout class="QGridLayout" name="gridLayout_5">
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QGroupBox" name="groupBox">
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Backup destination directory</string>
|
<string>Backup destination directory</string>
|
||||||
</property>
|
</property>
|
||||||
@ -176,71 +182,103 @@
|
|||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QGroupBox" name="groupBox_2">
|
<widget class="QGroupBox" name="groupBox_2">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Backup security</string>
|
<string>Backup security</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QFormLayout" name="formLayout">
|
<layout class="QFormLayout" name="formLayout">
|
||||||
<item row="2" column="0">
|
<property name="fieldGrowthPolicy">
|
||||||
|
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||||
|
</property>
|
||||||
|
<item row="1" column="0">
|
||||||
<widget class="QLabel" name="label_12">
|
<widget class="QLabel" name="label_12">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string><html><head/><body><p>Encryption / Verification<br/>passphrase:</p></body></html></string>
|
<string><html><head/><body><p>Encryption / Verification<br/>passphrase:</p></body></html></string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="0">
|
<item row="1" column="1">
|
||||||
<widget class="QLabel" name="label_10">
|
|
||||||
<property name="text">
|
|
||||||
<string>Encrypt backup:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QCheckBox" name="encryption_checkbox">
|
|
||||||
<property name="layoutDirection">
|
|
||||||
<enum>Qt::LeftToRight</enum>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="0">
|
|
||||||
<widget class="QLabel" name="label_11">
|
|
||||||
<property name="text">
|
|
||||||
<string><html><head/><body><p>Reenter passphrase:</p></body></html></string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="1">
|
|
||||||
<widget class="QLineEdit" name="passphrase_line_edit">
|
<widget class="QLineEdit" name="passphrase_line_edit">
|
||||||
<property name="echoMode">
|
<property name="echoMode">
|
||||||
<enum>QLineEdit::Password</enum>
|
<enum>QLineEdit::Password</enum>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="1">
|
<item row="4" column="0">
|
||||||
|
<widget class="QLabel" name="label_11">
|
||||||
|
<property name="text">
|
||||||
|
<string><html><head/><body><p>Reenter passphrase:</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="1">
|
||||||
<widget class="QLineEdit" name="passphrase_line_edit_verify">
|
<widget class="QLineEdit" name="passphrase_line_edit_verify">
|
||||||
<property name="echoMode">
|
<property name="echoMode">
|
||||||
<enum>QLineEdit::Password</enum>
|
<enum>QLineEdit::Password</enum>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="6" column="1">
|
|
||||||
<widget class="QLabel" name="label">
|
|
||||||
<property name="text">
|
|
||||||
<string><b>Note:</b> Even if you choose not to encrypt your backup, a password is still required in order to provide authenticated verification of the data. See the emergency restore instructions for more info.</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QGroupBox" name="groupBox_3">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>Save backup profile</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QLabel" name="label_8">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>10</x>
|
||||||
|
<y>30</y>
|
||||||
|
<width>267</width>
|
||||||
|
<height>25</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Save settings as default backup profile:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QCheckBox" name="save_profile_checkbox">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>270</x>
|
||||||
|
<y>30</y>
|
||||||
|
<width>539</width>
|
||||||
|
<height>25</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string> </string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<zorder>checkBox</zorder>
|
||||||
|
<zorder>groupBox_2</zorder>
|
||||||
|
<zorder>groupBox_2</zorder>
|
||||||
|
<zorder>label_8</zorder>
|
||||||
|
<zorder>save_profile_checkbox</zorder>
|
||||||
|
<zorder>groupBox_2</zorder>
|
||||||
|
<zorder>label_8</zorder>
|
||||||
|
<zorder>label_8</zorder>
|
||||||
|
<zorder>save_profile_checkbox</zorder>
|
||||||
|
<zorder>label_8</zorder>
|
||||||
|
<zorder>save_profile_checkbox</zorder>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QWizardPage" name="confirm_page">
|
<widget class="QWizardPage" name="confirm_page">
|
||||||
|
@ -147,6 +147,9 @@
|
|||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
@ -211,8 +214,8 @@
|
|||||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
<string><!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">
|
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||||
p, li { white-space: pre-wrap; }
|
p, li { white-space: pre-wrap; }
|
||||||
</style></head><body style=" font-family:'Sans Serif'; font-size:10pt; font-weight:400; font-style:normal;">
|
</style></head><body style=" font-family:'Cantarell'; font-size:11pt; 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></string>
|
<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-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html></string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
Loading…
Reference in New Issue
Block a user