Merge remote-tracking branch 'qubesos/pr/41'

* qubesos/pr/41:
  Create new VM
This commit is contained in:
Marek Marczykowski-Górecki 2017-09-14 00:28:39 +02:00
commit 54b45a91af
No known key found for this signature in database
GPG Key ID: 063938BA42CFA724
2 changed files with 140 additions and 62 deletions

View File

@ -26,6 +26,7 @@ import os
import sys import sys
import threading import threading
import time import time
import subprocess
from PyQt4.QtCore import * from PyQt4.QtCore import *
from PyQt4.QtGui import * from PyQt4.QtGui import *
@ -52,7 +53,6 @@ class NewVmDlg(QDialog, Ui_NewVMDlg):
# Theoretically we should be locking for writing here and unlock # Theoretically we should be locking for writing here and unlock
# only after the VM creation finished. But the code would be more messy... # only after the VM creation finished. But the code would be more messy...
# Instead we lock for writing in the actual worker thread # Instead we lock for writing in the actual worker thread
self.label_list, self.label_idx = utils.prepare_label_choice( self.label_list, self.label_idx = utils.prepare_label_choice(
self.label, self.label,
self.app, None, self.app, None,
@ -83,11 +83,23 @@ class NewVmDlg(QDialog, Ui_NewVMDlg):
self.tr('No template available!'), self.tr('No template available!'),
self.tr('Cannot create a qube when no template exists.')) self.tr('Cannot create a qube when no template exists.'))
# Order of types is important and used elsewhere; if it's changed
# check for changes needed in self.type_change and TODO
type_list = [self.tr("AppVM"),
self.tr("Standalone VM based on a template"),
self.tr("Standalone VM not based on a template")]
self.vm_type.addItems(type_list)
self.vm_type.currentIndexChanged.connect(self.type_change)
self.launch_settings.stateChanged.connect(self.settings_change)
self.install_system.stateChanged.connect(self.install_change)
def reject(self): def reject(self):
self.done(0) self.done(0)
def accept(self): def accept(self):
vmclass = ('StandaloneVM' if self.standalone.isChecked() else 'AppVM') vmclass = ('AppVM' if self.vm_type.currentIndex() == 0 else 'StandaloneVM')
name = str(self.name.text()) name = str(self.name.text())
try: try:
@ -102,11 +114,15 @@ class NewVmDlg(QDialog, Ui_NewVMDlg):
return return
label = self.label_list[self.label.currentIndex()] label = self.label_list[self.label.currentIndex()]
template = self.template_list[self.template_vm.currentIndex()]
if self.template_vm.currentIndex() == -1:
template = None
else:
template = self.template_list[self.template_vm.currentIndex()]
properties = {} properties = {}
properties['provides_network'] = self.provides_network.isChecked() properties['provides_network'] = self.provides_network.isChecked()
properties['virt_mode'] = 'hvm' if self.hvm.isChecked() else 'pv' properties['virt_mode'] = 'hvm'
properties['netvm'] = self.netvm_list[self.netvm.currentIndex()] properties['netvm'] = self.netvm_list[self.netvm.currentIndex()]
thread_monitor = ThreadMonitor() thread_monitor = ThreadMonitor()
@ -135,20 +151,68 @@ class NewVmDlg(QDialog, Ui_NewVMDlg):
self.done(0) self.done(0)
if thread_monitor.success:
if self.launch_settings.isChecked():
subprocess.check_call(['qubes-vm-settings', name])
if self.install_system.isChecked():
subprocess.check_call(
['qubes-vm-boot-from-device', name])
@staticmethod @staticmethod
def do_create_vm(app, vmclass, name, label, template, properties, def do_create_vm(app, vmclass, name, label, template, properties,
thread_monitor): thread_monitor):
try: try:
vm = app.add_new_vm(vmclass, if vmclass == 'StandaloneVM' and template is not None:
name=name, label=label, template=template) if template is qubesadmin.DEFAULT:
for k, v in properties.items(): src_vm = app.default_template
setattr(vm, k, v) else:
src_vm = template
vm = app.clone_vm(src_vm, name, vmclass)
vm.label = label
for k, v in properties.items():
setattr(vm, k, v)
else:
vm = app.add_new_vm(vmclass,
name=name, label=label, template=template)
for k, v in properties.items():
setattr(vm, k, v)
except Exception as ex: except Exception as ex:
thread_monitor.set_error_msg(str(ex)) thread_monitor.set_error_msg(str(ex))
thread_monitor.set_finished() thread_monitor.set_finished()
def type_change(self):
# AppVM
if self.vm_type.currentIndex() == 0:
self.template_vm.setEnabled(True)
self.template_vm.setCurrentIndex(0)
self.install_system.setEnabled(False)
self.install_system.setChecked(False)
# Standalone - based on a template
if self.vm_type.currentIndex() == 1:
self.template_vm.setEnabled(True)
self.template_vm.setCurrentIndex(0)
self.install_system.setEnabled(False)
self.install_system.setChecked(False)
# Standalone - not based on a template
if self.vm_type.currentIndex() == 2:
self.template_vm.setEnabled(False)
self.template_vm.setCurrentIndex(-1)
self.install_system.setEnabled(True)
self.install_system.setChecked(True)
def install_change(self):
if self.install_system.isChecked():
self.launch_settings.setChecked(False)
def settings_change(self):
if self.launch_settings.isChecked() and self.install_system.isEnabled():
self.install_system.setChecked(False)
parser = qubesadmin.tools.QubesArgumentParser() parser = qubesadmin.tools.QubesArgumentParser()
def main(args=None): def main(args=None):

