unattended,installer*: Deal with multiple install scripts

Windows' unattended installations have more than one installation script
in order to perform a "post" installation of some drivers
(spice-guest-tools, actually).

In order to do so, let's:
- Change unattended::_lookup_rawscript() to return a list of scripts;
  - And also rename it to _lookup_rawscripts();
- Change unattended::prepare_install_script to return a list of scripts;
  - And also rename it to prepare_install_scripts
- Change installer::_prepare_unattended_data() to deal with a list of
  scripts;
  - And also do the "renaming" changes accordingly;
- Change installertreeinfo::_prepare_unattended_data() to deal with a
  list of scripts;
  - And also do the "renaming" changes accordingly;
  - Mind that this change is not exactly needed as Linux unattended
    installations have only one install script. However, the change has
    been done ir order to be consitent with the changes done in the
    installer;
- Change installertreeinfo::_prepare_kernel_args() to deal with a list
  of scripts;
  - And also do the "renaming" changes accordingly;
  - As the changes above, this one is not exactly needed for the very
    same reason;

Reviewed-by: Cole Robinson <crobinso@redhat.com>
Signed-off-by: Fabiano Fidêncio <fidencio@redhat.com>
This commit is contained in:
Fabiano Fidêncio 2019-07-30 17:23:35 +02:00 committed by Cole Robinson
parent 9c051fe65f
commit f4d91dfcd2
3 changed files with 61 additions and 44 deletions

View File

@ -219,20 +219,23 @@ class Installer(object):
# Internal API overrides # # Internal API overrides #
########################## ##########################
def _prepare_unattended_data(self, guest, script): def _prepare_unattended_data(self, guest, scripts):
expected_filename = script.get_expected_filename() injections = []
unattended_cmdline = script.generate_cmdline() for script in scripts:
log.debug("Generated unattended cmdline: %s", unattended_cmdline) expected_filename = script.get_expected_filename()
unattended_cmdline = script.generate_cmdline()
log.debug("Generated unattended cmdline: %s", unattended_cmdline)
scriptpath = script.write() scriptpath = script.write()
self._tmpfiles.append(scriptpath) self._tmpfiles.append(scriptpath)
injections.append((scriptpath, expected_filename))
iso = perform_cdrom_injections([(scriptpath, expected_filename)], iso = perform_cdrom_injections(injections,
InstallerTreeMedia.make_scratchdir(guest)) InstallerTreeMedia.make_scratchdir(guest))
self._tmpfiles.append(iso) self._tmpfiles.append(iso)
self._add_unattended_install_cdrom_device(guest, iso) self._add_unattended_install_cdrom_device(guest, iso)
def _prepare_unattended_script(self, guest, meter): def _prepare_unattended_scripts(self, guest, meter):
url = None url = None
os_tree = None os_tree = None
if self._treemedia: if self._treemedia:
@ -253,21 +256,21 @@ class Installer(object):
os_media = osguess[1] if osguess else None os_media = osguess[1] if osguess else None
injection_method = "cdrom" injection_method = "cdrom"
return unattended.prepare_install_script( return unattended.prepare_install_scripts(
guest, self._unattended_data, url, guest, self._unattended_data, url,
os_media, os_tree, injection_method) os_media, os_tree, injection_method)
def _prepare(self, guest, meter): def _prepare(self, guest, meter):
unattended_script = None unattended_scripts = None
if self._unattended_data: if self._unattended_data:
unattended_script = self._prepare_unattended_script(guest, meter) unattended_scripts = self._prepare_unattended_scripts(guest, meter)
if self._treemedia: if self._treemedia:
self._treemedia_bootconfig = self._treemedia.prepare(guest, meter, self._treemedia_bootconfig = self._treemedia.prepare(guest, meter,
unattended_script) unattended_scripts)
elif unattended_script: elif unattended_scripts:
self._prepare_unattended_data(guest, unattended_script) self._prepare_unattended_data(guest, unattended_scripts)
def _cleanup(self, guest): def _cleanup(self, guest):
if self._treemedia: if self._treemedia:

View File

