Add handling for virt_mode including PVH mode

This commit is contained in:
HW42 2017-10-12 17:06:17 +02:00
parent 14b6eed25b
commit ebc7426cab
2 changed files with 224 additions and 3 deletions

View File

@ -28,6 +28,7 @@ import collections
import copy import copy
import os import os
import os.path import os.path
import re
import subprocess import subprocess
import sys import sys
import threading import threading
@ -462,6 +463,7 @@ class VMSettingsWindow(Ui_SettingsDialog, QDialog):
self.kernel, self.vm, 'kernel', self.kernel, self.vm, 'kernel',
self.vm.app.default_kernel, self.vm.app.default_kernel,
allow_default=True, allow_none=True) allow_default=True, allow_none=True)
self.kernel.currentIndexChanged.connect(self.kernel_changed)
else: else:
self.kernel_groupbox.setVisible(False) self.kernel_groupbox.setVisible(False)
@ -479,6 +481,8 @@ class VMSettingsWindow(Ui_SettingsDialog, QDialog):
(lambda vm: vm.klass == 'DispVM'), (lambda vm: vm.klass == 'DispVM'),
allow_default=True, allow_none=True) allow_default=True, allow_none=True)
self.update_virt_mode_list()
def __apply_advanced_tab__(self): def __apply_advanced_tab__(self):
msg = [] msg = []
@ -518,12 +522,105 @@ class VMSettingsWindow(Ui_SettingsDialog, QDialog):
except Exception as ex: except Exception as ex:
msg.append(str(ex)) msg.append(str(ex))
try:
if self.virt_mode.currentIndex() != self.virt_mode_idx:
self.vm.virt_mode = self.selected_virt_mode()
self.anything_changed = True
except Exception as ex:
msg.append(str(ex))
return msg return msg
def boot_from_cdrom_button_pressed(self): def boot_from_cdrom_button_pressed(self):
self.save_and_apply() self.save_and_apply()
subprocess.check_call(['qubes-vm-boot-from-device', self.vm.name]) subprocess.check_call(['qubes-vm-boot-from-device', self.vm.name])
def selected_virt_mode(self):
return self.virt_mode_list[self.virt_mode.currentIndex()]
def virt_mode_changed(self, new_idx):
self.update_pv_warning()
self.update_pvh_dont_support_devs()
self.update_pvh_kernel_version_warning()
def update_pv_warning(self):
if self.selected_virt_mode() == 'pv':
self.pv_warning.show()
else:
self.pv_warning.hide()
def update_virt_mode_list(self):
choices = ['hvm', 'pv']
if hasattr(self, 'dev_list'):
devs_attached = self.dev_list.selected_list.count() != 0
else:
devs_attached = len(list(self.vm.devices['pci'].persistent())) != 0
if devs_attached:
self.pvh_mode_hidden.show()
else:
choices.insert(0, 'pvh')
self.pvh_mode_hidden.hide()
if hasattr(self, 'virt_mode_list'):
old_mode = self.selected_virt_mode()
self.virt_mode.currentIndexChanged.disconnect()
else:
old_mode = None
self.virt_mode.clear()
# XXX: Hardcoded default value.
self.virt_mode_list, self.virt_mode_idx = utils.prepare_choice(
self.virt_mode, self.vm, 'virt_mode', choices, 'hvm',
allow_default=True)
if old_mode is not None:
self.virt_mode.setCurrentIndex(self.virt_mode_list.index(old_mode))
self.virt_mode.currentIndexChanged.connect(self.virt_mode_changed)
self.update_pv_warning()
self.update_pvh_kernel_version_warning()
def update_pvh_kernel_version_warning(self):
if self.selected_virt_mode() != 'pvh':
self.pvh_kernel_version_warning.hide()
return
kernel = self.kernel_list[self.kernel.currentIndex()]
if self.pvh_kernel_version_ok(kernel):
self.pvh_kernel_version_warning.hide()
else:
self.pvh_kernel_version_warning.show()
def kernel_changed(self):
self.update_pvh_kernel_version_warning()
def pvh_kernel_version_ok(self, name):
# There are nearly no limitaions on kernel names (only file system and
# general qvm-prefs rules). So we just look if we see something which
# looks like a version number. It's just a warning to help the user
# anyways.
if name is None:
return False
if name is qubesadmin.DEFAULT:
name = self.vm.app.default_kernel
m = re.search('(\d+)\.(\d+)', name)
if m is None:
return False
x = int(m.group(1))
y = int(m.group(2))
return (x, y) >= (4, 11)
######## devices tab ######## devices tab
def __init_devices_tab__(self): def __init_devices_tab__(self):
self.dev_list = multiselectwidget.MultiSelectWidget(self) self.dev_list = multiselectwidget.MultiSelectWidget(self)
@ -566,6 +663,8 @@ class VMSettingsWindow(Ui_SettingsDialog, QDialog):
self.dev_list.setEnabled(True) self.dev_list.setEnabled(True)
self.turn_off_vm_to_modify_devs.setVisible(False) self.turn_off_vm_to_modify_devs.setVisible(False)
self.update_pvh_dont_support_devs()
def __apply_devices_tab__(self): def __apply_devices_tab__(self):
msg = [] msg = []
@ -621,6 +720,16 @@ class VMSettingsWindow(Ui_SettingsDialog, QDialog):
self.dmm_warning_adv.hide() self.dmm_warning_adv.hide()
self.dmm_warning_dev.hide() self.dmm_warning_dev.hide()
self.update_virt_mode_list()
def update_pvh_dont_support_devs(self):
if self.selected_virt_mode() == 'pvh':
self.dev_list.setEnabled(False)
self.pvh_dont_support_devs.setVisible(True)
else:
self.dev_list.setEnabled(True)
self.pvh_dont_support_devs.setVisible(False)
######## applications tab ######## applications tab
def refresh_apps_in_vm(self, t_monitor): def refresh_apps_in_vm(self, t_monitor):

