Both epel and crb feature plugins independently install dnf-command(config-manager) via direct guest.package_manager.install(Package(...)) calls. This duplicates version-specific logic and doesn't follow the existing abstraction pattern established by copr_plugin / enable_copr().
Current state
epel.py has a private _install_config_manager() method that branches on version (yum-utils for v7, dnf-command(config-manager) for v8+)
crb.py directly calls guest.package_manager.install(Package("dnf-command(config-manager)"))
- No shared abstraction exists for this common operation
Proposed change
Follow the copr_plugin pattern:
- Add
config_manager_plugin ClassVar to DNF package manager classes (Dnf, Dnf5, Yum) with appropriate virtual provides
- Add
install_config_manager() method to PackageManager base class (raises PrepareError for unsupported managers)
- Implement
install_config_manager() in Dnf class (inherited by Dnf5 and Yum)
- Replace direct install calls in
epel.py and crb.py with guest.package_manager.install_config_manager()
References
Both
epelandcrbfeature plugins independently installdnf-command(config-manager)via directguest.package_manager.install(Package(...))calls. This duplicates version-specific logic and doesn't follow the existing abstraction pattern established bycopr_plugin/enable_copr().Current state
epel.pyhas a private_install_config_manager()method that branches on version (yum-utils for v7, dnf-command(config-manager) for v8+)crb.pydirectly callsguest.package_manager.install(Package("dnf-command(config-manager)"))Proposed change
Follow the
copr_pluginpattern:config_manager_pluginClassVar to DNF package manager classes (Dnf,Dnf5,Yum) with appropriate virtual providesinstall_config_manager()method toPackageManagerbase class (raisesPrepareErrorfor unsupported managers)install_config_manager()inDnfclass (inherited byDnf5andYum)epel.pyandcrb.pywithguest.package_manager.install_config_manager()References
epelandcrbfeatures in Image Mode #4800 (comment)epelandcrbfeatures in Image Mode #4800