create: Add kernel/initrd install option for arm

Basically just show kernel/initrd options for the 'import' install
method on non-x86.
This commit is contained in:
Cole Robinson 2013-10-02 11:56:51 -04:00
parent 89ba152f00
commit d6f96f72d5
3 changed files with 421 additions and 82 deletions

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.16.0 on Tue Oct 1 17:54:45 2013 -->
<!-- Generated with glade 3.16.0 on Wed Oct 2 10:09:09 2013 -->
<interface>
<!-- interface-requires gtk+ 3.0 -->
<object class="GtkAdjustment" id="adjustment1">
@ -293,10 +293,11 @@
<property name="spacing">3</property>
<child>
<object class="GtkRadioButton" id="method-container-app">
<property name="label" translatable="yes">Application container</property>
<property name="label" translatable="yes">_Application container</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
@ -310,10 +311,11 @@
</child>
<child>
<object class="GtkRadioButton" id="method-container-os">
<property name="label" translatable="yes">Operating system container</property>
<property name="label" translatable="yes">O_perating system container</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
<property name="draw_indicator">True</property>
<property name="group">method-container-app</property>
@ -497,7 +499,9 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Machine Type:</property>
<property name="label" translatable="yes">_Machine Type:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">config-machine</property>
</object>
<packing>
<property name="left_attach">0</property>
@ -510,6 +514,7 @@
<object class="GtkComboBox" id="config-machine">
<property name="visible">True</property>
<property name="can_focus">False</property>
<signal name="changed" handler="on_config_machine_changed" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
@ -616,7 +621,7 @@ bar</property>
<object class="GtkVBox" id="vbox7">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">10</property>
<property name="spacing">24</property>
<child>
<object class="GtkNotebook" id="install-method-pages">
<property name="visible">True</property>
@ -1046,16 +1051,75 @@ User shouldn't see this.</property>
</packing>
</child>
<child>
<object class="GtkVBox" id="vbox20">
<object class="GtkBox" id="box2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<property name="orientation">vertical</property>
<property name="spacing">24</property>
<child>
<object class="GtkLabel" id="label41">
<object class="GtkVBox" id="vbox20">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Provide the existing storage path:</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="label41">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Provide the existing storage path:</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="alignment22">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="left_padding">15</property>
<child>
<object class="GtkHBox" id="hbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkEntry" id="install-import-entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="install-import-browse">
<property name="label" translatable="yes">B_rowse...</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_underline">True</property>
<signal name="clicked" handler="on_install_import_browse_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
@ -1064,43 +1128,245 @@ User shouldn't see this.</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="alignment22">
<object class="GtkBox" id="config-kernel-box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="left_padding">12</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkHBox" id="hbox1">
<object class="GtkLabel" id="label11">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Direct kernel boot:</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="alignment19">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="left_padding">15</property>
<child>
<object class="GtkEntry" id="install-import-entry">
<object class="GtkGrid" id="grid1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
<property name="can_focus">False</property>
<property name="row_spacing">6</property>
<property name="column_spacing">6</property>
<child>
<object class="GtkLabel" id="label38">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">_Kernel path:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">config-kernel</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label48">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">_Initrd path:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">config-initrd</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label49">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">_DTB path:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">config-dtb</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="config-kernel">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="config-initrd">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="config-dtb">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="config-kernel-browse">
<property name="label" translatable="yes">Br_owse...</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_underline">True</property>
<signal name="clicked" handler="on_config_kernel_browse_clicked" swapped="no"/>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="config-initrd-browse">
<property name="label" translatable="yes">Bro_wse...</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_underline">True</property>
<signal name="clicked" handler="on_config_initrd_browse_clicked" swapped="no"/>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="config-dtb-browse">
<property name="label" translatable="yes">Brow_se...</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_underline">True</property>
<signal name="clicked" handler="on_config_dtb_browse_clicked" swapped="no"/>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkBox" id="config-dtb-warn-virtio">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkImage" id="image6">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-dialog-warning</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label50">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">&lt;span size='small'&gt;Specifying a DTB allows use of virtio for improved performance&lt;/span&gt;</property>
<property name="use_markup">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="width">3</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label51">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Kerne_l args:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">config-kernel-args</property>
<property name="ellipsize">end</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">4</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="config-kernel-args">
<property name="visible">True</property>
<property name="can_focus">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">4</property>
<property name="width">2</property>
<property name="height">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="install-import-browse">
<property name="label" translatable="yes">B_rowse...</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_underline">True</property>
<signal name="clicked" handler="on_install_import_browse_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>

