[et-mgmt-tools] [PATCH] Add support for Solaris PV

john.levon at sun.com john.levon at sun.com
Thu Dec 4 04:31:28 UTC 2008


# HG changeset patch
# User john.levon at sun.com
# Date 1228365031 28800
# Node ID 35baacfe79834400949ebdba69f952ed873ae442
# Parent  7dd32b4d7915937025f42c3519711db50e5a7ce3
Add support for Solaris PV

Solaris PV comes in two flavours: Nevada and OpenSolaris.  In order to
correctly build network installs for Nevada, we need to pass down guest
options into OSDistro.

os_type was horribly overloaded between the Installer and Guest classes,
meaning two different things ('solaris' or 'hvm'). Clean this up by
naming the latter 'virt_type'.

Signed-off-by: John Levon <john.levon at sun.com>

diff --git a/virt-install b/virt-install
--- a/virt-install
+++ b/virt-install
@@ -510,27 +510,27 @@ def main():
         fail(_("Can't do both --hvm and --paravirt"))
 
     if options.fullvirt:
-        os_type = "hvm"
+        virt_type = "hvm"
     elif options.paravirt:
-        os_type = "xen"
+        virt_type = "xen"
     else:
         # This should force capabilities to give us the most sensible default
-        os_type = None
-
-    logging.debug("Requesting virt method '%s'" % (os_type and os_type or \
+        virt_type = None
+
+    logging.debug("Requesting virt method '%s'" % (virt_type and virt_type or \
                                                   _("default")))
 
-    guest = capabilities.guestForOSType(type=os_type, arch=options.arch)
+    guest = capabilities.guestForVirtType(type=virt_type, arch=options.arch)
     if guest is None:
-        msg = _("Unsupported virtualization type '%s' " % (os_type and os_type
+        msg = _("Unsupported virtualization type '%s' " % (virt_type and virt_type
                                                            or _("default")))
         if options.arch:
             msg += _("for arch '%s'" % options.arch)
         fail(msg)
 
-    os_type = guest.os_type
-    logging.debug("Received virt method '%s'" % os_type)
-    if os_type == "hvm":
+    virt_type = guest.virt_type
+    logging.debug("Received virt method '%s'" % virt_type)
+    if virt_type == "hvm":
         hvm = True
     else:
         hvm = False
@@ -540,13 +540,13 @@ def main():
     logging.debug("Hypervisor type is '%s'" % htype)
 
     if options.livecd:
-        installer = virtinst.LiveCDInstaller(type = htype, os_type = os_type,
+        installer = virtinst.LiveCDInstaller(type = htype, virt_type = virt_type,
                                              conn = conn)
     elif options.pxe:
-        installer = virtinst.PXEInstaller(type = htype, os_type = os_type,
+        installer = virtinst.PXEInstaller(type = htype, virt_type = virt_type,
                                           conn = conn)
     else:
-        installer = virtinst.DistroInstaller(type = htype, os_type = os_type,
+        installer = virtinst.DistroInstaller(type = htype, virt_type = virt_type,
                                              conn = conn)
 
     if hvm:
diff --git a/virtinst/CapabilitiesParser.py b/virtinst/CapabilitiesParser.py
--- a/virtinst/CapabilitiesParser.py
+++ b/virtinst/CapabilitiesParser.py
@@ -121,7 +121,7 @@ class Guest(object):
 class Guest(object):
     def __init__(self, node = None):
         # e.g. "xen" or "hvm"
-        self.os_type = None
+        self.virt_type = None
         # e.g. "i686" or "x86_64"
         self.arch = None
 
@@ -135,8 +135,9 @@ class Guest(object):
     def parseXML(self, node):
         child = node.children
         while child:
+            # In the XML, os_type really means virt_type
             if child.name == "os_type":
-                self.os_type = child.content
+                self.virt_type = child.content
             elif child.name == "features":
                 self.features = CapabilityFeatures(child)
             elif child.name == "arch":
@@ -260,7 +261,7 @@ class Capabilities(object):
 
         self._fixBrokenEmulator()
 
-    def guestForOSType(self, type = None, arch = None):
+    def guestForVirtType(self, type = None, arch = None):
         if self.host is None:
             return None
 
@@ -270,7 +271,7 @@ class Capabilities(object):
             archs = [arch]
         for a in archs:
             for g in self.guests:
-                if (type is None or g.os_type == type) and \
+                if (type is None or g.virt_type == type) and \
                    (a is None or g.arch == a):
                     return g
 
@@ -283,7 +284,7 @@ class Capabilities(object):
 
         fixEmulator = None
         for g in self.guests:
-            if g.os_type != "hvm" or g.arch != "x86_64":
+            if g.virt_type != "hvm" or g.arch != "x86_64":
                 continue
             for d in g.domains:
                 if d.emulator.find("lib64") != -1:
@@ -293,7 +294,7 @@ class Capabilities(object):
             return
 
         for g in self.guests:
-            if g.os_type != "hvm" or g.arch != "i686":
+            if g.virt_type != "hvm" or g.arch != "i686":
                 continue
             for d in g.domains:
                 if d.emulator.find("lib64") == -1:
diff --git a/virtinst/DistroManager.py b/virtinst/DistroManager.py
--- a/virtinst/DistroManager.py
+++ b/virtinst/DistroManager.py
@@ -41,6 +41,8 @@ from OSDistro import DebianDistro
 from OSDistro import DebianDistro
 from OSDistro import UbuntuDistro
 from OSDistro import MandrivaDistro
+from OSDistro import SolarisDistro
+from OSDistro import OpenSolarisDistro
 from OSDistro import GenericDistro
 
 def _fetcherForURI(uri, scratchdir=None):
@@ -87,6 +89,11 @@ def _storeForDistro(fetcher, baseuri, ty
         stores.append(UbuntuDistro(baseuri, typ, scratchdir, arch))
     if distro == "mandriva" or distro is None:
         stores.append(MandrivaDistro(baseuri, typ, scratchdir, arch))
+    # XXX: this is really "nevada"
+    if distro == "solaris" or distro is None:
+        stores.append(SolarisDistro(baseuri, type, scratchdir))
+    if distro == "solaris" or distro is None:
+        stores.append(OpenSolarisDistro(baseuri, type, scratchdir))
 
     stores.append(GenericDistro(baseuri, typ, scratchdir, arch))
 
@@ -98,24 +105,6 @@ def _storeForDistro(fetcher, baseuri, ty
 
     raise ValueError, _("Could not find an installable distribution at '%s'" % baseuri) 
 
-
-# Method to fetch a kernel & initrd pair for a particular distro / HV type
-def acquireKernel(baseuri, progresscb, scratchdir="/var/tmp", type=None,
-                  distro=None, arch=None):
-    fetcher = _fetcherForURI(baseuri, scratchdir)
-
-    try:
-        fetcher.prepareLocation()
-    except ValueError, e:
-        raise ValueError, _("Invalid install location: ") + str(e)
-
-    try:
-        store = _storeForDistro(fetcher=fetcher, baseuri=baseuri, typ=type,
-                                progresscb=progresscb, distro=distro,
-                                scratchdir=scratchdir, arch=arch)
-        return store.acquireKernel(fetcher, progresscb)
-    finally:
-        fetcher.cleanupLocation()
 
 # Method to fetch a bootable ISO image for a particular distro / HV type
 def acquireBootDisk(baseuri, progresscb, scratchdir="/var/tmp", type=None,
@@ -137,9 +126,9 @@ def acquireBootDisk(baseuri, progresscb,
 
 class DistroInstaller(Guest.Installer):
     def __init__(self, type = "xen", location = None, boot = None,
-                 extraargs = None, os_type = None, conn = None):
+                 extraargs = None, virt_type = None, conn = None):
         Guest.Installer.__init__(self, type, location, boot, extraargs,
-                                 os_type, conn=conn)
+                                 virt_type, conn=conn)
 
         self.install = {
             "kernel" : "",
@@ -226,6 +215,27 @@ class DistroInstaller(Guest.Installer):
                                          readOnly=True,
                                          transient=True)
 
+    # Method to fetch a kernel & initrd pair for a particular distro / HV type
+    def _acquire_kernel(self, guest, progresscb, distro=None, arch=None):
+        fetcher = _fetcherForURI(self.location, self.scratchdir)
+
+        try:
+            fetcher.prepareLocation()
+        except ValueError, e:
+            raise ValueError, _("Invalid install location: ") + str(e)
+
+        try:
+            store = _storeForDistro(fetcher=fetcher, baseuri=self.location,
+                                    typ=self.virt_type, progresscb=progresscb,
+                                    distro=distro, scratchdir=self.scratchdir,
+                                    arch=arch)
+
+            os_type = store.os_type
+
+            return store.acquireKernel(guest, fetcher, progresscb), os_type
+        finally:
+            fetcher.cleanupLocation()
+
     def _prepare_kernel_and_initrd(self, guest, distro, meter):
         if self.boot is not None:
             # Got a local kernel/initrd already
@@ -239,26 +249,29 @@ class DistroInstaller(Guest.Installer):
             arch = os.uname()[4]
             if hasattr(guest, "arch"):
                 arch = guest.arch
-            (kernelfn, initrdfn, args) = acquireKernel(self.location,
-                                                       meter,
-                                                       scratchdir = self.scratchdir,
-                                                       type = self.os_type,
-                                                       distro = distro,
-                                                       arch=arch)
+
+            (kernelfn, initrdfn, args), os_type = \
+                self._acquire_kernel(guest, meter, distro = distro, arch = arch)
+
+            guest.os_type = os_type
             self.install["kernel"] = kernelfn
             self.install["initrd"] = initrdfn
-            if not self.extraargs is None:
-                self.install["extraargs"] = self.extraargs + " " + args
-            else:
-                self.install["extraargs"] = args
+            self.install["extraargs"] = args
 
             self._tmpfiles.append(kernelfn)
             self._tmpfiles.append(initrdfn)
 
         # If they're installing off a local file/device, we map it
-        # through to a virtual harddisk
-        if self.location is not None and self.location.startswith("/") and not os.path.isdir(self.location):
+        # through to a virtual CD or disk
+
+        if (self.location is not None and self.location.startswith("/")
+            and not os.path.isdir(self.location)):
+            device = Guest.VirtualDisk.DEVICE_DISK
+            if guest._lookup_osdict_key('pv_cdrom_install'):
+                device = Guest.VirtualDisk.DEVICE_CDROM
+
             self._install_disk = VirtualDisk(self.location,
+                                             device=device,
                                              readOnly=True,
                                              transient=True)
 
@@ -294,9 +307,9 @@ class DistroInstaller(Guest.Installer):
 
 class PXEInstaller(Guest.Installer):
     def __init__(self, type = "xen", location = None, boot = None,
-                 extraargs = None, os_type = None, conn = None):
+                 extraargs = None, virt_type = None, conn = None):
         Guest.Installer.__init__(self, type, location, boot, extraargs,
-                                 os_type, conn=conn)
+                                 virt_type, conn=conn)
 
     def prepare(self, guest, meter, distro = None):
         pass
diff --git a/virtinst/FullVirtGuest.py b/virtinst/FullVirtGuest.py
--- a/virtinst/FullVirtGuest.py
+++ b/virtinst/FullVirtGuest.py
@@ -35,7 +35,7 @@ class FullVirtGuest(Guest):
 
     def __init__(self, type=None, arch=None, connection=None, hypervisorURI=None, emulator=None, installer=None):
         if not installer:
-            installer = DistroManager.DistroInstaller(type = type, os_type = "hvm")
+            installer = DistroManager.DistroInstaller(type = type, virt_type = "hvm")
         Guest.__init__(self, type, connection, hypervisorURI, installer)
         self.disknode = "hd"
         self.features = { "acpi": None, "pae":
@@ -46,7 +46,7 @@ class FullVirtGuest(Guest):
 
         self.emulator = emulator
         self.loader = None
-        guest = self._caps.guestForOSType(type=self.installer.os_type,
+        guest = self._caps.guestForVirtType(type=self.installer.virt_type,
                                           arch=self.arch)
         if (not self.emulator) and guest:
             for dom in guest.domains:
diff --git a/virtinst/Guest.py b/virtinst/Guest.py
--- a/virtinst/Guest.py
+++ b/virtinst/Guest.py
@@ -305,12 +305,12 @@ class VirtualGraphics(object):
 
 class Installer(object):
     def __init__(self, type = "xen", location = None, boot = None,
-                 extraargs = None, os_type = None, conn = None):
+                 extraargs = None, virt_type = None, conn = None):
         self._location = None
         self._extraargs = None
         self._boot = None
         self._cdrom = False
-        self._os_type = os_type
+        self._virt_type = virt_type
         self._conn = conn
         self._install_disk = None   # VirtualDisk that contains install media
 
@@ -341,11 +341,11 @@ class Installer(object):
         self._type = val
     type = property(get_type, set_type)
 
-    def get_os_type(self):
-        return self._os_type
-    def set_os_type(self, val):
-        self._os_type = val
-    os_type = property(get_os_type, set_os_type)
+    def get_virt_type(self):
+        return self._virt_type
+    def set_virt_type(self, val):
+        self._virt_type = val
+    virt_type = property(get_virt_type, set_virt_type)
 
     def get_scratchdir(self):
         if platform.system() == 'SunOS':
@@ -411,15 +411,15 @@ class Installer(object):
 
         osblob = "<os>\n"
 
-        os_type = self.os_type
+        virt_type = self.virt_type
         # Hack for older libvirt Xen driver
-        if os_type == "xen" and self.type == "xen":
-            os_type = "linux"
+        if virt_type == "xen" and self.type == "xen":
+            virt_type = "linux"
 
         if arch:
-            osblob += "    <type arch='%s'>%s</type>\n" % (arch, os_type)
-        else:
-            osblob += "    <type>%s</type>\n" % os_type
+            osblob += "    <type arch='%s'>%s</type>\n" % (arch, virt_type)
+        else:
+            osblob += "    <type>%s</type>\n" % virt_type
 
         if loader:
             osblob += "    <loader>%s</loader>\n" % loader
diff --git a/virtinst/ImageManager.py b/virtinst/ImageManager.py
--- a/virtinst/ImageManager.py
+++ b/virtinst/ImageManager.py
@@ -111,18 +111,18 @@ class ImageInstaller(Guest.Installer):
         osblob = "<os>\n"
 
         if hvm:
-            os_type = "hvm"
+            virt_type = "hvm"
         else:
             # Hack for older libvirt Xen driver
             if self.type == "xen":
-                os_type = "linux"
+                virt_type = "linux"
             else:
-                os_type = "xen"
+                virt_type = "xen"
 
         if arch:
-            osblob += "    <type arch='%s'>%s</type>\n" % (arch, os_type)
+            osblob += "    <type arch='%s'>%s</type>\n" % (arch, virt_type)
         else:
-            osblob += "    <type>%s</type>\n" % os_type
+            osblob += "    <type>%s</type>\n" % virt_type
 
         if loader:
             osblob += "    <loader>%s</loader>\n" % loader
@@ -154,7 +154,7 @@ def match_boots(capabilities, boots):
 def match_boots(capabilities, boots):
     for b in boots:
         for g in capabilities.guests:
-            if b.type == g.os_type and b.arch == g.arch:
+            if b.type == g.virt_type and b.arch == g.arch:
                 found = True
                 for bf in b.features.names():
                     if not b.features[bf] & g.features[bf]:
diff --git a/virtinst/LiveCDInstaller.py b/virtinst/LiveCDInstaller.py
--- a/virtinst/LiveCDInstaller.py
+++ b/virtinst/LiveCDInstaller.py
@@ -29,10 +29,10 @@ class LiveCDInstallerException(Exception
         Exception.__init__(self, msg)
 
 class LiveCDInstaller(Guest.Installer):
-    def __init__(self, type = "xen", location = None, os_type = None,
+    def __init__(self, type = "xen", location = None, virt_type = None,
                  conn = None):
         Guest.Installer.__init__(self, type=type, location=location,
-                                 os_type=os_type, conn=conn)
+                                 virt_type=virt_type, conn=conn)
 
     def prepare(self, guest, meter, distro = None):
         self.cleanup()
@@ -41,7 +41,7 @@ class LiveCDInstaller(Guest.Installer):
 
         found = False
         for guest_caps in capabilities.guests:
-            if guest_caps.os_type == "hvm":
+            if guest_caps.virt_type == "hvm":
                 found = True
                 break
 
diff --git a/virtinst/OSDistro.py b/virtinst/OSDistro.py
--- a/virtinst/OSDistro.py
+++ b/virtinst/OSDistro.py
@@ -25,8 +25,10 @@ import re
 import re
 import tempfile
 import platform
+import socket
 import ConfigParser
 
+from virtinst import util
 from virtinst import _virtinst as _
 
 def distroFromTreeinfo(fetcher, progresscb, uri, vmtype=None,
@@ -83,7 +85,7 @@ class Distro:
         """Determine if uri points to a tree of the store's distro"""
         raise NotImplementedError
 
-    def acquireKernel(self, fetcher, progresscb):
+    def acquireKernel(self, guest, fetcher, progresscb):
         kernelpath = None
         initrdpath = None
         if self._hasTreeinfo(fetcher, progresscb):
@@ -106,7 +108,7 @@ class Distro:
                                  "%(distro)s tree.") % \
                                  { "distro": self.name, "type" : self.type })
 
-        return self._kernelFetchHelper(fetcher, progresscb, kernelpath,
+        return self._kernelFetchHelper(fetcher, guest, progresscb, kernelpath,
                                        initrdpath)
 
     def acquireBootDisk(self, fetcher, progresscb):
@@ -172,18 +174,21 @@ class Distro:
 
         return False
 
-    def _kernelFetchHelper(self, fetcher, progresscb, kernelpath, initrdpath):
+    def _kernelFetchHelper(self, fetcher, guest, progresscb, kernelpath, initrdpath):
         # Simple helper for fetching kernel + initrd and performing
         # cleanup if neccessary
         kernel = fetcher.acquireFile(kernelpath, progresscb)
+        args = ''
+
+        if not fetcher.location.startswith("/"):
+            args += "method=" + fetcher.location
+
+        if guest.extraargs:
+            args += guest.extraargs
+
         try:
             initrd = fetcher.acquireFile(initrdpath, progresscb)
-            if fetcher.location.startswith("/"):
-                # Local host path, so can't pass a location to guest
-                #for install method
-                return (kernel, initrd, "")
-            else:
-                return (kernel, initrd, "method=" + fetcher.location)
+            return kernel, initrd, args
         except:
             os.unlink(kernel)
 
@@ -193,6 +198,7 @@ class GenericDistro(Distro):
        as a last resort if we can't recognize any actual distro"""
 
     name = "Generic"
+    os_type = "linux"
     uses_treeinfo = True
 
     _xen_paths = [ ("images/xen/vmlinuz",
@@ -249,12 +255,12 @@ class GenericDistro(Distro):
             return True
         return False
 
-    def acquireKernel(self, fetcher, progresscb):
+    def acquireKernel(self, guest, fetcher, progresscb):
         if self._valid_kernel_path == None:
             raise ValueError(_("Could not find a kernel path for virt type "
                                "'%s'" % self.type))
 
-        return self._kernelFetchHelper(fetcher, progresscb,
+        return self._kernelFetchHelper(fetcher, guest, progresscb,
                                        self._valid_kernel_path[0],
                                        self._valid_kernel_path[1])
 
@@ -270,6 +276,7 @@ class RedHatDistro(Distro):
 class RedHatDistro(Distro):
 
     name = "Red Hat"
+    os_type = "linux"
     uses_treeinfo = True
     _boot_iso_paths   = [ "images/boot.iso" ]
     _hvm_kernel_paths = [ ("images/pxeboot/vmlinuz",
@@ -285,6 +292,7 @@ class FedoraDistro(RedHatDistro):
 class FedoraDistro(RedHatDistro):
 
     name = "Fedora"
+    os_type = "linux"
 
     def isValidStore(self, fetcher, progresscb):
         if self._hasTreeinfo(fetcher, progresscb):
@@ -300,6 +308,7 @@ class RHELDistro(RedHatDistro):
 class RHELDistro(RedHatDistro):
 
     name = "Red Hat Enterprise Linux"
+    os_type = "linux"
 
     def isValidStore(self, fetcher, progresscb):
         if self._hasTreeinfo(fetcher, progresscb):
@@ -322,6 +331,7 @@ class CentOSDistro(RedHatDistro):
 class CentOSDistro(RedHatDistro):
 
     name = "CentOS"
+    os_type = "linux"
 
     def isValidStore(self, fetcher, progresscb):
         if self._hasTreeinfo(fetcher, progresscb):
@@ -338,6 +348,7 @@ class SLDistro(RedHatDistro):
 class SLDistro(RedHatDistro):
 
     name = "Scientific Linux"
+    os_type = "linux"
     _boot_iso_paths = RedHatDistro._boot_iso_paths + [ "images/SL/boot.iso" ]
     _hvm_kernel_paths = RedHatDistro._hvm_kernel_paths + \
                         [ ("images/SL/pxeboot/vmlinuz",
@@ -361,6 +372,7 @@ class SuseDistro(Distro):
 class SuseDistro(Distro):
 
     name = "SUSE"
+    os_type = "linux"
     _boot_iso_paths   = [ "boot/boot.iso" ]
     _hvm_kernel_paths = []
     _xen_kernel_paths = []
@@ -385,11 +397,11 @@ class SuseDistro(Distro):
             return True
         return False
 
-    def acquireKernel(self, fetcher, progresscb):
+    def acquireKernel(self, guest, fetcher, progresscb):
         # If installing a fullvirt guest
         if self.type is None or self.type == "hvm" or \
            fetcher.hasFile("boot/%s/vmlinuz-xen" % self.arch):
-            return Distro.acquireKernel(self, fetcher, progresscb)
+            return Distro.acquireKernel(self, guest, fetcher, progresscb)
 
         # For Opensuse <= 10.2, we need to perform some heinous stuff
         logging.debug("Trying Opensuse 10 PV rpm hacking")
@@ -590,6 +602,7 @@ class DebianDistro(Distro):
     # daily builds: http://people.debian.org/~joeyh/d-i/
 
     name = "Debian"
+    os_type = "linux"
 
     def __init__(self, uri, vmtype=None, scratchdir=None, arch=None):
         Distro.__init__(self, uri, vmtype, scratchdir, arch)
@@ -642,6 +655,7 @@ class UbuntuDistro(DebianDistro):
 class UbuntuDistro(DebianDistro):
 
     name = "Ubuntu"
+    os_type = "linux"
 
     def _set_media_paths(self):
         DebianDistro._set_media_paths(self)
@@ -672,6 +686,7 @@ class MandrivaDistro(Distro):
     # Ex. ftp://ftp.uwsg.indiana.edu/linux/mandrake/official/2007.1/x86_64/
 
     name = "Mandriva"
+    os_type = "linux"
     _boot_iso_paths = [ "install/images/boot.iso" ]
     # Kernels for HVM: valid for releases 2007.1, 2008.*, 2009.0
     _hvm_kernel_paths = [ ("isolinux/alt0/vmlinuz", "isolinux/alt0/all.rdz")]
@@ -692,3 +707,194 @@ class MandrivaDistro(Distro):
 
         return False
 
+# Solaris and OpenSolaris distros
+class SunDistro(Distro):
+
+    name = "Solaris"
+    os_type = "solaris"
+
+    def isValidStore(self, fetcher, progresscb):
+        """Determine if uri points to a tree of the store's distro"""
+        raise NotImplementedError
+
+    def acquireBootDisk(self, fetcher, progresscb):
+        return fetcher.acquireFile("images/solarisdvd.iso", progresscb)
+
+    def process_extra_args(self, argstr):
+        """Collect additional arguments."""
+        if not argstr:
+            return (None, None, None, None)
+
+        kopts = ''
+        kargs = ''
+        smfargs = ''
+        Bargs = ''
+
+        args = argstr.split()
+        i = 0
+        while i < len(args):
+            exarg = args[i]
+            if exarg == '-B':
+                i += 1
+                if i == len(args):
+                    continue
+
+                if not Bargs:
+                    Bargs = args[i]
+                else:
+                    Bargs = ','.join([Bargs, args[i]])
+        
+            elif exarg == '-m':
+                i += 1
+                if i == len(args):
+                    continue
+                smfargs = args[i]
+            elif exarg.startswith('-'):
+                if kopts is None:
+                    kopts = exarg[1:]
+                else:
+                    kopts = kopts + exarg[1:]
+            else:
+                if kargs is None:
+                    kargs = exarg
+                else:
+                    kargs = kargs + ' ' + exarg
+            i += 1
+
+        return kopts, kargs, smfargs, Bargs
+
+class SolarisDistro(SunDistro):
+    kernelpath = "boot/platform/i86xpv/kernel/unix"
+    initrdpath = "boot/x86.miniroot"
+
+    def isValidStore(self, fetcher, progresscb):
+        if fetcher.hasFile(self.kernelpath):
+            logging.debug("Detected Solaris")
+            return True
+        return False
+
+    def install_args(self, guest):
+        """Construct kernel cmdline args for the installer, consisting of:
+           the pathname of the kernel (32/64) to load, kernel options
+           and args, and '-B' boot properties."""
+
+        # XXX: ignoring smfargs for the time being
+        (kopts, kargs, smfargs, kbargs) = \
+            self.process_extra_args(guest.extraargs)
+
+        bargs = ''
+        if kopts:
+            bargs += '-' + kopts + ' -'
+
+        if guest.graphics['enabled'] == False:
+            bargs += ' nowin'
+
+        if guest.autocf:
+            bargs += ' install'
+
+        if kargs:
+            bargs += ' ' + kargs
+
+        if guest.location.startswith('nfs:'):
+            try:
+                guestIP = socket.gethostbyaddr(guest.name)[2][0]
+            except:
+                bargs += ' dhcp'
+            else:
+                iserver = guest.location.split(':')[1]
+                ipath = guest.location.split(':')[2]
+                iserverIP = socket.gethostbyaddr(iserver)[2][0]
+                bargs += " -B install_media=" + iserverIP + ":" + ipath
+                bargs += ",host-ip=" + guestIP
+                droute = util.default_route(guest.nics[0].bridge)
+                if droute is not None:
+                    bargs += ",router-ip=" + droute
+                if guest.nics[0].macaddr is not None:
+                    en = guest.nics[0].macaddr.split(':')
+                    for i in range(len(en)):
+                        # remove leading '0' from mac address element
+                        if len(en[i]) > 1 and en[i][0] == '0':
+                            en[i] = en[i][1]
+                    boot_mac = ":".join(en)
+                    bargs += ",boot-mac=" + boot_mac
+                if guest.autocf:
+                    acf_host = guest.autocf.split(":")[1]
+                    acf_path = guest.autocf.split(":")[2]
+                    try:
+                        acf_hostip = socket.gethostbyaddr(acf_host)[2][0]
+                        bargs += ",sysid_config=" + acf_hostip + ":" + acf_path
+                        bargs += ",install_config=" + acf_hostip + ":" + acf_path
+                    except:
+                        print "failed to lookup host %s" % acf_host
+        else:
+            bargs += " -B install_media=cdrom"
+
+        if kbargs:
+            bargs += "," + kbargs
+
+        return bargs
+
+    def acquireKernel(self, guest, fetcher, progresscb):
+
+        try:
+            kernel = fetcher.acquireFile(self.kernelpath, progresscb)
+        except:
+            raise RuntimeError("Solaris PV kernel not found at %s" %
+                self.kernelpath)
+
+        # strip boot from the kernel path
+        kpath = self.kernelpath.split('/')[1:]
+        args = "/" + "/".join(kpath) + self.install_args(guest)
+
+        try:
+            initrd = fetcher.acquireFile(self.initrdpath, progresscb)
+            return (kernel, initrd, args)
+        except:
+            os.unlink(kernel)
+            raise RuntimeError(_("Solaris miniroot not found at %s") %
+                self.initrdpath)
+
+class OpenSolarisDistro(SunDistro):
+    kernelpath = "platform/i86xpv/kernel/unix"
+    initrdpath = "boot/x86.microroot"
+
+    def isValidStore(self, fetcher, progresscb):
+        if fetcher.hasFile(self.kernelpath):
+            logging.debug("Detected OpenSolaris")
+            return True
+        return False
+
+    def install_args(self, guest):
+        """Construct kernel cmdline args for the installer, consisting of:
+           the pathname of the kernel (32/64) to load, kernel options
+           and args, and '-B' boot properties."""
+
+        # XXX: ignoring smfargs and kargs for the time being
+        (kopts, kargs, smfargs, kbargs) = \
+            self.process_extra_args(guest.extraargs)
+
+        bargs = ''
+        if kopts:
+            bargs += ' -' + kopts
+        if kbargs:
+            bargs += ' -B ' + kbargs
+
+        return bargs
+
+    def acquireKernel(self, guest, fetcher, progresscb):
+
+        try:
+            kernel = fetcher.acquireFile(self.kernelpath, progresscb)
+        except:
+            raise RuntimeError(_("OpenSolaris PV kernel not found at %s") %
+                self.kernelpath)
+
+        args = "/" + self.kernelpath + self.install_args(guest)
+
+        try:
+            initrd = fetcher.acquireFile(self.initrdpath, progresscb)
+            return (kernel, initrd, args)
+        except:
+            os.unlink(kernel)
+            raise RuntimeError(_("OpenSolaris microroot not found at %s") %
+                self.initrdpath)
diff --git a/virtinst/ParaVirtGuest.py b/virtinst/ParaVirtGuest.py
--- a/virtinst/ParaVirtGuest.py
+++ b/virtinst/ParaVirtGuest.py
@@ -26,7 +26,7 @@ class ParaVirtGuest(Guest):
 class ParaVirtGuest(Guest):
     def __init__(self, type=None, connection=None, hypervisorURI=None, installer=None):
         if not installer:
-            installer = DistroInstaller(type = type, os_type = "linux")
+            installer = DistroInstaller(type = type, virt_type = "linux")
         Guest.__init__(self, type, connection, hypervisorURI, installer)
         self.disknode = "xvd"
 
diff --git a/virtinst/VirtualDisk.py b/virtinst/VirtualDisk.py
--- a/virtinst/VirtualDisk.py
+++ b/virtinst/VirtualDisk.py
@@ -519,6 +519,9 @@ class VirtualDisk(VirtualDevice):
 
         if self.target:
             disknode = self.target
+        if self.device == VirtualDisk.DEVICE_CDROM and disknode.startswith('xvd'):
+            disknode = disknode + ':cdrom'
+
         if not disknode:
             raise ValueError(_("'disknode' or self.target must be set!"))
 
diff --git a/virtinst/osdict.py b/virtinst/osdict.py
--- a/virtinst/osdict.py
+++ b/virtinst/osdict.py
@@ -31,6 +31,7 @@ DEFAULTS = { \
     "continue": False,
     "distro": None,
     "label": None,
+    "pv_cdrom_install": False,
     "devices" : {
      #  "devname" : { "attribute" : [( ["applicable", "hv-type", list"],
      #                               "recommended value for hv-types" ),]},
@@ -110,6 +111,7 @@ OS_TYPES = {\
 "solaris": {
     "label": "Solaris",
     "clock": "localtime",
+    "pv_cdrom_install": True,
     "variants": {
         "solaris9": { "label": "Sun Solaris 9", },
         "solaris10": { "label": "Sun Solaris 10",
diff --git a/virtinst/util.py b/virtinst/util.py
--- a/virtinst/util.py
+++ b/virtinst/util.py
@@ -38,7 +38,17 @@ KEYBOARD_DIR = "/etc/sysconfig/keyboard"
 KEYBOARD_DIR = "/etc/sysconfig/keyboard"
 XORG_CONF = "/etc/X11/xorg.conf"
 
-def default_route():
+def default_route(nic = None):
+    if platform.system() == 'SunOS':
+        cmd = '/usr/bin/netstat -rn'
+        if nic:
+            cmd += ' -I %s' % nic
+        for i in os.popen(cmd):
+            line = i.split()
+            if len(line) > 1 and line[0] == 'default':
+                return line[1]
+        return None
+
     route_file = "/proc/net/route"
     d = file(route_file)
 




More information about the et-mgmt-tools mailing list