@ -231,18 +231,26 @@ class InstallerTreeMedia(object):
# Public API # # Public API #
############## ##############
def _prepare_unattended_data(self, script): def _prepare_unattended_data(self, scripts):
if not script: if not scripts:
return return
expected_filename = script.get_expected_filename()
scriptpath = script.write()
self._tmpfiles.append(scriptpath)
self._initrd_injections.append((scriptpath, expected_filename))
def _prepare_kernel_args(self, cache, unattended_script): for script in scripts:
expected_filename = script.get_expected_filename()
scriptpath = script.write()
self._tmpfiles.append(scriptpath)
self._initrd_injections.append((scriptpath, expected_filename))
def _prepare_kernel_args(self, cache, unattended_scripts):
install_args = None install_args = None
if unattended_script: if unattended_scripts:
install_args = unattended_script.generate_cmdline() args = []
for unattended_script in unattended_scripts:
cmdline = unattended_script.generate_cmdline()
if not cmdline:
continue
args.append(cmdline)
install_args = (" ").join(args)
log.debug("Generated unattended cmdline: %s", install_args) log.debug("Generated unattended cmdline: %s", install_args)
elif self.is_network_url() and cache.kernel_url_arg: elif self.is_network_url() and cache.kernel_url_arg:
install_args = "%s=%s" % (cache.kernel_url_arg, self.location) install_args = "%s=%s" % (cache.kernel_url_arg, self.location)
@ -261,12 +269,12 @@ class InstallerTreeMedia(object):
"installer at a network accessible install tree.")) "installer at a network accessible install tree."))
return ret return ret
def prepare(self, guest, meter, unattended_script): def prepare(self, guest, meter, unattended_scripts):
fetcher = self._get_fetcher(guest, meter) fetcher = self._get_fetcher(guest, meter)
cache = self._get_cached_data(guest, fetcher) cache = self._get_cached_data(guest, fetcher)
self._prepare_unattended_data(unattended_script) self._prepare_unattended_data(unattended_scripts)
kernel_args = self._prepare_kernel_args(cache, unattended_script) kernel_args = self._prepare_kernel_args(cache, unattended_scripts)
kernel, initrd = self._prepare_kernel_url(guest, cache, fetcher) kernel, initrd = self._prepare_kernel_url(guest, cache, fetcher)
return kernel, initrd, kernel_args return kernel, initrd, kernel_args

View File

@ -282,7 +282,7 @@ def _find_default_profile(profile_names):
return found or profile_names[0] return found or profile_names[0]
def _lookup_rawscript(osinfo, profile, os_media): def _lookup_rawscripts(osinfo, profile, os_media):
script_list = [] script_list = []
if os_media: if os_media:
@ -320,35 +320,41 @@ def _lookup_rawscript(osinfo, profile, os_media):
# Some OSes (as Windows) have more than one installer script, # Some OSes (as Windows) have more than one installer script,
# depending on the OS version and profile chosen, to be used to # depending on the OS version and profile chosen, to be used to
# perform the unattended installation. Let's just deal with # perform the unattended installation.
# multiple installer scripts when its actually needed, though. ids = []
usescript = rawscripts[0] for rawscript in rawscripts:
log.debug("Install script found for profile '%s': %s", ids.append(rawscript.get_id())
profile, usescript.get_id())
return usescript log.debug("Install scripts found for profile '%s': %s",
profile, ", ".join(ids))
return rawscripts
def prepare_install_script(guest, unattended_data, def prepare_install_scripts(guest, unattended_data,
url, os_media, os_tree, injection_method): url, os_media, os_tree, injection_method):
def _get_installation_source(os_media): def _get_installation_source(os_media):
if not os_media: if not os_media:
return "network" return "network"
return "media" return "media"
rawscript = _lookup_rawscript(guest.osinfo, scripts = []
rawscripts = _lookup_rawscripts(guest.osinfo,
unattended_data.profile, os_media) unattended_data.profile, os_media)
osinfomediaobj = os_media.get_osinfo_media() if os_media else None osinfomediaobj = os_media.get_osinfo_media() if os_media else None
osinfotreeobj = os_tree.get_osinfo_tree() if os_tree else None osinfotreeobj = os_tree.get_osinfo_tree() if os_tree else None
script = OSInstallScript(
rawscript, guest.osinfo, osinfomediaobj, osinfotreeobj)
script.set_preferred_injection_method(injection_method) for rawscript in rawscripts:
script = OSInstallScript(
rawscript, guest.osinfo, osinfomediaobj, osinfotreeobj)
installationsource = _get_installation_source(os_media) script.set_preferred_injection_method(injection_method)
script.set_installation_source(installationsource)
config = _make_installconfig(script, guest.osinfo, unattended_data, installationsource = _get_installation_source(os_media)
guest.os.arch, guest.name, url) script.set_installation_source(installationsource)
script.set_config(config)
return script config = _make_installconfig(script, guest.osinfo, unattended_data,
guest.os.arch, guest.name, url)
script.set_config(config)
scripts.append(script)
return scripts