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?