View File

@ -112,6 +112,7 @@ class vmmCreate(vmmGObjectUI):
"on_create_vm_name_activate": self.forward,
"on_create_conn_changed": self.conn_changed,
"on_method_changed": self.method_changed,
"on_config_machine_changed": self.machine_changed,
"on_install_url_box_changed": self.url_box_changed,
"on_install_local_cdrom_toggled": self.toggle_local_cdrom,
@ -129,6 +130,10 @@ class vmmCreate(vmmGObjectUI):
"on_install_detect_os_box_show": self.detect_visibility_changed,
"on_install_detect_os_box_hide": self.detect_visibility_changed,
"on_config_kernel_browse_clicked": self.browse_kernel,
"on_config_initrd_browse_clicked": self.browse_initrd,
"on_config_dtb_browse_clicked": self.browse_dtb,
"on_enable_storage_toggled": self.toggle_enable_storage,
"on_config_storage_browse_clicked": self.browse_storage,
"on_config_storage_select_toggled": self.toggle_storage_select,
@ -364,6 +369,9 @@ class vmmCreate(vmmGObjectUI):
# Install import
self.widget("install-import-entry").set_text("")
self.widget("config-kernel").set_text("")
self.widget("config-initrd").set_text("")
self.widget("config-dtb").set_text("")
# Install container app
self.widget("install-app-entry").set_text("/bin/sh")
@ -391,7 +399,9 @@ class vmmCreate(vmmGObjectUI):
# Make sure window is a sane size
self.topwin.resize(1, 1)
def _change_install_options_from_arch(self):
def set_caps_state(self):
# State that is dependent on when capsguest changes
# Helper state
is_local = not self.conn.is_remote()
is_storage_capable = self.conn.is_storage_capable()
@ -401,6 +411,9 @@ class vmmCreate(vmmGObjectUI):
can_remote_url = self.conn.check_stream_support(
self.conn.SUPPORT_STREAM_UPLOAD)
installable_arch = (self.capsguest.arch in
["i686", "x86_64", "ppc64", "ia64"])
# Install Options
method_tree = self.widget("method-tree")
method_pxe = self.widget("method-pxe")
@ -408,9 +421,11 @@ class vmmCreate(vmmGObjectUI):
method_import = self.widget("method-import")
method_container_app = self.widget("method-container-app")
method_tree.set_sensitive(is_local or can_remote_url)
method_local.set_sensitive(not is_pv and can_storage)
method_pxe.set_sensitive(not is_pv)
method_tree.set_sensitive((is_local or can_remote_url) and
installable_arch)
method_local.set_sensitive(not is_pv and can_storage and
installable_arch)
method_pxe.set_sensitive(not is_pv and installable_arch)
method_import.set_sensitive(can_storage)
virt_methods = [method_local, method_tree, method_pxe, method_import]
@ -432,6 +447,13 @@ class vmmCreate(vmmGObjectUI):
pxe_tt = base % "PXE"
local_tt = base % "CDROM/ISO"
if not installable_arch:
msg = (_("Architecture '%s' is not installable") %
self.capsguest.arch)
tree_tt = msg
local_tt = msg
pxe_tt = msg
for w in virt_methods:
if w.get_sensitive():
w.set_active(True)
@ -453,6 +475,13 @@ class vmmCreate(vmmGObjectUI):
self.widget("virt-install-box").set_visible(not is_container)
self.widget("container-install-box").set_visible(is_container)
show_kernel = (self.capsguest.arch not in ["x86_64", "i686"])
show_dtb = ("arm" in self.capsguest.arch or
"microblaze" in self.capsguest.arch or
"ppc" in self.capsguest.arch)
self.widget("config-kernel-box").set_visible(show_kernel)
uihelpers.set_grid_row_visible(self.widget("config-dtb"), show_dtb)
def set_conn_state(self):
# Update all state that has some dependency on the current connection
self.conn.schedule_priority_tick(pollnet=True,
@ -508,9 +537,6 @@ class vmmCreate(vmmGObjectUI):
"are not loaded. Your virtual machines may perform poorly.")
self.startup_warning(error)
# Set install options
self._change_install_options_from_arch()
# Install local
iso_option = self.widget("install-local-iso")
cdrom_option = self.widget("install-local-cdrom")
@ -705,6 +731,8 @@ class vmmCreate(vmmGObjectUI):
uihelpers.set_grid_row_visible(lst, show)
if show:
lst.set_active(default)
else:
lst.emit("changed")
def populate_conn_list(self, urihint=None):
conn_list = self.widget("create-conn")
@ -856,7 +884,7 @@ class vmmCreate(vmmGObjectUI):
self.capsguest.arch,
self.capsdomain.hypervisor_type)
self.populate_machine()
self._change_install_options_from_arch()
self.set_caps_state()
def populate_summary(self):
distro, version, dlabel, vlabel = self.get_config_os_info()
@ -916,6 +944,13 @@ class vmmCreate(vmmGObjectUI):
def get_config_name(self):
return self.widget("create-vm-name").get_text()
def get_config_machine(self):
lst = self.widget("config-machine")
idx = lst.get_active()
if not lst.get_visible() or idx == -1:
return None
return lst.get_model()[idx][0]
def is_install_page(self):
notebook = self.widget("create-pages")
curpage = notebook.get_current_page()
@ -1082,6 +1117,14 @@ class vmmCreate(vmmGObjectUI):
ignore = src
self.set_page_num_text(0)
def machine_changed(self, ignore):
machine = self.get_config_machine()
show_dtb_virtio = (self.capsguest.arch == "armv7l" and
machine in ["vexpress-a9", "vexpress-15"])
print machine, show_dtb_virtio
uihelpers.set_grid_row_visible(
self.widget("config-dtb-warn-virtio"), show_dtb_virtio)
def netdev_changed(self, ignore):
self.check_network_selection()
@ -1240,31 +1283,25 @@ class vmmCreate(vmmGObjectUI):
else:
nodetect_label.show()
def browse_oscontainer(self, ignore1=None, ignore2=None):
def set_path(ignore, path):
self.widget("install-oscontainer-fs").set_text(path)
self._browse_file(set_path, is_media=False, is_dir=True)
def browse_app(self, ignore1=None, ignore2=None):
def set_path(ignore, path):
self.widget("install-app-entry").set_text(path)
self._browse_file(set_path, is_media=False)
def browse_import(self, ignore1=None, ignore2=None):
def set_path(ignore, path):
self.widget("install-import-entry").set_text(path)
self._browse_file(set_path, is_media=False)
def browse_iso(self, ignore1=None, ignore2=None):
def browse_oscontainer(self, ignore):
self._browse_file("install-oscontainer-fs", is_dir=True)
def browse_app(self, ignore):
self._browse_file("install-app-entry")
def browse_import(self, ignore):
self._browse_file("install-import-entry")
def browse_iso(self, ignore):
def set_path(ignore, path):
self.widget("install-local-box").get_child().set_text(path)
self._browse_file(set_path, is_media=True)
self._browse_file(None, cb=set_path, is_media=True)
self.widget("install-local-box").activate()
def browse_storage(self, ignore1):
def set_path(ignore, path):
self.widget("config-storage-entry").set_text(path)
self._browse_file(set_path, is_media=False)
def browse_storage(self, ignore):
self._browse_file("config-storage-entry")
def browse_kernel(self, ignore):
self._browse_file("config-kernel")
def browse_initrd(self, ignore):
self._browse_file("config-initrd")
def browse_dtb(self, ignore):
self._browse_file("config-dtb")
def toggle_enable_storage(self, src):
self.widget("config-storage-box").set_sensitive(src.get_active())
@ -1429,15 +1466,10 @@ class vmmCreate(vmmGObjectUI):
gdev.type = gtype
return gdev
def build_guest_stub(self):
return self.conn.caps.build_virtinst_guest(self.conn.get_backend(),
self.capsguest,
self.capsdomain)
def build_guest(self, installer):
guest = self.build_guest_stub()
guest.installer = installer
def build_guest(self):
guest = self.conn.caps.build_virtinst_guest(
self.conn.get_backend(), self.capsguest, self.capsdomain)
guest.os.machine = self.get_config_machine()
# Generate UUID (makes customize dialog happy)
try:
@ -1482,7 +1514,13 @@ class vmmCreate(vmmGObjectUI):
return
def validate_name_page(self):
self.build_guest_stub()
# We just set this here because it's needed soon after for distro
# detction. But the 'real' self.guest is created in validate_install,
# and it just uses build_guest, so don't ever add any other guest
# altering here.
self.guest = self.build_guest()
if not self.guest:
return False
return True
def _generate_default_name(self, distro, variant):
@ -1564,10 +1602,12 @@ class vmmCreate(vmmGObjectUI):
# Build the installer and Guest instance
try:
# Overwrite the guest
installer = instclass(self.conn.get_backend())
self.guest = self.build_guest(installer)
self.guest = self.build_guest()
if not self.guest:
return False
self.guest.installer = installer
except Exception, e:
return self.err.val_err(
_("Error setting installer parameters."), e)
@ -1608,6 +1648,31 @@ class vmmCreate(vmmGObjectUI):
except ValueError, e:
return self.err.val_err(_("Error setting OS information."), e)
# Setting kernel
if instmethod == INSTALL_PAGE_IMPORT:
kernel = self.widget("config-kernel").get_text() or None
kargs = self.widget("config-kernel-args").get_text() or None
initrd = self.widget("config-initrd").get_text() or None
dtb = self.widget("config-dtb").get_text() or None
if not self.widget("config-dtb").get_visible():
dtb = None
if not self.widget("config-kernel").get_visible():
kernel = None
initrd = None
kargs = None
self.guest.os.kernel = kernel
self.guest.os.initrd = initrd
self.guest.os.dtb = dtb
self.guest.os.kernel_args = kargs
require_kernel = ("arm" in self.capsguest.arch)
if require_kernel and not kernel:
return self.err.val_err(
_("A kernel is required for %s guests.") %
self.capsguest.arch)
try:
name = self._generate_default_name(distro, variant)
self.widget("create-vm-name").set_text(name)
@ -2069,9 +2134,8 @@ class vmmCreate(vmmGObjectUI):
try:
installer = virtinst.DistroInstaller(self.conn)
installer.location = media
guest = self.guest or self.build_guest_stub()
self.detectedDistro = installer.detect_distro(guest)
self.detectedDistro = installer.detect_distro(self.guest)
except:
logging.exception("Error detecting distro.")
self.detectedDistro = -1
@ -2086,7 +2150,7 @@ class vmmCreate(vmmGObjectUI):
ret = self.conn.rhel6_defaults(emu)
return ret
def _browse_file(self, callback, is_media=False, is_dir=False):
def _browse_file(self, cbwidget, cb=None, is_media=False, is_dir=False):
if is_media:
reason = self.config.CONFIG_DIR_ISO_MEDIA
elif is_dir:
@ -2094,6 +2158,12 @@ class vmmCreate(vmmGObjectUI):
else:
reason = self.config.CONFIG_DIR_IMAGE
if cb:
callback = cb
else:
def callback(ignore, text):
self.widget(cbwidget).set_text(text)
if self.storage_browser is None:
self.storage_browser = vmmStorageBrowser(self.conn)

View File

@ -215,7 +215,10 @@ class vmmStorageBrowser(vmmGObjectUI):
row = uihelpers.get_list_selection(self.widget("pool-list"))
if not row:
return
return self.conn.get_pool(row[0])
try:
return self.conn.get_pool(row[0])
except KeyError:
return None
def current_vol_row(self):
if not self.current_pool():