Hi!

On Sun, 2025-01-05 at 22:47:31 +0000, Ian Jackson wrote:
> Package: dpkg
> Version: 1.22.13
> Control: block 1092190 by -1

As a heads up, please read my reply more as an exploratory one with
a pinch of push back, instead of a directed vector to a wontfix kind
of thing, as I'd like to understand exactly how you see this being
problematic, in case we missed some stuff, and also because this feels
like adding support for new stuff that is immediately intended to
start a deprecation cycle to get rid of it in N release cycles. Because
in the end the whole exercise here is to try to eventually be able to
fully get rid of the need for fakeroot in our tooling stack (which we
cannot fully do even now, but we are going in that direction).

> It seems likely to me that there will continue to be packages in the
> wild which this behavioural change will break - particularly including
> packages not part of Debian, packages from old Debian release, and
> perhaps whole derivative distros.

I've actually been reluctant to perform this default switch in the past
for two main reasons, one was the amount of potential breakage (silent
or aborting) in the archive (where we have ways to easily detect silent
breakage), and the other was for the unknown potential silent breakage
in out of archive packages (potential aborting breakage should be part
of the deal when updating the toolchain IMO).

Given that the archive was in a quite manageable state, and Niels
provided actual numbers, my remaining concern was about out of
archive silent breakage. We went over the potential cases that could
affect these packages, where the packaging uses dpkg-buildpackage to
build, but does not use a helper like debhelper (which handle rootless
builds automatically), and might do the equivalent of:

  1) chown fails w/ checked exit code, aborts
  2) chown fails w/o abort, silent breakage

In here chmod (say to set-user-ID) does not matter because the chown
success or failure always wins.

So for the problematic case 2), which are packages not using a helper
that would transparently support rootless builds, and would thus end
up with non-root owned paths, for which Niels proposed a fatal check
in dpkg-deb for "normal users" (unless run with --root-owner-group),
which had a feel as a good general approach but was potentially
problematic in two fronts. One with the check itself as that would
require cooking vendor specific user/group policies, which would break
with foreign builds, as dpkg-deb is really a cross tool, and the other
with the checks being fatal, as that might potentially get in the way
of legitimate usages of the tool. After pondering about this I thought
that warning in dpkg-deb if the build root directory was not root owned
was a portable compromise solution that gives us the properties we are
looking for, which would still turn the category 2) problem above into
a non-silent one. (This is implemented in dpkg-deb 1.22.13.) I could
also see turning the warning into an error (and adding a
--no-check-fsys or similar to disable it) to not let any non-aborting
breakage through, if the warning alone is still considered too risky.


Said that. It's true that packages can of course still break (either
with an abort, or with a dpkg-deb warning), but an extremely quick and
backwards compatible way to unbreak them would be to add an
«Rules-Requires-Root: binary-targets», which should do the right thing
even with old dpkg-dev tools that do not understand it (as then it would
be the default).

Note that when we designed the R³ interfaces and behavior we took care
of defining them so that new packages declaring these interfaces,
after having been adapted, should still work with old tooling.

> In order to allow us to build old packages with new tooling, or
> out-of-distro packages, or whatever, I think dpkg-buildpackage should
> have a way to request the previous (bookworm-and-earlier) behaviour.

This is the part I'd like to apply this slight push back. :) I don't
think we can guarantee to build old packages with new tooling,
otherwise we could not make progress. We do change language toolchains
which break old stuff, change default flags, do ABI transitions like
the time64 one, etc. Out of archive packages need to update the
packaging to new standards too, new lintian errors, new more strict
syntax checks, etc., when switching Debian release or upgrading the
tooling they use.

While I agree it's important to have ways to back off from a change,
to ease with such transitions, in this case we have provided that
already from the beginning. And what matters most is not failing
silently.

> I looked through the manpage and found --rules-requires-root, but that
> says that it disregards the Rules-Requires-Root field entirely, which
> isn't right.  (And might also break things...)

It's certainly not ideal, as it would run things under say fakeroot
that would otherwise not need to, but it should be always safe, and
it was designed and intended to be able to build any new package,
including the ones that have explicitly opted out of root builds
(otherwise I'd consider that a bug in the package).

I thought I could propose for dgit to use only this option if
«dpkg-buildtree is-rootless» returned failure, but that program was
only introduced in the 1.22.x series which would not be of much help.

Another option for dgit, could be to check whether the package
contains «Rules-Requires-Root: no» (because dpkg-build-api(7) being
the other factor influencing the default value, was also only
introduced in 1.22.x, so it would not affect older releases), but
perhaps combining this with the previous «is-rootless» and then using
--rules-requires-root conditional on these would be a viable
alternative.

> Could we please have a command line option to just change the default,
> so that trixie's dpkg-buildpackage can be used in circumstances where
> bookworm's would have worked ?
> 
> We should probably consider whether we want to make this behaviour
> controllable by an environment variable, as well.  That way a program
> which is trying to work with various different dpkg-buildpackage
> version (eg a CI job that runs with different images) wouldn't have to
> probe for the option.

As mentioned at the beginning I'm not outright opposed to adding such
option or environment variable. But TBH I'd like to avoid it if
possible, because to me it looks deprecated on arrival, and in need
of an immediate (long-winded) transition to remove it, when external
packages should be getting switched to use rootless builds. And
because I guess I don't understand/see the scenario where old packages
are being used with new tooling, and where the easy scape hatch of
adding the field with the old behavior value is not a viable solution.

I was going to say I don't think I understand how this interacts badly
with dgit, but from your thread with Niels, it looks like dgit might
need to be changed anyway if it's doing tests based on incorrect
assumptions, so this part is probably not very relevant anymore?

Thanks,
Guillem

Reply via email to