View File

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>618</width> <width>616</width>
<height>214</height> <height>300</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -21,8 +21,8 @@
<widget class="QDialogButtonBox" name="buttonBox"> <widget class="QDialogButtonBox" name="buttonBox">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>330</x> <x>450</x>
<y>180</y> <y>260</y>
<width>160</width> <width>160</width>
<height>27</height> <height>27</height>
</rect> </rect>
@ -39,22 +39,55 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>10</y> <y>10</y>
<width>596</width> <width>611</width>
<height>175</height> <height>241</height>
</rect> </rect>
</property> </property>
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<item row="0" column="3"> <item row="2" column="0">
<widget class="QComboBox" name="label"> <widget class="QLabel" name="template_label">
<property name="frame"> <property name="text">
<bool>true</bool> <string>Template:</string>
</property>
<property name="buddy">
<cstring>template_vm</cstring>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="1" colspan="2"> <item row="6" column="0">
<widget class="QLineEdit" name="name"> <widget class="QLabel" name="netvm_label">
<property name="text"> <property name="text">
<string>my-new-vm</string> <string>Networking:</string>
</property>
<property name="buddy">
<cstring>template_vm</cstring>
</property>
</widget>
</item>
<item row="9" column="1" colspan="3">
<widget class="QCheckBox" name="install_system">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>install system from device (also available from settings)</string>
</property>
</widget>
</item>
<item row="8" column="1" colspan="3">
<widget class="QCheckBox" name="launch_settings">
<property name="text">
<string>launch settings after creation</string>
</property>
</widget>
</item>
<item row="2" column="1" colspan="3">
<widget class="QComboBox" name="template_vm"/>
</item>
<item row="7" column="1" colspan="3">
<widget class="QCheckBox" name="provides_network">
<property name="text">
<string>provides network</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -68,56 +101,37 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="1" colspan="3"> <item row="0" column="3">
<widget class="QComboBox" name="netvm"/> <widget class="QComboBox" name="label">
</item> <property name="frame">
<item row="1" column="0">
<widget class="QLabel" name="template_label">
<property name="text">
<string>Use this template:</string>
</property>
<property name="buddy">
<cstring>template_vm</cstring>
</property>
</widget>
</item>
<item row="1" column="1" colspan="3">
<widget class="QComboBox" name="template_vm"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="netvm_label">
<property name="text">
<string>Network:</string>
</property>
<property name="buddy">
<cstring>template_vm</cstring>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QCheckBox" name="hvm">
<property name="text">
<string>HVM</string>
</property>
<property name="checked">
<bool>true</bool> <bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="1"> <item row="7" column="0">
<widget class="QCheckBox" name="provides_network"> <widget class="QLabel" name="label_3">
<property name="text"> <property name="text">
<string>Provides network</string> <string>Advanced</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="3"> <item row="6" column="1" colspan="3">
<widget class="QCheckBox" name="standalone"> <widget class="QComboBox" name="netvm"/>
<property name="enabled"> </item>
<bool>false</bool> <item row="0" column="1" colspan="2">
</property> <widget class="QLineEdit" name="name">
<property name="text"> <property name="text">
<string>Standalone</string> <string>my-new-vm</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="3">
<widget class="QComboBox" name="vm_type"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Type:</string>
</property> </property>
</widget> </widget>
</item> </item>