Detecting ebuild upgrades in Gentoo
I’ve recently been writing Gentoo ebuilds (interestingly enough, not being a Gentoo user myself) and faced the follwing problem: “How to distinguish between a package upgrade and a package removal from within the package?”
Gentoo has only a standard set of “hooks” that get called during package installation (related to install and uninstall, but not to upgade). The upgrade stage P1 -> P2 is performed as follows:
- P2.configure/compile/install
- P1.prerm()
- remove files from P1 that are not in P2
- P1.postrm()
This works fine for simple file replacement tasks, which are handled automatically. However, there are situations where you want something more sophisticated:
- preinst/postinst: configure the system to use the package (services, system variables, etc).
- prerm/postrm: remove the remnants of system configuration when the package is deleted.
For this to work, package P1 needs to know if it’s being upgraded and removed (no system conf. needed). Simiarly, P2 needs to know if P1 exists and the system has already been configured (so that the configuration is not removed on update). To make things even more difficult, a package can be upgraded, downgraded or reinstalled (for reinstall rm not called). After a bit of experimenting and scratching my head, here’s what I came up with:
#detecting upgrades while installing
pkg_preinst () {
has_version "<${PF}" && UPGRADE=1 || UPGRADE=0
has_version ">${PF}" && DOWNGRADE=1 || DOWNGRADE=0
has_version "=${PF}" && REINSTALL=1 || REINSTALL=0
#now in the preinst or postinst code we can
#perform different actions depending on the variables set
}
#detecting upgrades while removing
pkg_prerm () {
has_version ">${PF}" && UPGRADE=1 || UPGRADE=0
has_version "<${PF}" && DOWNGRADE=1 || DOWNGRADE=0
[ -n -${A} ] && REINSTALL=1 || REINSTALL=0
#perform different actions depending on the variables set
#(either here or in posrm - the variables have to be be set right here
}
I wonder whether there’s abetter solution to this problem?
November 19th, 2005 at 1:44 am
Interesting technique! In RPM-land, the {pre,post}{install,remove} scripts are called with an argument that indicates how many copies of the current package there will be after the current operation is complete. So by checking this number, the script can know if it’s a first-time install, an upgrade, or a complete removal. I wonder if something like this is kept internally by Portage, and if it can be accessed from the ebuild.
November 20th, 2005 at 2:27 pm
It’s a hack, but it works. I agree that Portage probably knows what it is doing and it would be nice to access it from ebuilds. However it looks that Portage is not willing to share this information with others: - The docummentation does not discuss this issue. - There are no parameters passed to these functions (checked: preinst and postrm). - I diff-ed variables exported in both situations (clean install vs. reinstall) and (remove vs. upgrade) and there was absolutely no difference.
November 20th, 2005 at 2:50 pm
[...] Tadek’s Blog Some random notes about computers, security, cool links and others. « Detecting ebuild upgrades in Gentoo [...]