From f4d91dfcd2c67ad6237fdc4feb7de10575fba61b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= Date: Tue, 30 Jul 2019 17:23:35 +0200 Subject: [PATCH] unattended,installer*: Deal with multiple install scripts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Signed-off-by: Fabiano FidĂȘncio --- virtinst/install/installer.py | 31 ++++++++++--------- virtinst/install/installertreemedia.py | 32 ++++++++++++-------- virtinst/install/unattended.py | 42 +++++++++++++++----------- 3 files changed, 61 insertions(+), 44 deletions(-) diff --git a/virtinst/install/installer.py b/virtinst/install/installer.py index e2765512a..cbe0b4281 100644 --- a/virtinst/install/installer.py +++ b/virtinst/install/installer.py @@ -219,20 +219,23 @@ class Installer(object): # Internal API overrides # ########################## - def _prepare_unattended_data(self, guest, script): - expected_filename = script.get_expected_filename() - unattended_cmdline = script.generate_cmdline() - log.debug("Generated unattended cmdline: %s", unattended_cmdline) + def _prepare_unattended_data(self, guest, scripts): + injections = [] + for script in scripts: + expected_filename = script.get_expected_filename() + unattended_cmdline = script.generate_cmdline() + log.debug("Generated unattended cmdline: %s", unattended_cmdline) - scriptpath = script.write() - self._tmpfiles.append(scriptpath) + scriptpath = script.write() + 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)) self._tmpfiles.append(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 os_tree = None if self._treemedia: @@ -253,21 +256,21 @@ class Installer(object): os_media = osguess[1] if osguess else None injection_method = "cdrom" - return unattended.prepare_install_script( + return unattended.prepare_install_scripts( guest, self._unattended_data, url, os_media, os_tree, injection_method) def _prepare(self, guest, meter): - unattended_script = None + unattended_scripts = None if self._unattended_data: - unattended_script = self._prepare_unattended_script(guest, meter) + unattended_scripts = self._prepare_unattended_scripts(guest, meter) if self._treemedia: self._treemedia_bootconfig = self._treemedia.prepare(guest, meter, - unattended_script) + unattended_scripts) - elif unattended_script: - self._prepare_unattended_data(guest, unattended_script) + elif unattended_scripts: + self._prepare_unattended_data(guest, unattended_scripts) def _cleanup(self, guest): if self._treemedia: diff --git a/virtinst/install/installertreemedia.py b/virtinst/install/installertreemedia.py index d91af55e8..059f826f3 100644 --- a/virtinst/install/installertreemedia.py +++ b/virtinst/install/installertreemedia.py @@ -231,18 +231,26 @@ class InstallerTreeMedia(object): # Public API # ############## - def _prepare_unattended_data(self, script): - if not script: + def _prepare_unattended_data(self, scripts): + if not scripts: 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 - if unattended_script: - install_args = unattended_script.generate_cmdline() + if unattended_scripts: + 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) elif self.is_network_url() and cache.kernel_url_arg: install_args = "%s=%s" % (cache.kernel_url_arg, self.location) @@ -261,12 +269,12 @@ class InstallerTreeMedia(object): "installer at a network accessible install tree.")) return ret - def prepare(self, guest, meter, unattended_script): + def prepare(self, guest, meter, unattended_scripts): fetcher = self._get_fetcher(guest, meter) cache = self._get_cached_data(guest, fetcher) - self._prepare_unattended_data(unattended_script) - kernel_args = self._prepare_kernel_args(cache, unattended_script) + self._prepare_unattended_data(unattended_scripts) + kernel_args = self._prepare_kernel_args(cache, unattended_scripts) kernel, initrd = self._prepare_kernel_url(guest, cache, fetcher) return kernel, initrd, kernel_args diff --git a/virtinst/install/unattended.py b/virtinst/install/unattended.py index 1d6f0b4ab..9cdb2886e 100644 --- a/virtinst/install/unattended.py +++ b/virtinst/install/unattended.py @@ -282,7 +282,7 @@ def _find_default_profile(profile_names): return found or profile_names[0] -def _lookup_rawscript(osinfo, profile, os_media): +def _lookup_rawscripts(osinfo, profile, os_media): script_list = [] if os_media: @@ -320,35 +320,41 @@ def _lookup_rawscript(osinfo, profile, os_media): # Some OSes (as Windows) have more than one installer script, # depending on the OS version and profile chosen, to be used to - # perform the unattended installation. Let's just deal with - # multiple installer scripts when its actually needed, though. - usescript = rawscripts[0] - log.debug("Install script found for profile '%s': %s", - profile, usescript.get_id()) - return usescript + # perform the unattended installation. + ids = [] + for rawscript in rawscripts: + ids.append(rawscript.get_id()) + + 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): def _get_installation_source(os_media): if not os_media: return "network" return "media" - rawscript = _lookup_rawscript(guest.osinfo, + scripts = [] + rawscripts = _lookup_rawscripts(guest.osinfo, unattended_data.profile, os_media) osinfomediaobj = os_media.get_osinfo_media() if os_media 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_installation_source(installationsource) + script.set_preferred_injection_method(injection_method) - config = _make_installconfig(script, guest.osinfo, unattended_data, - guest.os.arch, guest.name, url) - script.set_config(config) - return script + installationsource = _get_installation_source(os_media) + script.set_installation_source(installationsource) + + config = _make_installconfig(script, guest.osinfo, unattended_data, + guest.os.arch, guest.name, url) + script.set_config(config) + scripts.append(script) + return scripts