From 2a8a8000658a08da83dd68529b6b1f630ad904f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milo=C5=A1=20Prchl=C3=ADk?= Date: Sat, 9 Dec 2023 13:33:11 +0100 Subject: [PATCH] squash: address comments --- tmt/package_managers/dnf.py | 50 +++++++++++++++++++++++-------- tmt/steps/prepare/install.py | 57 +++++++++++++++++++++++------------- 2 files changed, 74 insertions(+), 33 deletions(-) diff --git a/tmt/package_managers/dnf.py b/tmt/package_managers/dnf.py index 635ed60ca4..937746f03d 100644 --- a/tmt/package_managers/dnf.py +++ b/tmt/package_managers/dnf.py @@ -42,6 +42,14 @@ def query(self, packages: list[Command]) -> CommandOutput: """ )) + def _check_presence_script(self, packages: list[Command]) -> ShellScript: + return ShellScript( + f'rpm -q --whatprovides {" ".join(str(package.to_script()) for package in packages)}' + ) + + def check_presence(self, packages: list[Command]) -> CommandOutput: + return self.guest.execute(self._check_presence_script(packages)) + def install( self, packages: list[Command], @@ -55,20 +63,14 @@ def install( packages_as_arguments = " ".join(str(package.to_script()) for package in packages) if check_first: - return self.guest.execute(ShellScript( - f'rpm -q --whatprovides {packages_as_arguments}' - ' || ' - f'{self.command.to_script()} install {self.options.to_script()} {extra_options} {packages_as_arguments}' - )) + return self.guest.execute( + self._check_presence_script(packages) + | ShellScript(f'{self.command.to_script()} install {self.options.to_script()} {extra_options} {packages_as_arguments}') + ) return self.guest.execute(ShellScript( - f""" - {self.command.to_script()} install \ - {self.options.to_script()} \ - {extra_options} \ - {packages_as_arguments} - """ - )) + f'{self.command.to_script()} install {self.options.to_script()} {extra_options} {packages_as_arguments}' + )) def install_local( self, @@ -157,3 +159,27 @@ class Dnf5(Dnf): @provides_package_manager('yum') class Yum(Dnf): base_command = Command('yum') + + def install( + self, + packages: list[Command], + excluded_packages: Optional[list[str]] = None, + skip_missing: bool = False, + check_first: bool = True) -> CommandOutput: + super().install( + packages, + excluded_packages=excluded_packages, + skip_missing=skip_missing, + check_first=check_first) + +# # Extra ignore/check for yum to workaround BZ#1920176 +# check = ShellScript(f'rpm -q --whatprovides {packages.to_script()}') +# script = check | self.operation_script(Command('install'), packages) +# +# if self.skip_missing: +# script |= ShellScript('true') +# else: +# script &= check +# +# # Check and install +# self.guest.execute(script) diff --git a/tmt/steps/prepare/install.py b/tmt/steps/prepare/install.py index b34fe5406b..cad3af8ea7 100644 --- a/tmt/steps/prepare/install.py +++ b/tmt/steps/prepare/install.py @@ -27,15 +27,12 @@ class InstallBase(tmt.utils.Common): # copr_plugin: str skip_missing: bool = False - - packages: list[str] - directories: list[Path] exclude: list[str] + packages: list[str] local_packages: list[Path] remote_packages: list[str] debuginfo_packages: list[str] - repository_packages: list[str] rpms_directory: Path @@ -44,34 +41,40 @@ def __init__( *, parent: 'PrepareInstall', guest: Guest, + packages: list[tmt.base.DependencySimple], + directories: list[Path], + exclude: list[str], logger: tmt.log.Logger) -> None: """ Initialize installation data """ super().__init__(logger=logger, parent=parent, relative_indent=0) + if not packages and not directories: + self.debug("No packages for installation found.", level=3) + self.guest = guest + self.exclude = exclude # Get package related data from the plugin - self.packages = parent.get("package", []) - self.directories = cast(list[Path], parent.get("directory", [])) - self.exclude = parent.get("exclude", []) - - if not self.packages and not self.directories: - self.debug("No packages for installation found.", level=3) + # self.packages = parent.get("package", []) + # self.directories = cast(list[Path], parent.get("directory", [])) self.skip_missing = bool(parent.get('missing') == 'skip') # Prepare package lists and installation command - self.prepare_packages() + self.prepare_packages(packages, directories) - def prepare_packages(self) -> None: + def prepare_packages( + self, + packages: list[tmt.base.DependencySimple], + directories: list[Path]) -> None: """ Process package names and directories """ + self.packages = [] self.local_packages = [] self.remote_packages = [] self.debuginfo_packages = [] - self.repository_packages = [] # Detect local, debuginfo and repository packages - for package in self.packages: + for package in packages: if re.match(r"^http(s)?://", package): self.remote_packages.append(package) elif package.endswith(".rpm"): @@ -82,10 +85,10 @@ def prepare_packages(self) -> None: package = re.sub(r"-debuginfo((?=\.)|$)", "", package) self.debuginfo_packages.append(package) else: - self.repository_packages.append(package) + self.packages.append(package) # Check rpm packages in local directories - for directory in self.directories: + for directory in directories: self.info('directory', directory, 'green') if not directory.is_dir(): raise tmt.utils.PrepareError(f"Packages directory '{directory}' not found.") @@ -204,7 +207,7 @@ def install(self) -> None: self.install_local() if self.remote_packages: self.install_from_url() - if self.repository_packages: + if self.packages: self.install_from_repository() if self.debuginfo_packages: self.install_debuginfo() @@ -247,7 +250,7 @@ def install_from_url(self) -> None: def install_from_repository(self) -> None: """ Install packages from a repository """ - packages = self.list_packages(self.repository_packages, title="package") + packages = self.list_packages(self.packages, title="package") self.guest.package_manager.install( [packages], @@ -304,7 +307,7 @@ def sort_packages(self) -> None: """ Identify required and recommended packages """ self.recommended_packages = [] self.required_packages = [] - for package in self.repository_packages: + for package in self.packages: try: output = self.guest.execute(Command('rpm', '-q', package), silent=True) assert output.stdout @@ -489,10 +492,22 @@ def go( # TODO: it'd be nice to use a "plugin registry" and make the implementations # discovered as any other plugins. if guest.facts.package_manager == GuestPackageManager.RPM_OSTREE: - installer: InstallBase = InstallRpmOstree(logger=logger, parent=self, guest=guest) + installer: InstallBase = InstallRpmOstree( + logger=logger, + parent=self, + packages=self.data.package, + directories=self.data.directory, + exclude=self.data.exclude, + guest=guest) elif guest.facts.package_manager in (GuestPackageManager.DNF, GuestPackageManager.DNF5, GuestPackageManager.YUM): - installer = InstallDnf(logger=logger, parent=self, guest=guest) + installer = InstallDnf( + logger=logger, + parent=self, + packages=self.data.package, + directories=self.data.directory, + exclude=self.data.exclude, + guest=guest) else: raise tmt.utils.PrepareError(