Merge branch 'master' of git.qubes-os.org:/var/lib/qubes/git/marmarek/qubes-manager

This commit is contained in:
Joanna Rutkowska 2012-07-12 13:43:36 +02:00
commit 2bdfa028f4
2 changed files with 80 additions and 3 deletions

View File

@ -229,7 +229,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>769</width> <width>769</width>
<height>25</height> <height>22</height>
</rect> </rect>
</property> </property>
<widget class="QMenu" name="menu_system"> <widget class="QMenu" name="menu_system">
@ -285,6 +285,7 @@
</widget> </widget>
<addaction name="action_createvm"/> <addaction name="action_createvm"/>
<addaction name="action_removevm"/> <addaction name="action_removevm"/>
<addaction name="action_clonevm"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="action_resumevm"/> <addaction name="action_resumevm"/>
<addaction name="action_pausevm"/> <addaction name="action_pausevm"/>
@ -738,6 +739,18 @@
<string>Run command in the specified VM</string> <string>Run command in the specified VM</string>
</property> </property>
</action> </action>
<action name="action_clonevm">
<property name="enabled">
<bool>false</bool>
</property>
<property name="icon">
<iconset resource="resources.qrc">
<normaloff>:/templatevm.png</normaloff>:/templatevm.png</iconset>
</property>
<property name="text">
<string>Clone VM</string>
</property>
</action>
</widget> </widget>
<resources> <resources>
<include location="resources.qrc"/> <include location="resources.qrc"/>

View File

