Move all <os> bits to OSXML object, proxy through Installer

We want to remove all XML altering from the Installer, this is part one.
This commit is contained in:
Cole Robinson 2013-07-16 20:39:24 -04:00
parent 07215853b3
commit c0bdd24a55
4 changed files with 149 additions and 143 deletions

View File

@ -307,7 +307,7 @@ class DistroInstaller(Installer.Installer):
self._tmpfiles.append(initrdfn)
_perform_initrd_injections(initrdfn,
self._initrd_injections,
self.initrd_injections,
self.scratchdir)
kernelfn, initrdfn, tmpvols = _upload_media(

View File

@ -178,6 +178,7 @@ class Guest(XMLBuilder):
self._features = None
self._replace = None
self._emulator = None
self._type = None
self._os_type = None
self._os_variant = None
@ -202,6 +203,8 @@ class Guest(XMLBuilder):
self.installer = virtinst.DistroInstaller(conn)
self._type = "xen"
# Need to do this after all parameter init
self._features = DomainFeatures(self.conn)
self._clock = Clock(self.conn)
@ -632,7 +635,6 @@ class Guest(XMLBuilder):
self.add_device(dev)
def _get_device_xml(self, devs, install=True):
def do_remove_media(d):
# Keep cdrom around, but with no media attached,
# But only if we are a distro that doesn't have a multi

View File

@ -24,10 +24,10 @@ import platform
import logging
import copy
from virtinst import util
import virtinst
from virtinst import osxml
from virtinst import util
from virtinst.xmlbuilder import XMLBuilder, XMLProperty
from virtinst.Boot import Boot
XEN_SCRATCH = "/var/lib/xen"
LIBVIRT_SCRATCH = "/var/lib/libvirt/boot"
@ -64,17 +64,12 @@ class Installer(XMLBuilder):
def __init__(self, conn, parsexml=None, parsexmlnode=None):
XMLBuilder.__init__(self, conn, parsexml, parsexmlnode)
self._type = None
self._location = None
self._initrd_injections = []
self._cdrom = False
self._os_type = None
self._scratchdir = None
self._arch = None
self._machine = None
self._loader = None
self._init = None
self.bootconfig = Boot(self.conn, parsexml, parsexmlnode)
self.initrd_injections = []
self.bootconfig = osxml.OSXML(self.conn, parsexml, parsexmlnode)
self._install_kernel = None
self._install_initrd = None
@ -86,69 +81,29 @@ class Installer(XMLBuilder):
self._tmpfiles = []
self._tmpvols = []
if self._is_parse():
return
self._type = "xen"
self._arch = self.conn.caps.host.arch
self._os_type = "xen"
#####################
# XML related props #
#####################
# Hypervisor name (qemu, kvm, xen, lxc, etc.)
def get_type(self):
return self._type
def set_type(self, val):
self._type = val
type = XMLProperty(get_type, set_type,
xpath="./@type")
# Virtualization type ('xen' == xen paravirt, or 'hvm)
def get_os_type(self):
return self._os_type
def set_os_type(self, val):
# Older libvirt back compat: if user specifies 'linux', convert
# internally to newer equivalent value 'xen'
if val == "linux":
val = "xen"
# XXX: Need to validate this: have some whitelist based on caps?
self._os_type = val
os_type = XMLProperty(get_os_type, set_os_type,
xpath="./os/type")
def get_arch(self):
return self._arch
def set_arch(self, val):
# XXX: Sanitize to a consisten value (i368 -> i686)
# XXX: Validate against caps
self._arch = val
arch = XMLProperty(get_arch, set_arch,
xpath="./os/type/@arch")
def _get_machine(self):
return self._machine
def _set_type(self, val):
self.bootconfig.type = val
type = property(lambda s: s.bootconfig.type, _set_type)
def _set_os_type(self, val):
self.bootconfig.os_type = val
os_type = property(lambda s: s.bootconfig.os_type, _set_os_type)
def _set_machine(self, val):
self._machine = val
machine = XMLProperty(_get_machine, _set_machine,
xpath="./os/type/@machine")
def _get_loader(self):
return self._loader
self.bootconfig.machine = val
machine = property(lambda s: s.bootconfig.machine, _set_machine)
def _set_arch(self, val):
self.bootconfig.arch = val
arch = property(lambda s: s.bootconfig.arch, _set_arch)
def _set_loader(self, val):
self._loader = val
loader = XMLProperty(_get_loader, _set_loader,
xpath="./os/loader")
def _get_init(self):
return self._init
self.bootconfig.loader = val
loader = property(lambda s: s.bootconfig.loader, _set_loader)
def _set_init(self, val):
self._init = val
init = XMLProperty(_get_init, _set_init,
xpath="./os/init")
self.bootconfig.init = val
init = property(lambda s: s.bootconfig.init, _set_init)
######################
@ -179,12 +134,6 @@ class Installer(XMLBuilder):
self._location = self._validate_location(val)
location = property(get_location, set_location)
def get_initrd_injections(self):
return self._initrd_injections
def set_initrd_injections(self, val):
self._initrd_injections = val
initrd_injections = property(get_initrd_injections, set_initrd_injections)
def get_extra_args(self):
return self._install_args
def set_extra_args(self, val):
@ -241,15 +190,6 @@ class Installer(XMLBuilder):
return bootorder
def _get_default_init(self, guest):
if not self.is_container():
return
for fs in guest.get_devices("filesystem"):
if fs.target == "/":
return "/sbin/init"
return "/bin/sh"
def _make_cdrom_dev(self, path):
dev = virtinst.VirtualDisk(self.conn)
dev.path = path
@ -258,55 +198,6 @@ class Installer(XMLBuilder):
dev.validate()
return dev
def _get_osblob_helper(self, guest, isinstall, bootconfig):
arch = self.arch
machine = self.machine
hvtype = self.type
loader = self.loader
os_type = self.os_type
init = self.init or self._get_default_init(guest)
hvxen = (hvtype == "xen")
if not loader and self.is_hvm() and hvxen:
loader = "/usr/lib/xen/boot/hvmloader"
# Use older libvirt 'linux' value for back compat
if os_type == "xen" and hvxen:
os_type = "linux"
if (not isinstall and
self.is_xenpv() and
not self.bootconfig.kernel):
# This really should be provided by capabilites xml
return "<bootloader>/usr/bin/pygrub</bootloader>"
osblob = "<os>"
typexml = " <type"
if arch:
typexml += " arch='%s'" % arch
if machine:
typexml += " machine='%s'" % machine
typexml += ">%s</type>" % os_type
osblob = util.xml_append(osblob, typexml)
if init:
osblob = util.xml_append(osblob,
" <init>%s</init>" %
util.xml_escape(init))
if loader:
osblob = util.xml_append(osblob,
" <loader>%s</loader>" %
util.xml_escape(loader))
if not self.is_container():
osblob = util.xml_append(osblob, bootconfig.get_xml_config())
osblob = util.xml_append(osblob, " </os>")
return osblob
def _get_xml_config(self, guest, isinstall):
"""
Generate the portion of the guest xml that determines boot devices
@ -338,7 +229,8 @@ class Installer(XMLBuilder):
if self._install_args:
bootconfig.kernel_args = self._install_args
return self._get_osblob_helper(guest, isinstall, bootconfig)
return self.bootconfig._get_osblob_helper(guest, isinstall,
bootconfig, self.bootconfig)
##########################
@ -368,12 +260,9 @@ class Installer(XMLBuilder):
"""
return False
def is_hvm(self):
return self.os_type == "hvm"
def is_xenpv(self):
return self.os_type in ["xen", "linux"]
def is_container(self):
return self.os_type == "exe"
is_hvm = lambda s: s.bootconfig.is_hvm()
is_xenpv = lambda s: s.bootconfig.is_xenpv()
is_container = lambda s: s.bootconfig.is_container()
def has_install_phase(self):
"""
@ -430,10 +319,6 @@ class Installer(XMLBuilder):
to pass it. This is a convenience method to save the API user from
having to enter all these known details twice.
"""
if not self.conn:
raise ValueError(_("A connection must be specified."))
guest, domain = self.conn.caps.guest_lookup(os_type=self.os_type,
typ=self.type,
arch=self.arch,

View File

@ -21,7 +21,7 @@ from virtinst import util
from virtinst.xmlbuilder import XMLBuilder, XMLProperty
class Boot(XMLBuilder):
class OSXML(XMLBuilder):
"""
Class for generating boot device related XML
"""
@ -43,6 +43,26 @@ class Boot(XMLBuilder):
self._kernel = None
self._initrd = None
self._kernel_args = None
self._type = None
self._arch = None
self._machine = None
self._loader = None
self._init = None
self._os_type = None
if self._is_parse():
return
self._arch = self.conn.caps.host.arch
self._type = "xen"
self._os_type = "xen"
def is_hvm(self):
return self.os_type == "hvm"
def is_xenpv(self):
return self.os_type in ["xen", "linux"]
def is_container(self):
return self.os_type == "exe"
def _get_enable_bootmenu(self):
return self._enable_bootmenu
@ -80,6 +100,55 @@ class Boot(XMLBuilder):
kernel_args = XMLProperty(_get_kernel_args, _set_kernel_args,
xpath="./os/cmdline")
def _get_default_init(self, guest):
if not self.is_container():
return
for fs in guest.get_devices("filesystem"):
if fs.target == "/":
return "/sbin/init"
return "/bin/sh"
def _get_init(self):
return self._init
def _set_init(self, val):
self._init = val
init = XMLProperty(_get_init, _set_init,
xpath="./os/init")
def _get_loader(self):
return self._loader
def _set_loader(self, val):
self._loader = val
loader = XMLProperty(_get_loader, _set_loader,
xpath="./os/loader")
def get_arch(self):
return self._arch
def set_arch(self, val):
self._arch = val
arch = XMLProperty(get_arch, set_arch,
xpath="./os/type/@arch")
def _get_machine(self):
return self._machine
def _set_machine(self, val):
self._machine = val
machine = XMLProperty(_get_machine, _set_machine,
xpath="./os/type/@machine")
def get_ostype(self):
return self._os_type
def set_ostype(self, val):
self._os_type = val
os_type = XMLProperty(get_ostype, set_ostype, xpath="./os/type")
def get_type(self):
return self._type
def set_type(self, val):
self._type = val
type = XMLProperty(get_type, set_type, xpath="./@type")
def _get_xml_config(self):
xml = ""
@ -103,3 +172,53 @@ class Boot(XMLBuilder):
" <bootmenu enable='%s'/>" % val)
return xml
def _get_osblob_helper(self, guest, isinstall,
bootconfig, endbootconfig):
arch = self.arch
machine = self.machine
hvtype = self.type
loader = self.loader
os_type = self.os_type
init = self.init or self._get_default_init(guest)
hvxen = (hvtype == "xen")
if not loader and self.is_hvm() and hvxen:
loader = "/usr/lib/xen/boot/hvmloader"
# Use older libvirt 'linux' value for back compat
if os_type == "xen" and hvxen:
os_type = "linux"
if (not isinstall and
self.is_xenpv() and
not endbootconfig.kernel):
# This really should be provided by capabilites xml
return "<bootloader>/usr/bin/pygrub</bootloader>"
osblob = "<os>"
typexml = " <type"
if arch:
typexml += " arch='%s'" % arch
if machine:
typexml += " machine='%s'" % machine
typexml += ">%s</type>" % os_type
osblob = util.xml_append(osblob, typexml)
if init:
osblob = util.xml_append(osblob,
" <init>%s</init>" %
util.xml_escape(init))
if loader:
osblob = util.xml_append(osblob,
" <loader>%s</loader>" %
util.xml_escape(loader))
if not self.is_container():
osblob = util.xml_append(osblob, bootconfig.get_xml_config())
osblob = util.xml_append(osblob, " </os>")
return osblob