Forcing intentional deb package dependency resolution
Sam Varshavchik
mrsam at courier-mta.com
Fri Dec 29 03:56:42 UTC 2023
I'm building a set of deb packages, and I'm trying to have an update fail if
newer versions of these packages were not built with a configuration that
matches the existing packages' configuration. This is a failsafe, a sanity
check.
I was able to implement the analogous logic with rpm packages on Fedora, but
with equivalent deb dependency resolution "apt update" is too smart for its
britches and figures out how to avoid the intended dependency resolution
failure by removing the conflicting package. And I don't want that, I want
the dependency resolution to fail.
First, some colorful background: the packages in question can be configured
to use reserved user and group ids as the owners of various installed files.
What I'm trying to do is prevent an update unless the newer version of the
packages was configured identically. What I accomplished with rpm packages,
which works, was like this:
The main package is named "libcourier-auth" and it declares a dependency,
the .deb equivalent of "Depends" on a libcourier-auth-config-${user}-${group}
package. In so many words:
Depends: libcourier-auth-config-$mailuser-$mailgroup
And the subpackage declares a virtual conflicting dependency with a fixed
name:
Provides: libcourier-auth-uidgid
Conflicts: libcourier-auth-uidgid
This approach works with .rpm packages. If the currently installed packages
are "libcourier-auth" and, say, "libcourier-auth-config-daemon-daemon", and
the newer set of packages are "libcourier-auth" and "libcourier-auth-config-
daemon-bin", then:
1. The newer "libcourier-auth" package results in an attempt to uninstall
the older one.
2. The newer "libcourier-auth-daemon-bin" package is considered to be
different than the existing "libcourier-auth-daemon-daemon", and the
existing package does not get slated for uninstallation, and the whole
operation fails due to the conflicting dependencies.
If I translate the dependencies to .deb packaging, "apt upgrade" does not
fall into the carefully-laud trap and abort the update. It figures out it
can manually uninstall the existing config package, and fix the dependency
issue.
Specifically: in my control file I have:
Package: libcourier-auth
Depends: libcourier-auth-config-%MAILUSER%-%MAILGROUP%
Package: libcourier-auth-config-%MAILUSER%-%MAILGROUP%
Provides: libcourier-auth-uidgid
Conflicts: libcourier-auth-uidgid
The %MAILUSER% and %MAILGROUP% placeholders get replaced by my build scripts
with the actual user/group ids configured during building. So, if the
package was configured with a different user or group the resulting
subpackage name is different.
So, if:
1. I currently have "libcourier-auth" and "libcourier-auth-daemon-daemon"
installed, and have "libcourier-auth" and "libcourier-auth-daemon-bin"
packages, with a newer version on them, standing by, then:
2. The "apt upgrade libcourier-auth" ends up doing this:
The following packages will be REMOVED:
libcourier-auth-config-daemon-daemon
The following NEW packages will be installed:
libcourier-auth-config-daemon-bin
The following packages will be upgraded:
libcourier-auth libcourier-auth-dev libcourier-auth0
I don't want this. I want an attempted update to fail dependency resolution
and not even have anything unpacked. How can I fiddle the dependencies to
force a dependency resolution failure in this situation?
The best I could do was to replace Provides/Conflicts with a file in the
config subpackage. dpkg then detects an attempt to install a package with a
file that's also owned by an existing package. This is not ideal, the
conflict gets detected too late. The dependency resolution appears to
succeed, only to result in a conflict after unpacking the new package. rpm
could detect this conflict when resolving dependencies, and abort the entire
install.
More information about the ubuntu-users
mailing list