Hide Forgot
Description of problem: When dnf plugin is shipped via rpm package and that rpm package gets upgraded to newer version, the operation of the plugin is not disturbed -- the transaction() call after the old package was removed is still invoked, running code from the old version. However, when instead of upgrading the rpm package with the plugin, different package which brings the same dnf plugin is installed, and it removes the previous package via Obsoletes, the transaction() is not invoked. Version-Release number of selected component (if applicable): dnf-4.0.9.2-5.el8.noarch How reproducible: Deterministic. Steps to Reproduce: 1. Have plugin code in dnf-plugins/a.py which implements plugin "a" which will show us the list of installed and removed packages: from dnf import Plugin from dnfpluginscore import logger class a(Plugin): def resolved(self): logger.warning("resolved a0: install_set %s, remove_set %s" % ( self.base.transaction.install_set, self.base.transaction.remove_set )) def transaction(self): logger.warning("transaction a0: install_set %s, remove_set %s" % ( self.base.transaction.install_set, self.base.transaction.remove_set )) 2. Have setup.py: try: from setuptools import setup except ImportError: from distutils.core import setup setup( name = 'a-plugin', version = '0.0.0', py_modules = ['dnf-plugins.a'], ) 3. Build the plugin rpm: python3 setup.py bdist_rpm --binary-only 4. Install the plugin: dnf install -y dist/a-plugin-0.0.0-1.noarch.rpm 5. Install some package, to see what the transaction looks like: dnf install -y zsh 6. Observe the output says Last metadata expiration check: 0:59:09 ago on Wed 17 Apr 2019 04:34:58 AM EDT. resolved a0: install_set {<hawkey.Package object id 13644, zsh-5.5.1-6.el8.x86_64, BaseOS>}, remove_set set() Dependencies resolved. [...] Verifying : zsh-5.5.1-6.el8.x86_64 1/1 Installed products updated. transaction a0: install_set {<hawkey.Package object id 13644, zsh-5.5.1-6.el8.x86_64, BaseOS>}, remove_set set() 7. Now we update the version of the rpm but also record the new version in the plugin code: diff --git a/dnf-plugins/a.py b/dnf-plugins/a.py index 8467b0f..a5da385 100644 --- a/dnf-plugins/a.py +++ b/dnf-plugins/a.py @@ -4,9 +4,9 @@ from dnfpluginscore import logger class a(Plugin): def resolved(self): - logger.warning("resolved a0: install_set %s, remove_set %s" + logger.warning("resolved a1: install_set %s, remove_set %s" % ( self.base.transaction.install_set, self.base.transaction.remove_set )) def transaction(self): - logger.warning("transaction a0: install_set %s, remove_set %s" + logger.warning("transaction a1: install_set %s, remove_set %s" % ( self.base.transaction.install_set, self.base.transaction.remove_set )) diff --git a/setup.py b/setup.py index 01d7eb4..98b370b 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ except ImportError: setup( name = 'a-plugin', - version = '0.0.0', + version = '1.0.0', py_modules = ['dnf-plugins.a'], ) 8. Build rpm: python3 setup.py bdist_rpm --binary-only 9. Upgrade the plugin: dnf upgrade -y dist/a-plugin-1.0.0-1.noarch.rpm 10. Observe the output says that the old version (a0) code was invoked both before the upgrade (resolved) and after the upgrade (transaction): resolved a0: install_set {<hawkey.Package object id 46307, a-plugin-1.0.0-1.noarch, @commandline>}, remove_set {<hawkey.Package object id 6, a-plugin-0.0.0-1.noarch, @System>} [...] Installed products updated. transaction a0: install_set {<hawkey.Package object id 46307, a-plugin-1.0.0-1.noarch, @commandline>}, remove_set {<hawkey.Package object id 6, a-plugin-0.0.0-1.noarch, @System>} 11. Run some dnf operation and notice that now the "a1" code is invoked: dnf remove -y zsh resolved a1: install_set set(), remove_set {<hawkey.Package object id 444, zsh-5.5.1-6.el8.x86_64, @System>} [...] transaction a1: install_set set(), remove_set {<hawkey.Package object id 444, zsh-5.5.1-6.el8.x86_64, @System>} 12. Now move the plugin to different rpm package, from a-plugin to b-plugin. Since the actual name of the plugin and thus the file where it is stored stays the same, we need to add Obsoletes, to avoid errors like file /usr/lib/python3.6/site-packages/dnf-plugins/a.py from install of b-plugin-1.0.0-1.noarch conflicts with file from package a-plugin-1.0.0-1.noarch: diff --git a/dnf-plugins/a.py b/dnf-plugins/a.py index a5da385..22a1b9e 100644 --- a/dnf-plugins/a.py +++ b/dnf-plugins/a.py @@ -4,9 +4,9 @@ from dnfpluginscore import logger class a(Plugin): def resolved(self): - logger.warning("resolved a1: install_set %s, remove_set %s" + logger.warning("resolved b1: install_set %s, remove_set %s" % ( self.base.transaction.install_set, self.base.transaction.remove_set )) def transaction(self): - logger.warning("transaction a1: install_set %s, remove_set %s" + logger.warning("transaction b1: install_set %s, remove_set %s" % ( self.base.transaction.install_set, self.base.transaction.remove_set )) diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..0b08475 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,2 @@ +[bdist_rpm] +obsoletes = a-plugin diff --git a/setup.py b/setup.py index 98b370b..4937d84 100644 --- a/setup.py +++ b/setup.py @@ -4,7 +4,7 @@ except ImportError: from distutils.core import setup setup( - name = 'a-plugin', + name = 'b-plugin', version = '1.0.0', py_modules = ['dnf-plugins.a'], ) 13. Build rpm: python3 setup.py bdist_rpm --binary-only 14. Install the new package: dnf install -y dist/b-plugin-1.0.0-1.noarch.rpm Actual results: Updating Subscription Management repositories. Unable to read consumer identity This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register. Last metadata expiration check: 0:11:35 ago on Wed 17 Apr 2019 05:36:48 AM EDT. resolved a1: install_set {<hawkey.Package object id 46306, b-plugin-1.0.0-1.noarch, @commandline>}, remove_set {<hawkey.Package object id 6, a-plugin-1.0.0-1.noarch, @System>} Dependencies resolved. ================================================================================ Package Arch Version Repository Size ================================================================================ Installing: b-plugin noarch 1.0.0-1 @commandline 8.2 k replacing a-plugin.noarch 1.0.0-1 Transaction Summary ================================================================================ Install 1 Package Total size: 8.2 k Downloading Packages: Running transaction check Transaction check succeeded. Running transaction test Transaction test succeeded. Running transaction Preparing : 1/1 Installing : b-plugin-1.0.0-1.noarch 1/2 Obsoleting : a-plugin-1.0.0-1.noarch 2/2 Running scriptlet: a-plugin-1.0.0-1.noarch 2/2 Verifying : b-plugin-1.0.0-1.noarch 1/2 Verifying : a-plugin-1.0.0-1.noarch 2/2 Installed products updated. Installed: b-plugin-1.0.0-1.noarch Complete! Expected results: Updating Subscription Management repositories. Unable to read consumer identity This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register. Last metadata expiration check: 0:11:35 ago on Wed 17 Apr 2019 05:36:48 AM EDT. resolved a1: install_set {<hawkey.Package object id 46306, b-plugin-1.0.0-1.noarch, @commandline>}, remove_set {<hawkey.Package object id 6, a-plugin-1.0.0-1.noarch, @System>} Dependencies resolved. ================================================================================ Package Arch Version Repository Size ================================================================================ Installing: b-plugin noarch 1.0.0-1 @commandline 8.2 k replacing a-plugin.noarch 1.0.0-1 Transaction Summary ================================================================================ Install 1 Package Total size: 8.2 k Downloading Packages: Running transaction check Transaction check succeeded. Running transaction test Transaction test succeeded. Running transaction Preparing : 1/1 Installing : b-plugin-1.0.0-1.noarch 1/2 Obsoleting : a-plugin-1.0.0-1.noarch 2/2 Running scriptlet: a-plugin-1.0.0-1.noarch 2/2 Verifying : b-plugin-1.0.0-1.noarch 1/2 Verifying : a-plugin-1.0.0-1.noarch 2/2 Installed products updated. transaction a1: install_set {<hawkey.Package object id 46306, b-plugin-1.0.0-1.noarch, @commandline>}, remove_set {<hawkey.Package object id 6, a-plugin-1.0.0-1.noarch, @System>} Installed: b-plugin-1.0.0-1.noarch Complete! In other words, I expect the transaction phase of the original (a-plugin-1.0.0-1) to be still invoked, and the transaction a1: install_set {<hawkey.Package object id 46306, b-plugin-1.0.0-1.noarch, @commandline>}, remove_set {<hawkey.Package object id 6, a-plugin-1.0.0-1.noarch, @System>} output to be shown. Additional info:
I would like to resolve the issue by enhancing a documentation. Please do you have any suggestion where to put such information?
I'd likely put it to the dnf plugin API documentation, as a note about behaviour expectations.
I added a note for the transaction hook into documentation: https://github.com/rpm-software-management/dnf/pull/1435
Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory, and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. https://access.redhat.com/errata/RHSA-2019:3583