All VMs available on backup list. One click 'shutdown running'
This commit is contained in:
parent
b616a8f536
commit
81bb0f75a6
92
backupdlg.ui
92
backupdlg.ui
@ -22,20 +22,80 @@
|
||||
<widget class="QWizardPage" name="select_vms_page">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>9</pointsize>
|
||||
<weight>50</weight>
|
||||
<italic>false</italic>
|
||||
<bold>false</bold>
|
||||
<underline>false</underline>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Select VMs to backup:</string>
|
||||
</property>
|
||||
</widget>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="shutdown_running_vms_button">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Shutdown all running selected VMs</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/shutdownvm.png</normaloff>:/shutdownvm.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QPushButton" name="refresh_button">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Refresh running states.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" rowspan="2">
|
||||
<widget class="QLabel" name="running_vms_warning">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<italic>true</italic>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color:rgb(255, 0, 0)</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Some of the selected VMs are running (red). Running VMs can not be backuped!</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>9</pointsize>
|
||||
<weight>50</weight>
|
||||
<italic>false</italic>
|
||||
<bold>false</bold>
|
||||
<underline>false</underline>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Select VMs to backup:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
@ -187,6 +247,8 @@ p, li { white-space: pre-wrap; }
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<resources>
|
||||
<include location="resources.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
@ -54,12 +54,13 @@ class BackupVMsWindow(Ui_Backup, QWizard):
|
||||
|
||||
__pyqtSignals__ = ("backup_progress(int)",)
|
||||
|
||||
def __init__(self, app, qvm_collection, blk_manager, parent=None):
|
||||
def __init__(self, app, qvm_collection, blk_manager, shutdown_vm_func, parent=None):
|
||||
super(BackupVMsWindow, self).__init__(parent)
|
||||
|
||||
self.app = app
|
||||
self.qvm_collection = qvm_collection
|
||||
self.blk_manager = blk_manager
|
||||
self.shutdown_vm_func = shutdown_vm_func
|
||||
|
||||
self.dev_mount_path = None
|
||||
self.backup_dir = None
|
||||
@ -75,12 +76,16 @@ class BackupVMsWindow(Ui_Backup, QWizard):
|
||||
|
||||
self.setupUi(self)
|
||||
|
||||
self.show_running_vms_warning(False)
|
||||
self.dir_line_edit.setReadOnly(True)
|
||||
|
||||
self.select_vms_widget = MultiSelectWidget(self)
|
||||
self.verticalLayout.insertWidget(1, self.select_vms_widget)
|
||||
|
||||
self.connect(self, SIGNAL("currentIdChanged(int)"), self.current_page_changed)
|
||||
self.connect(self.select_vms_widget, SIGNAL("selected_changed()"), self.check_running)
|
||||
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)
|
||||
|
||||
@ -93,26 +98,92 @@ class BackupVMsWindow(Ui_Backup, QWizard):
|
||||
self.__fill_vms_list__()
|
||||
fill_devs_list(self)
|
||||
|
||||
def show_running_vms_warning(self, show):
|
||||
self.running_vms_warning.setVisible(show)
|
||||
self.shutdown_running_vms_button.setVisible(show)
|
||||
self.refresh_button.setVisible(show)
|
||||
|
||||
class VmListItem(QListWidgetItem):
|
||||
def __init__(self, vm):
|
||||
super(BackupVMsWindow.VmListItem, self).__init__(vm.name)
|
||||
self.vm = vm
|
||||
|
||||
def __fill_vms_list__(self):
|
||||
for vm in self.qvm_collection.values():
|
||||
if vm.is_running() and vm.qid != 0:
|
||||
self.excluded.append(vm.name)
|
||||
continue
|
||||
|
||||
if vm.is_appvm() and vm.internal:
|
||||
self.excluded.append(vm.name)
|
||||
continue
|
||||
|
||||
if vm.is_template() and vm.installed_by_rpm:
|
||||
self.excluded.append(vm.name)
|
||||
continue
|
||||
|
||||
item = BackupVMsWindow.VmListItem(vm)
|
||||
if vm.include_in_backups == True:
|
||||
self.select_vms_widget.selected_list.addItem(vm.name)
|
||||
self.select_vms_widget.selected_list.addItem(item)
|
||||
else:
|
||||
self.select_vms_widget.available_list.addItem(vm.name)
|
||||
self.select_vms_widget.available_list.addItem(item)
|
||||
self.check_running()
|
||||
|
||||
def check_running(self):
|
||||
some_selected_vms_running = False
|
||||
for i in range(self.select_vms_widget.selected_list.count()):
|
||||
item = self.select_vms_widget.selected_list.item(i)
|
||||
if item.vm.is_running() and item.vm.qid != 0:
|
||||
item.setForeground(QBrush(QColor(255, 0, 0)))
|
||||
some_selected_vms_running = True
|
||||
else:
|
||||
item.setForeground(QBrush(QColor(0, 0, 0)))
|
||||
|
||||
self.show_running_vms_warning(some_selected_vms_running)
|
||||
|
||||
for i in range(self.select_vms_widget.available_list.count()):
|
||||
item = self.select_vms_widget.available_list.item(i)
|
||||
if item.vm.is_running() and item.vm.qid != 0:
|
||||
item.setForeground(QBrush(QColor(255, 0, 0)))
|
||||
else:
|
||||
item.setForeground(QBrush(QColor(0, 0, 0)))
|
||||
|
||||
return some_selected_vms_running
|
||||
|
||||
def shutdown_all_running_selected(self):
|
||||
names = []
|
||||
vms = []
|
||||
for i in range(self.select_vms_widget.selected_list.count()):
|
||||
item = self.select_vms_widget.selected_list.item(i)
|
||||
if item.vm.is_running() and item.vm.qid != 0:
|
||||
names.append(item.vm.name)
|
||||
vms.append(item.vm)
|
||||
|
||||
if len(vms) == 0:
|
||||
return;
|
||||
|
||||
reply = QMessageBox.question(None, "VM Shutdown Confirmation",
|
||||
"Are you sure you want to power down the following VMs: <b>{0}</b>?<br>"
|
||||
"<small>This will shutdown all the running applications within them.</small>".format(', '.join(names)),
|
||||
QMessageBox.Yes | QMessageBox.Cancel)
|
||||
|
||||
self.app.processEvents()
|
||||
|
||||
if reply == QMessageBox.Yes:
|
||||
for vm in vms:
|
||||
self.shutdown_vm_func(vm)
|
||||
|
||||
progress = QProgressDialog ("Shutting down VMs <b>{0}</b>...".format(', '.join(names)), "", 0, 0)
|
||||
progress.setModal(True)
|
||||
progress.show()
|
||||
|
||||
wait_time = 15.0
|
||||
wait_for = wait_time
|
||||
while self.check_running() and wait_for > 0:
|
||||
self.app.processEvents()
|
||||
time.sleep (0.1)
|
||||
wait_for -= 0.1
|
||||
|
||||
progress.hide()
|
||||
|
||||
if self.check_running():
|
||||
QMessageBox.information(None, "Strange", "Could not power down the VMs in {0} seconds...".format(wait_time))
|
||||
|
||||
|
||||
|
||||
|
||||
def dev_combobox_activated(self, idx):
|
||||
dev_combobox_activated(self, idx)
|
||||
|
||||
@ -123,9 +194,16 @@ class BackupVMsWindow(Ui_Backup, QWizard):
|
||||
|
||||
def validateCurrentPage(self):
|
||||
if self.currentPage() is self.select_vms_page:
|
||||
for i in range(self.select_vms_widget.selected_list.count()):
|
||||
if self.check_running() == True:
|
||||
QMessageBox.information(None, "Wait!", "Some selected VMs are running. Running VMs can not be backuped. Please shut them down or remove them from the list.")
|
||||
return False
|
||||
|
||||
del self.excluded[:]
|
||||
for i in range(self.select_vms_widget.available_list.count()):
|
||||
vmname = self.select_vms_widget.available_list.item(i).text()
|
||||
vmname = str(self.select_vms_widget.available_list.item(i).text())
|
||||
self.excluded.append(vmname)
|
||||
|
||||
return True
|
||||
|
||||
def gather_output(self, s):
|
||||
@ -152,7 +230,10 @@ class BackupVMsWindow(Ui_Backup, QWizard):
|
||||
def current_page_changed(self, id):
|
||||
if self.currentPage() is self.confirm_page:
|
||||
del self.func_output[:]
|
||||
self.files_to_backup = qubesutils.backup_prepare(str(self.backup_dir), exclude_list = self.excluded, print_callback = self.gather_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))
|
||||
|
||||
self.textEdit.setReadOnly(True)
|
||||
self.textEdit.setFontFamily("Monospace")
|
||||
@ -213,8 +294,6 @@ def handle_exception( exc_type, exc_value, exc_traceback ):
|
||||
% ( line, filename ))
|
||||
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
global qubes_host
|
||||
|
@ -1142,16 +1142,22 @@ class VmManagerWindow(Ui_VmManagerWindow, QMainWindow):
|
||||
app.processEvents()
|
||||
|
||||
if reply == QMessageBox.Yes:
|
||||
try:
|
||||
subprocess.check_call (["/usr/sbin/xl", "shutdown", vm.name])
|
||||
except Exception as ex:
|
||||
QMessageBox.warning (None, "Error shutting down VM!", "ERROR: {0}".format(ex))
|
||||
return
|
||||
self.shutdown_vm(vm)
|
||||
|
||||
|
||||
def shutdown_vm(self, vm):
|
||||
try:
|
||||
subprocess.check_call (["/usr/sbin/xl", "shutdown", vm.name])
|
||||
except Exception as ex:
|
||||
QMessageBox.warning (None, "Error shutting down VM!", "ERROR: {0}".format(ex))
|
||||
return
|
||||
|
||||
trayIcon.showMessage ("Qubes Manager", "VM '{0}' is shutting down...".format(vm.name), msecs=3000)
|
||||
|
||||
self.shutdown_monitor[vm.qid] = VmShutdownMonitor (vm)
|
||||
QTimer.singleShot (vm_shutdown_timeout, self.shutdown_monitor[vm.qid].check_if_vm_has_shutdown)
|
||||
|
||||
trayIcon.showMessage ("Qubes Manager", "VM '{0}' is shutting down...".format(vm.name), msecs=3000)
|
||||
|
||||
self.shutdown_monitor[vm.qid] = VmShutdownMonitor (vm)
|
||||
QTimer.singleShot (vm_shutdown_timeout, self.shutdown_monitor[vm.qid].check_if_vm_has_shutdown)
|
||||
|
||||
@pyqtSlot(name='on_action_settings_triggered')
|
||||
def action_settings_triggered(self):
|
||||
@ -1235,7 +1241,7 @@ class VmManagerWindow(Ui_VmManagerWindow, QMainWindow):
|
||||
|
||||
@pyqtSlot(name='on_action_backup_triggered')
|
||||
def action_backup_triggered(self):
|
||||
backup_window = BackupVMsWindow(app, self.qvm_collection, self.blk_manager)
|
||||
backup_window = BackupVMsWindow(app, self.qvm_collection, self.blk_manager, self.shutdown_vm)
|
||||
backup_window.exec_()
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user