Hi Raphaël, On Wed, May 03, 2023 at 10:31:14AM +0200, Raphael Hertzog wrote: > I don't know APT well enough to answer that question but from my point of > view it's perfectly acceptable to document in the release notes that you > need to upgrade dpkg first.
Yes, this issue seems vaguely solvable one way or another. It also affects other approaches modifying dpkg in the very same way. > Are you sure that we need anything for diversions except some documented > policy on how to deal with it? Yes! There is a hard ordering constraint involved here. Failure to do so results in unpack errors and or file loss in much the same way. > AFAIK the following sequence performs no filesystem changes and should > be sufficient to move a diversion to its new location (I only consider the > case of an upgrade, not of a new installation that should just work > "normally" on the new location): > > dpkg-divert --package $package --remove /bin/foo --no-rename > dpkg-divert --package $package --add /usr/bin/foo --divert > /usr/bin/foo.diverted --no-rename This is insufficient. Either we modify dpkg to consider aliasing when managing diversions (i.e. Simon Richter's branch or DEP17) or there is a more complex ordering requirement involved: * We must not remove the aliased diversion (/bin/foo) before the diverted package has moved its files to the canonical location (/bin/foo -> /usr/bin/foo). * We must add the canonical diversion (/usr/bin/foo) before the diverted package update that moves its files to canonical locations can be unpacked. Say we currently have Package: diverter Version: 1 Files: /bin/foo preinst: diverts /bin/foo Package: diverted Version: 1 Files: /bin/foo We must first update the diverter. Package: diverter Version: 2 Files: /usr/bin/foo preinst: diverts both /bin/foo and /usr/bin/foo Since we divert both locations, diverter can now deal with an old diverted and a canonicalized diverted. Package: diverted Version: 2 Conflicts: diverter (<< 2~) Files: /usr/bin/foo At the time of unpacking the updated diverted, we must ensure that no diverter versioned 1 is unpacked. Breaks does not help here as it allows concurrent unpacks. Neither does Replaces since dpkg thinks that /bin/foo is different from /usr/bin/foo and thus no replacing happens. Package: diverter Version: 3 Conflicts: diverted (<< 2~) Files: /usr/bin/foo preinst: diverts /usr/bin/foo When unpacking the updated diverter, we must ensure that no diverted version 1 is unpacked. Again, Breaks and Replaces does not suffice. Therefore an upgrade from stable to nextstable containing both diverter and diverted must temporarily remove either package, which is known to annoy apt. What still applies here is that we can have usr-is-merged divert /usr/bin/dpkg-divert and have it automatically duplicate any possibly aliased diversion and then the diverter may Pre-Depends: usr-is-merged (>=...) to have its diversions duplicated. Of course, doing so will make usr-is-merged very hard to remove, but we have experience here from multiarch-support. Hope this clarifies. > The case of update-alternatives is likely more tricky. You already looked > into it. That's a place where it will be harder to get things right > without some changes. As detailed in https://lists.debian.org/debian-devel/2023/04/msg00169.html I believe that update-alternatives really are not tricky at all as long as we do not attempt to migrate them to canonical paths in any way. For instance, elvis-tiny needs to continue to name the editor alternative /bin/elvis-tiny even when it actually moves that file to /usr/bin. The reason that this does not hurt is that we never attempted to move alternatives (unlike regular files in packages). If we really want to migrate alternatives to canonical paths, we do get into the tricky area of preserving the user configuration and we also break custom scripts, ansible's community.general.alternatives, uses of puppet's alternatives modules and probably a lot more. And of course, we can always draw the diversion card and have usr-is-merged divert /usr/bin/update-alternatives to have it canonicalize paths as required to be able to migrate alternatives in a sane way (from a consumer point of view). Helmut