View File

@ -409,7 +409,7 @@
<property name="fieldGrowthPolicy"> <property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum> <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property> </property>
<item row="0" column="0"> <item row="0" column="0" rowspan="2">
<widget class="QLabel" name="label_19"> <widget class="QLabel" name="label_19">
<property name="text"> <property name="text">
<string>Kernel:</string> <string>Kernel:</string>
@ -422,14 +422,31 @@
<item row="0" column="1"> <item row="0" column="1">
<widget class="QComboBox" name="kernel"/> <widget class="QComboBox" name="kernel"/>
</item> </item>
<item row="1" column="0"> <item row="1" column="1">
<widget class="QLabel" name="pvh_kernel_version_warning">
<property name="font">
<font>
<weight>75</weight>
<italic>true</italic>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>PVH mode requires Linux 4.11 or newer.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_20"> <widget class="QLabel" name="label_20">
<property name="text"> <property name="text">
<string>Kernel opts:</string> <string>Kernel opts:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="2" column="1">
<widget class="QLabel" name="kernel_opts"> <widget class="QLabel" name="kernel_opts">
<property name="font"> <property name="font">
<font> <font>
@ -447,6 +464,87 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="2" column="1" rowspan="2" colspan="2">
<layout class="QVBoxLayout" name="verticalLayout_7">
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="virt_groupbox">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Virtualization</string>
</property>
<layout class="QFormLayout" name="formLayout_10">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="0" column="0" rowspan="3">
<widget class="QLabel" name="label_27">
<property name="text">
<string>Mode:</string>
</property>
<property name="buddy">
<cstring>virt_mode</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="virt_mode"/>
</item>
<item row="1" column="1">
<widget class="QLabel" name="pv_warning">
<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>Using PV mode exposes more hypervisor attack surface!</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="pvh_mode_hidden">
<property name="font">
<font>
<weight>75</weight>
<italic>true</italic>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>PVH mode is hidden since it doesn't support PCI passthrough.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item row="2" column="0"> <item row="2" column="0">
<widget class="QGroupBox" name="other_groupbox"> <widget class="QGroupBox" name="other_groupbox">
<property name="title"> <property name="title">
@ -894,6 +992,20 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QLabel" name="pvh_dont_support_devs">
<property name="font">
<font>
<weight>75</weight>
<italic>true</italic>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Currently PVH VMs don't support PCI passthrough. Select another virtualization mode if you want to add PCI devices</string>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
</layout> </layout>