diff --git a/tmt/package_managers/__init__.py b/tmt/package_managers/__init__.py index 82f05bac4e..248de6aa09 100644 --- a/tmt/package_managers/__init__.py +++ b/tmt/package_managers/__init__.py @@ -329,6 +329,12 @@ class Options: #: If set, instruct package manager to install from untrusted sources. allow_untrusted: bool = False + #: If set, allow erasing conflicting or obsoleting packages during install. + allow_erasing: bool = False + + #: If set, allow downgrades of transitive dependencies during install. + allow_downgrade: bool = False + class PackageManagerEngine(tmt.utils.Common): command: Command diff --git a/tmt/package_managers/dnf.py b/tmt/package_managers/dnf.py index 9a807595cc..b71fbafae6 100644 --- a/tmt/package_managers/dnf.py +++ b/tmt/package_managers/dnf.py @@ -59,6 +59,10 @@ def _extra_dnf_options(self, options: Options, command: Optional[Command] = None else: raise GeneralError(f"Unhandled package manager command '{command}'.") + if options.allow_erasing: + # Supported by DNF4 and DNF5; YumEngine raises PrepareError for this flag. + extra_options += Command('--allowerasing') + return extra_options def _construct_presence_script( @@ -398,6 +402,19 @@ class Dnf5Engine(DnfEngine): skip_missing_packages_option = '--skip-unavailable' skip_missing_debuginfo_option = skip_missing_packages_option + def _extra_dnf_options(self, options: Options, command: Optional[Command] = None) -> Command: + """ + Collect additional options for ``dnf5`` based on given options. + """ + + extra_options = super()._extra_dnf_options(options, command) + + if options.allow_downgrade: + # DNF4 allows transitive downgrades automatically; this flag is DNF5-specific. + extra_options += Command('--allow-downgrade') + + return extra_options + @provides_package_manager('dnf5') class Dnf5(Dnf): @@ -415,6 +432,11 @@ class Dnf5(Dnf): class YumEngine(DnfEngine): _base_command = Command('yum') + def _extra_dnf_options(self, options: Options, command: Optional[Command] = None) -> Command: + if options.allow_erasing: + raise PrepareError("Package manager 'yum' does not support '--allowerasing'.") + return super()._extra_dnf_options(options, command) + def _yum_config_manager_command(self) -> Command: command = Command('yum-config-manager')