1 Support for OpenSolaris AI (Auto Installer) 2 3 Allows OpenSolaris AI-specific boot options as part of the --autocf command line switch. 4 5 Signed-off-by: Tim Foster <tim.foster (a] sun.com> 6 7 diff --git a/virt-install b/virt-install 8 --- a/virt-install 9 +++ b/virt-install 10 @@ -422,9 +422,12 @@ 11 help=_("Additional arguments to pass to the kernel " 12 "booted from --location")) 13 insg.add_option("", "--autocf", type="string", dest="autocf", 14 - default=None, action="callback", 15 - callback=check_before_store, 16 - help=_("Guest auto-configuration path")) 17 + default=None, 18 + help=_("Guest auto-configuration path. " 19 + "A Jumpstart or kickstart path (eg, nfs:host:/path) " 20 + "or AI options, comma-separated name=value " 21 + "pairs (eg, install_service=x86_install," 22 + "install_media=http://host/path)")) 23 parser.add_option_group(insg) 24 25 stog = OptionGroup(parser, _("Storage Configuration")) 26 diff --git a/virtinst/Guest.py b/virtinst/Guest.py 27 --- a/virtinst/Guest.py 28 +++ b/virtinst/Guest.py 29 @@ -72,6 +72,7 @@ 30 self._graphics_dev = None 31 self._consolechild = None 32 self._autocf = None 33 + self._has_autocf = False 34 35 self._os_type = None 36 self._os_variant = None 37 @@ -103,18 +104,15 @@ 38 39 self._caps = CapabilitiesParser.parse(self.conn.getCapabilities()) 40 41 - # location of auto-install config data (Solaris jumpstart) 42 + # location of auto-install config data (Solaris jumpstart, kickstart or OpenSolaris AI) 43 def get_autocf(self): 44 return self._autocf 45 + def has_autocf(self): 46 + return self._has_autocf 47 def set_autocf(self, val): 48 - if type(val) is not type("string") or len(val) == 0: 49 - raise ValueError, _("You must specify a valid pathname to autoconfiguration data") 50 - if val.startswith('nfs:'): 51 + if val is not "": 52 self._autocf = val 53 - else: 54 - if not os.path.exists(val): 55 - raise ValueError, _("%s does not exist" % val) 56 - self._autocf = val 57 + self._has_autocf = True 58 autocf = property(get_autocf, set_autocf) 59 60 def get_installer(self): 61 diff --git a/virtinst/OSDistro.py b/virtinst/OSDistro.py 62 --- a/virtinst/OSDistro.py 63 +++ b/virtinst/OSDistro.py 64 @@ -965,7 +965,7 @@ 65 initrdpath = 'boot/x86.miniroot' 66 67 def isValidStore(self, fetcher, progresscb): 68 - if fetcher.hasFile(self.kernelpath): 69 + if fetcher.hasFile(self.kernelpath) and fetcher.hasFile(self.initrdpath): 70 logging.debug('Detected Solaris') 71 return True 72 return False 73 @@ -1090,6 +1090,31 @@ 74 if kbargs: 75 args += ' -B ' + kbargs 76 77 + # For OpenSolaris AI install, pull install server 78 + # and other options from the autocf entry 79 + if guest.has_autocf(): 80 + try: 81 + ai_opts = self.parse_ai_bootargs(guest.get_autocf()) 82 + except OSDistroException, osd_exception: 83 + raise Exception, "Unable to parse OpenSolaris AI options from %s: %s" \ 84 + % (guest.get_autocf(), str(osd_exception)) 85 + args += " -B network-interface=xnf0,xpv-hcp=dhcp,livemode=text" 86 + # If we're installing from a non http location 87 + # (like an AI-capable CD) we likely have the .zlib files locally 88 + # available and won't need to download from the install_media server. 89 + # Of course, the user can always set it in --autocf if they prefer 90 + if guest.get_location().startswith('http'): 91 + args += ",install_media=%s" % guest.get_location() 92 + 93 + for key in ai_opts: 94 + args += ",%s=%s" % (key, ai_opts[key]) 95 + 96 + # The user really should specify an install_service option unless 97 + # the installation server has a default set 98 + if not ai_opts.has_key('install_service'): 99 + print "WARNING: No install_service set via --autocf arguments,\ 100 + using default installation service, if configured." 101 + 102 return args 103 104 def acquireKernel(self, guest, fetcher, progresscb): 105 @@ -1113,6 +1138,22 @@ 106 os.unlink(kernel) 107 raise Exception("No OpenSolaris boot archive found: %s\n" % e) 108 109 + def parse_ai_bootargs(self, autocf): 110 + """For OpenSolaris AI installs, autocf boot arguments are comma-separated 111 + name-value pairs, 112 + eg. --autocf=install_service=foobar,install_media=http://foo/bar 113 + """ 114 + ai_opts = {} 115 + if autocf is not None: 116 + for nvpair in autocf.split(','): 117 + items = nvpair.split('=') 118 + if len(items) != 2: 119 + raise OSDistroException("Missing key value pair from autocf arg %s" % items) 120 + name, value = items 121 + ai_opts[name] = value 122 + 123 + return ai_opts 124 + 125 126 # NetWare 6 PV 127 class NetWareDistro(Distro): 128 @@ -1131,3 +1172,6 @@ 129 def acquireKernel(self, guest, fetcher, progresscb): 130 loader = fetcher.acquireFile(self.loaderpath, progresscb) 131 return (loader, "", "") 132 + 133 +class OSDistroException(Exception): 134 + pass 135