@ -39,6 +39,7 @@ from qubes.qubes import dry_run
from qubes.qubes import qubes_guid_path from qubes.qubes import qubes_guid_path
from qubes.qubes import QubesDaemonPidfile from qubes.qubes import QubesDaemonPidfile
from qubes.qubes import QubesHost from qubes.qubes import QubesHost
from qubes import qubes
from qubes import qubesutils from qubes import qubesutils
import qubesmanager.resources_rc import qubesmanager.resources_rc
@ -647,8 +648,6 @@ class VmShutdownMonitor(QObject):
vm = self.vm vm = self.vm
vm_start_time = vm.get_start_time() vm_start_time = vm.get_start_time()
if not vm.is_running() or (vm_start_time and vm_start_time >= datetime.utcnow() - timedelta(0,self.shutdown_time/1000)): if not vm.is_running() or (vm_start_time and vm_start_time >= datetime.utcnow() - timedelta(0,self.shutdown_time/1000)):
if vm.is_template():
trayIcon.showMessage ("You have just modified template '{0}'. You should now restart all the VMs based on it, so they could see the changes.".format(vm.name), msecs=8000)
return return
reply = QMessageBox.question(None, "VM Shutdown", reply = QMessageBox.question(None, "VM Shutdown",
@ -756,6 +755,7 @@ class VmManagerWindow(Ui_VmManagerWindow, QMainWindow):
self.context_menu = QMenu(self) self.context_menu = QMenu(self)
self.context_menu.addAction(self.action_removevm) self.context_menu.addAction(self.action_removevm)
self.context_menu.addAction(self.action_resumevm) self.context_menu.addAction(self.action_resumevm)
self.context_menu.addAction(self.action_clonevm)
self.context_menu.addAction(self.action_pausevm) self.context_menu.addAction(self.action_pausevm)
self.context_menu.addAction(self.action_shutdownvm) self.context_menu.addAction(self.action_shutdownvm)
self.context_menu.addAction(self.action_killvm) self.context_menu.addAction(self.action_killvm)
@ -1075,6 +1075,7 @@ class VmManagerWindow(Ui_VmManagerWindow, QMainWindow):
# Update available actions: # Update available actions:
self.action_settings.setEnabled(vm.qid != 0) self.action_settings.setEnabled(vm.qid != 0)
self.action_removevm.setEnabled(not vm.installed_by_rpm and not (vm.last_running)) self.action_removevm.setEnabled(not vm.installed_by_rpm and not (vm.last_running))
self.action_clonevm.setEnabled(not vm.installed_by_rpm and not (vm.last_running) and not vm.is_netvm())
self.action_resumevm.setEnabled(not vm.last_running) self.action_resumevm.setEnabled(not vm.last_running)
self.action_pausevm.setEnabled(vm.last_running and vm.qid != 0) self.action_pausevm.setEnabled(vm.last_running and vm.qid != 0)
self.action_shutdownvm.setEnabled(vm.last_running and vm.qid != 0) self.action_shutdownvm.setEnabled(vm.last_running and vm.qid != 0)
@ -1087,6 +1088,7 @@ class VmManagerWindow(Ui_VmManagerWindow, QMainWindow):
else: else:
self.action_settings.setEnabled(False) self.action_settings.setEnabled(False)
self.action_removevm.setEnabled(False) self.action_removevm.setEnabled(False)
self.action_clonevm.setEnabled(False)
self.action_resumevm.setEnabled(False) self.action_resumevm.setEnabled(False)
self.action_pausevm.setEnabled(False) self.action_pausevm.setEnabled(False)
self.action_shutdownvm.setEnabled(False) self.action_shutdownvm.setEnabled(False)
@ -1215,6 +1217,68 @@ class VmManagerWindow(Ui_VmManagerWindow, QMainWindow):
thread_monitor.set_finished() thread_monitor.set_finished()
@pyqtSlot(name='on_action_clonevm_triggered')
def action_clonevm_triggered(self):
vm = self.get_selected_vm()
name_number = 1
name_format = vm.name + '-clone-%d'
while self.qvm_collection.get_vm_by_name(name_format % name_number):
name_number += 1
cmd = ['kdialog', '--title', 'Qubes clone VM', '--inputbox', 'Enter name for VM <b>'+vm.name+'</b> clone:', name_format % name_number]
kdialog = subprocess.Popen(cmd, stdout = subprocess.PIPE)
clone_name = kdialog.stdout.read().strip()
if clone_name == "":
return
thread_monitor = ThreadMonitor()
thread = threading.Thread (target=self.do_clone_vm, args=(vm, clone_name, thread_monitor))
thread.daemon = True
thread.start()
progress = QProgressDialog ("Cloning VM <b>{0}</b> to <b>{1}</b>...".format(vm.name, clone_name), "", 0, 0)
progress.setCancelButton(None)
progress.setModal(True)
progress.show()
while not thread_monitor.is_finished():
app.processEvents()
time.sleep (0.2)
progress.hide()
if not thread_monitor.success:
QMessageBox.warning (None, "Error while cloning VM", "Exception while cloning:<br>{0}".format(thread_monitor.error_msg))
def do_clone_vm(self, vm, dst_name, thread_monitor):
try:
self.qvm_collection.lock_db_for_writing()
self.qvm_collection.load()
src_vm = self.qvm_collection[vm.qid]
dst_vm = None
if isinstance(src_vm, qubes.QubesTemplateVm):
dst_vm = self.qvm_collection.add_new_templatevm(name=dst_name,
installed_by_rpm=False)
elif isinstance(src_vm, qubes.QubesAppVm):
dst_vm = self.qvm_collection.add_new_appvm(name=dst_name, template=src_vm.template,
label=src_vm.label)
elif hasattr(qubes, 'QubesHVm') and isinstance(src_vm, qubes.QubesHVm):
dst_vm = self.qvm_collection.add_new_hvm(name=dst_name, label=src_vm.label)
dst_vm.clone_attrs(src_vm)
dst_vm.clone_disk_files (src_vm=src_vm, verbose=False)
self.qvm_collection.save()
self.qvm_collection.unlock_db()
except Exception as ex:
if dst_vm:
self.qvm_collection.pop(dst_vm.qid)
self.qvm_collection.unlock_db()
thread_monitor.set_error_msg(str(ex))
thread_monitor.set_finished()
@pyqtSlot(name='on_action_resumevm_triggered') @pyqtSlot(name='on_action_resumevm_triggered')
def action_resumevm_triggered(self): def action_resumevm_triggered(self):
vm = self.get_selected_vm() vm = self.get_selected_vm()