Broken APT -- how to fix this?

Colin Watson cjwatson at ubuntu.com
Sun Dec 4 17:52:45 UTC 2022


On Sun, Dec 04, 2022 at 03:03:10PM +0100, Ralf Mardorf via ubuntu-users wrote:
> On Sun, 2022-12-04 at 13:33 +0000, Colin Watson wrote:
> > Perhaps; there are various reasons why files might have been moved
> > between packages, not all of which involve completely renaming a
> > package.
> 
> Hi,
> 
> what's your point? "I'm afraid this is nonsense", since the package with
> the files has got a different name, in this case there is no other
> reason. In this case the many packages marked for removal were evidently
> replaced by a few packages with different names.
> 
> I might be mistaken, but this at least is the most reasonable
> explanation. Take a look at the original posted log.

Quoting that log:

  Preparing to unpack .../mxe-x86-64-pc-linux-gnu-mxe-conf_1-bionic-build-2021-01-10_amd64.deb ...
  Unpacking mxe-x86-64-pc-linux-gnu-mxe-conf (1-bionic-build-2021-01-10) ...
  dpkg: error processing archive /var/cache/apt/archives/mxe-x86-64-pc-linux-gnu-mxe-conf_1-bionic-build-2021-01-10_amd64.deb (--unpack):
   trying to overwrite '/usr/lib/mxe/usr/bin/config.guess', which is also in package mxe-x86-64-unknown-linux-gnu-mxe-conf 1-20170208
  Preparing to unpack .../mxe-x86-64-pc-linux-gnu-cmake-conf_1-bionic-build-2021-01-10_amd64.deb ...
  Unpacking mxe-x86-64-pc-linux-gnu-cmake-conf (1-bionic-build-2021-01-10) ...
  dpkg: error processing archive /var/cache/apt/archives/mxe-x86-64-pc-linux-gnu-cmake-conf_1-bionic-build-2021-01-10_amd64.deb (--unpack):
   trying to overwrite '/usr/lib/mxe/usr/share/cmake/modules/FindFreetype.cmake', which is also in package mxe-x86-64-unknown-linux-gnu-mxe-conf 1-20170208

This unambiguously tells us that it is not just as simple as a renamed
package.  Files that were previously in a single package
(mxe-x86-64-unknown-linux-gnu-mxe-conf) are now distributed between at
least two packages (mxe-x86-64-pc-linux-gnu-mxe-conf and
mxe-x86-64-pc-linux-gnu-cmake-conf).  It therefore can't be the case
that mxe-x86-64-unknown-linux-gnu-mxe-conf was simply renamed, nor even
just a case of consolidating many packages into fewer packages; if
anything, it looks like a package may have been split up.

The list of proposed autoremovals further up the log is mildly
suggestive, but not directly relevant to the actual error, since there
are likely to be a number of other mxe-x86-64-* packages that are in an
installed state and so aren't shown in this log of an attempt to fix
broken packages.  While the log doesn't contain enough information to
say for sure exactly what the full set of packages involves, one
interesting aspect of it is that there's no *-cmake-conf package among
the proposed autoremovals (as opposed to *-cmake and *-mxe-conf),
further suggesting that there may have been some kind of package split
going on here.

> > > To work around such a dependency cycle, the maintainers of the third
> > > party repository probably should have used transitional packages.
> > 
> > I'm afraid this is nonsense.  Transitional packages are of no help for
> > moving files between packages; the correct solution normally involves
> > the Replaces field.
> 
> Your tone of voice is inappropriate. A dummy package, what ever you call
> it, could work around such a dependency cycle. It's not that unlikely,
> that the replace field is the reason for the issue.

Dependency cycles are cases where package A depends on B and B also
depends on A.  No such situation is evident in the posted log; even if
there were such a situation, transitional packages by definition only
add dependencies, so they can't normally help with that.  (Side note:
dpkg can break certain dependency cycles, so they aren't always errors.
There are some in the Ubuntu base system.)

The problem of handling files that move from one package to another is
not a problem that transitional packages are capable of solving.  The
way to communicate to dpkg that it should not raise an error when a
package attempts to install a file that is currently on the system owned
by another package is to use the Replaces field, usually in conjunction
with Breaks or Conflicts depending on whether individual files are being
moved (as appears to be the case here) or whether an entire other
package should be removed.  See section 7.6 of the Debian Policy Manual:

  https://www.debian.org/doc/debian-policy/ch-relationships.html#overwriting-files-and-replacing-packages-replaces

Also see section 7.4 on details of Breaks vs. Conflicts:

  https://www.debian.org/doc/debian-policy/ch-relationships.html#conflicting-binary-packages-conflicts

The package maintainer will have more context on exactly what happened,
but based on the log it looks like a Breaks+Replaces situation to me.

Transitional or dummy packages (packages that contain only dependencies,
and no files except minimal requirements such as a changelog) do help
with some issues related to full package renames: a common pattern is
for the old package to become a transitional package that Depends on the
new package, and the new package would normally declare Breaks+Replaces
on versions of the old package prior to the renaming.  However,
attempting to use a transitional package without also using the Replaces
field will cause an error similar to the one at the start of this thread
if the new package shares any file names in common with the old package,
as it often will.

Renaming a package doesn't always have to involve a transitional
package.  If you have a package that's essentially only ever installed
due to dependencies (perhaps it's a library of some kind), then it can
be appropriate to just use Conflicts+Replaces+Provides in the new
package name to cause the old package to be removed, and rely on updated
dependencies elsewhere to cause the new package to be installed.  Or, if
the old and new package names don't share any files, then you may be
able to simply update dependencies on the renamed package and rename it
without Replaces; this is the common case for runtime library packages
(libfoo1 → libfoo2 or similar), since in those cases the package rename
is normally accompanied by all the file names changing at the same time.

In any event, the function of the transitional package is not to
suppress file-overwrite errors from dpkg, but rather to cause the new
package to be installed when the packaging system might not otherwise
know that it needs to do so.  That's not the problem here: apt already
attempted to install the new packages, but its attempt failed.  The
correct solution will involve Replaces.

-- 
Colin Watson (he/him)                              [cjwatson at ubuntu.com]



More information about the ubuntu-users mailing list