Added gui for booting VM from CDROM/block device.
Available via command line (qubes-vm-boot-from-device) and from a button in VM Settings/Advanced.
This commit is contained in:
parent
0e5feeac0d
commit
2ac9b1d182
130
qubesmanager/bootfromdevice.py
Normal file
130
qubesmanager/bootfromdevice.py
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
#
|
||||||
|
# The Qubes OS Project, http://www.qubes-os.org
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
from . import utils
|
||||||
|
from .firewall import *
|
||||||
|
from .ui_bootfromdevice import *
|
||||||
|
import qubesadmin.tools.qvm_start as qvm_start
|
||||||
|
|
||||||
|
|
||||||
|
class VMBootFromDeviceWindow(Ui_BootDialog, QDialog):
|
||||||
|
def __init__(self, vm, qapp, parent=None):
|
||||||
|
super(VMBootFromDeviceWindow, self).__init__(parent)
|
||||||
|
|
||||||
|
self.vm = vm
|
||||||
|
self.qapp = qapp
|
||||||
|
|
||||||
|
self.setupUi(self)
|
||||||
|
self.setWindowTitle(self.tr("Boot {vm} from device").format(vm=self.vm.name))
|
||||||
|
|
||||||
|
self.connect(self.buttonBox, SIGNAL("accepted()"), self.save_and_apply)
|
||||||
|
self.connect(self.buttonBox, SIGNAL("rejected()"), self.reject)
|
||||||
|
|
||||||
|
# populate buttons and such
|
||||||
|
self.__init_buttons__()
|
||||||
|
|
||||||
|
|
||||||
|
def reject(self):
|
||||||
|
self.done(0)
|
||||||
|
|
||||||
|
def save_and_apply(self):
|
||||||
|
if self.blockDeviceRadioButton.isChecked():
|
||||||
|
cdrom_location = self.blockDeviceComboBox.currentText()
|
||||||
|
elif self.fileRadioButton.isChecked():
|
||||||
|
cdrom_location = self.vm_list[self.fileVM.currentIndex()] + ":" + self.pathText.text()
|
||||||
|
else:
|
||||||
|
QMessageBox.warning(None,
|
||||||
|
self.tr(
|
||||||
|
"ERROR!"),
|
||||||
|
self.tr("No file or block device selected; please select one."))
|
||||||
|
return
|
||||||
|
|
||||||
|
qvm_start.main(['--cdrom', cdrom_location, self.vm.name])
|
||||||
|
|
||||||
|
def __init_buttons__(self):
|
||||||
|
self.fileVM.setEnabled(False)
|
||||||
|
self.selectFileButton.setEnabled(False)
|
||||||
|
self.blockDeviceComboBox.setEnabled(False)
|
||||||
|
|
||||||
|
self.blockDeviceRadioButton.clicked.connect(self.radio_button_clicked)
|
||||||
|
self.fileRadioButton.clicked.connect(self.radio_button_clicked)
|
||||||
|
self.selectFileButton.clicked.connect(self.select_file_dialog)
|
||||||
|
|
||||||
|
self.vm_list, self.vm_idx = utils.prepare_vm_choice(
|
||||||
|
self.fileVM,
|
||||||
|
self.vm, None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
allow_default=False, allow_none=False)
|
||||||
|
|
||||||
|
self.block_list, self.block_idx = utils.prepare_choice(
|
||||||
|
self.blockDeviceComboBox,
|
||||||
|
self.vm,
|
||||||
|
None,
|
||||||
|
[device for domain in self.vm.app.domains
|
||||||
|
for device in domain.devices["block"]],
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
allow_default=False, allow_none=False
|
||||||
|
)
|
||||||
|
|
||||||
|
def radio_button_clicked(self):
|
||||||
|
self.blockDeviceComboBox.setEnabled(self.blockDeviceRadioButton.isChecked())
|
||||||
|
self.fileVM.setEnabled(self.fileRadioButton.isChecked())
|
||||||
|
self.selectFileButton.setEnabled(self.fileRadioButton.isChecked())
|
||||||
|
self.pathText.setEnabled(self.fileRadioButton.isChecked())
|
||||||
|
|
||||||
|
def select_file_dialog(self):
|
||||||
|
backend_vm = self.vm_list[self.fileVM.currentIndex()]
|
||||||
|
|
||||||
|
try:
|
||||||
|
new_path = utils.get_path_from_vm(backend_vm, "qubes.SelectFile")
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
new_path = None
|
||||||
|
|
||||||
|
if new_path:
|
||||||
|
self.pathText.setText(new_path)
|
||||||
|
|
||||||
|
|
||||||
|
parser = qubesadmin.tools.QubesArgumentParser(vmname_nargs=1)
|
||||||
|
|
||||||
|
def main(args=None):
|
||||||
|
global bootfromdevice_window
|
||||||
|
|
||||||
|
args = parser.parse_args(args)
|
||||||
|
vm = args.domains.pop()
|
||||||
|
|
||||||
|
qapp = QApplication(sys.argv)
|
||||||
|
qapp.setOrganizationName('Invisible Things Lab')
|
||||||
|
qapp.setOrganizationDomain("https://www.qubes-os.org/")
|
||||||
|
qapp.setApplicationName("Qubes VM Settings")
|
||||||
|
|
||||||
|
# if not utils.is_debug(): #FIXME
|
||||||
|
# sys.excepthook = handle_exception
|
||||||
|
|
||||||
|
bootfromdevice_window = VMBootFromDeviceWindow(vm, qapp)
|
||||||
|
bootfromdevice_window.show()
|
||||||
|
|
||||||
|
qapp.exec_()
|
||||||
|
qapp.exit()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
@ -46,6 +46,7 @@ from .backup_utils import get_path_for_vm
|
|||||||
from .firewall import *
|
from .firewall import *
|
||||||
|
|
||||||
from .ui_settingsdlg import *
|
from .ui_settingsdlg import *
|
||||||
|
from .bootfromdevice import main as bootfromdevice
|
||||||
|
|
||||||
class VMSettingsWindow(Ui_SettingsDialog, QDialog):
|
class VMSettingsWindow(Ui_SettingsDialog, QDialog):
|
||||||
tabs_indices = collections.OrderedDict((
|
tabs_indices = collections.OrderedDict((
|
||||||
@ -91,6 +92,7 @@ class VMSettingsWindow(Ui_SettingsDialog, QDialog):
|
|||||||
self.connect(self.init_mem, SIGNAL("editingFinished()"), self.check_mem_changes)
|
self.connect(self.init_mem, SIGNAL("editingFinished()"), self.check_mem_changes)
|
||||||
self.connect(self.max_mem_size, SIGNAL("editingFinished()"), self.check_mem_changes)
|
self.connect(self.max_mem_size, SIGNAL("editingFinished()"), self.check_mem_changes)
|
||||||
self.drive_path_button.clicked.connect(self.drive_path_button_pressed)
|
self.drive_path_button.clicked.connect(self.drive_path_button_pressed)
|
||||||
|
self.bootFromDeviceButton.clicked.connect(self.boot_from_cdrom_button_pressed)
|
||||||
|
|
||||||
###### firewall tab
|
###### firewall tab
|
||||||
if self.tabWidget.isTabEnabled(self.tabs_indices['firewall']):
|
if self.tabWidget.isTabEnabled(self.tabs_indices['firewall']):
|
||||||
@ -454,22 +456,6 @@ class VMSettingsWindow(Ui_SettingsDialog, QDialog):
|
|||||||
self.vm.features.get('services.meminfo-writer', True))
|
self.vm.features.get('services.meminfo-writer', True))
|
||||||
self.max_mem_size.setEnabled(self.include_in_balancing.isChecked())
|
self.max_mem_size.setEnabled(self.include_in_balancing.isChecked())
|
||||||
|
|
||||||
# try:
|
|
||||||
# self.root_img_path.setText('{volume.pool}:{volume.vid}'.format(
|
|
||||||
# volume=self.vm.volumes['root']))
|
|
||||||
# except AttributeError:
|
|
||||||
# self.root_img_path.setText("n/a")
|
|
||||||
# try:
|
|
||||||
# self.volatile_img_path.setText('{volume.pool}:{volume.vid}'.format(
|
|
||||||
# volume=self.vm.volumes['volatile']))
|
|
||||||
# except AttributeError:
|
|
||||||
# self.volatile_img_path.setText('n/a')
|
|
||||||
# self.private_img_path.setText('{volume.pool}:{volume.vid}'.format(
|
|
||||||
# volume=self.vm.volumes['private']))
|
|
||||||
|
|
||||||
|
|
||||||
#kernel
|
|
||||||
|
|
||||||
#in case VM is HVM
|
#in case VM is HVM
|
||||||
if hasattr(self.vm, "kernel"):
|
if hasattr(self.vm, "kernel"):
|
||||||
self.kernel_groupbox.setVisible(True)
|
self.kernel_groupbox.setVisible(True)
|
||||||
@ -582,6 +568,10 @@ class VMSettingsWindow(Ui_SettingsDialog, QDialog):
|
|||||||
|
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
|
def boot_from_cdrom_button_pressed(self):
|
||||||
|
self.save_and_apply()
|
||||||
|
subprocess.check_call(['qubes-vm-boot-from-device', self.vm.name])
|
||||||
|
|
||||||
def drive_path_button_pressed(self):
|
def drive_path_button_pressed(self):
|
||||||
if str(self.drive_domain.currentText()) in ["dom0", "dom0 (current)"]:
|
if str(self.drive_domain.currentText()) in ["dom0", "dom0 (current)"]:
|
||||||
file_dialog = QFileDialog()
|
file_dialog = QFileDialog()
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
import functools
|
import functools
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import qubesadmin
|
import qubesadmin
|
||||||
|
|
||||||
from PyQt4.QtGui import QIcon
|
from PyQt4.QtGui import QIcon
|
||||||
@ -135,3 +135,31 @@ def debug(*args, **kwargs):
|
|||||||
if not is_debug():
|
if not is_debug():
|
||||||
return
|
return
|
||||||
print(*args, **kwargs)
|
print(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def get_path_from_vm(vm, service_name):
|
||||||
|
"""
|
||||||
|
Displays a file/directory selection window for the given VM.
|
||||||
|
|
||||||
|
:param vm: vm from which to select path
|
||||||
|
:param service_name: qubes.SelectFile or qubes.SelectDirectory
|
||||||
|
:return: path to file, checked for validity
|
||||||
|
"""
|
||||||
|
|
||||||
|
path_re = re.compile(r"[a-zA-Z0-9/:.,_+=() -]*")
|
||||||
|
path_max_len = 512
|
||||||
|
|
||||||
|
if not vm:
|
||||||
|
return None
|
||||||
|
stdout, stderr = vm.run_service_for_stdio(service_name)
|
||||||
|
|
||||||
|
untrusted_path = stdout.decode(encoding='ascii')[:path_max_len]
|
||||||
|
|
||||||
|
if len(untrusted_path) == 0:
|
||||||
|
return None
|
||||||
|
if path_re.match(untrusted_path):
|
||||||
|
assert '../' not in untrusted_path
|
||||||
|
assert '\0' not in untrusted_path
|
||||||
|
return untrusted_path.strip()
|
||||||
|
else:
|
||||||
|
raise ValueError('Unexpected characters in path.')
|
||||||
|
@ -61,6 +61,7 @@ rm -rf $RPM_BUILD_ROOT
|
|||||||
/usr/bin/qubes-global-settings
|
/usr/bin/qubes-global-settings
|
||||||
/usr/bin/qubes-vm-settings
|
/usr/bin/qubes-vm-settings
|
||||||
/usr/bin/qubes-vm-create
|
/usr/bin/qubes-vm-create
|
||||||
|
/usr/bin/qubes-vm-boot-from-device
|
||||||
/usr/libexec/qubes-manager/mount_for_backup.sh
|
/usr/libexec/qubes-manager/mount_for_backup.sh
|
||||||
/usr/libexec/qubes-manager/qvm_about.sh
|
/usr/libexec/qubes-manager/qvm_about.sh
|
||||||
|
|
||||||
@ -85,10 +86,12 @@ rm -rf $RPM_BUILD_ROOT
|
|||||||
%{python3_sitelib}/qubesmanager/create_new_vm.py
|
%{python3_sitelib}/qubesmanager/create_new_vm.py
|
||||||
%{python3_sitelib}/qubesmanager/thread_monitor.py
|
%{python3_sitelib}/qubesmanager/thread_monitor.py
|
||||||
%{python3_sitelib}/qubesmanager/utils.py
|
%{python3_sitelib}/qubesmanager/utils.py
|
||||||
|
%{python3_sitelib}/qubesmanager/bootfromdevice.py
|
||||||
|
|
||||||
%{python3_sitelib}/qubesmanager/resources_rc.py
|
%{python3_sitelib}/qubesmanager/resources_rc.py
|
||||||
|
|
||||||
%{python3_sitelib}/qubesmanager/ui_backupdlg.py
|
%{python3_sitelib}/qubesmanager/ui_backupdlg.py
|
||||||
|
%{python3_sitelib}/qubesmanager/ui_bootfromdevice.py
|
||||||
%{python3_sitelib}/qubesmanager/ui_globalsettingsdlg.py
|
%{python3_sitelib}/qubesmanager/ui_globalsettingsdlg.py
|
||||||
%{python3_sitelib}/qubesmanager/ui_multiselectwidget.py
|
%{python3_sitelib}/qubesmanager/ui_multiselectwidget.py
|
||||||
%{python3_sitelib}/qubesmanager/ui_newappvmdlg.py
|
%{python3_sitelib}/qubesmanager/ui_newappvmdlg.py
|
||||||
|
1
setup.py
1
setup.py
@ -21,5 +21,6 @@ if __name__ == '__main__':
|
|||||||
'qubes-global-settings = qubesmanager.global_settings:main',
|
'qubes-global-settings = qubesmanager.global_settings:main',
|
||||||
'qubes-vm-settings = qubesmanager.settings:main',
|
'qubes-vm-settings = qubesmanager.settings:main',
|
||||||
'qubes-vm-create = qubesmanager.create_new_vm:main',
|
'qubes-vm-create = qubesmanager.create_new_vm:main',
|
||||||
|
'qubes-vm-boot-from-device = qubesmanager.bootfromdevice:main'
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
117
ui/bootfromdevice.ui
Normal file
117
ui/bootfromdevice.ui
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>BootDialog</class>
|
||||||
|
<widget class="QDialog" name="BootDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>600</width>
|
||||||
|
<height>170</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>400</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Boot from device</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Boot qube from device</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>30</y>
|
||||||
|
<width>581</width>
|
||||||
|
<height>72</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
|
<item row="0" column="0" colspan="2">
|
||||||
|
<widget class="QRadioButton" name="blockDeviceRadioButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>from existing block device</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QRadioButton" name="fileRadioButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>from file in qube</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QComboBox" name="fileVM">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>150</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="2">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="pathText"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="selectFileButton">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="2">
|
||||||
|
<widget class="QComboBox" name="blockDeviceComboBox">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
@ -29,7 +29,7 @@
|
|||||||
<locale language="English" country="UnitedStates"/>
|
<locale language="English" country="UnitedStates"/>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>0</number>
|
<number>1</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="basic_tab">
|
<widget class="QWidget" name="basic_tab">
|
||||||
<property name="locale">
|
<property name="locale">
|
||||||
@ -383,6 +383,99 @@
|
|||||||
<string>Advanced</string>
|
<string>Advanced</string>
|
||||||
</attribute>
|
</attribute>
|
||||||
<layout class="QGridLayout" name="gridLayout_9">
|
<layout class="QGridLayout" name="gridLayout_9">
|
||||||
|
<item row="0" column="1" rowspan="2" colspan="2">
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SetDefaultConstraint</enum>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="kernel_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>Kernel</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QFormLayout" name="formLayout_9">
|
||||||
|
<property name="fieldGrowthPolicy">
|
||||||
|
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||||
|
</property>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label_19">
|
||||||
|
<property name="text">
|
||||||
|
<string>Kernel:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>kernel</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QComboBox" name="kernel"/>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_20">
|
||||||
|
<property name="text">
|
||||||
|
<string>Kernel opts:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLabel" name="kernel_opts">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<weight>50</weight>
|
||||||
|
<bold>false</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>[]</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QGroupBox" name="other_groupbox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Other</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QFormLayout" name="formLayout_2">
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_26">
|
||||||
|
<property name="text">
|
||||||
|
<string>Default DispVM:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>default_dispvm</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QComboBox" name="default_dispvm"/>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0" colspan="2">
|
||||||
|
<widget class="QPushButton" name="bootFromDeviceButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Boot qube from CDROM</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="0" column="0" rowspan="2">
|
<item row="0" column="0" rowspan="2">
|
||||||
<widget class="QGroupBox" name="groupBox_2">
|
<widget class="QGroupBox" name="groupBox_2">
|
||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
@ -942,11 +1035,6 @@
|
|||||||
<tabstop>vcpus</tabstop>
|
<tabstop>vcpus</tabstop>
|
||||||
<tabstop>include_in_balancing</tabstop>
|
<tabstop>include_in_balancing</tabstop>
|
||||||
<tabstop>kernel</tabstop>
|
<tabstop>kernel</tabstop>
|
||||||
<tabstop>drive_groupbox</tabstop>
|
|
||||||
<tabstop>drive_type</tabstop>
|
|
||||||
<tabstop>drive_domain</tabstop>
|
|
||||||
<tabstop>drive_path</tabstop>
|
|
||||||
<tabstop>drive_path_button</tabstop>
|
|
||||||
<tabstop>policyAllowRadioButton</tabstop>
|
<tabstop>policyAllowRadioButton</tabstop>
|
||||||
<tabstop>policyDenyRadioButton</tabstop>
|
<tabstop>policyDenyRadioButton</tabstop>
|
||||||
<tabstop>icmpCheckBox</tabstop>
|
<tabstop>icmpCheckBox</tabstop>
|
||||||
|
Loading…
Reference in New Issue
Block a user