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