#1092193 option (or env) to request <=bookworm r-r-r behaviour

Package:
dpkg
Source:
dpkg
Description:
Debian package management system
Submitter:
Ian Jackson
Date:
2025-03-07 21:33:02 UTC
Severity:
normal
#1092193#5
Date:
2025-01-05 22:47:31 UTC
From:
To:
Hi.

(Firstly, I should say thank you very much to Niels Thykier for your
work on Rules-Requires-Root.  Tidying this up is a big job which
you've been doing very well.  Speaking personally I have really
appreciated the interactions I've had with you over my packages.
Now, though, I'm afraid I come with the change request:)

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.

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.

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...)

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.

I'm filing this bug as "normal" because I think that's warranted by
the behavioural regression for out-of-Debian users.

Thanks for your attention.

Ian.

#1092193#12
Date:
2025-01-06 02:15:41 UTC
From:
To:
Hi!

I've got a draft reply almost finished, but it's gotten too late and
need to sleep, and would need to go over it a few more times, and
recheck IRC backlogs, etc. Given that this is marked as blocking an
RC bug, just wanted to mention this to set expectations. I'll finish
that later tomorrow.

Thanks,
Guillem

#1092193#17
Date:
2025-01-06 08:13:31 UTC
From:
To:
Ian Jackson:

You are welcome. I appreciate your openness to the R³ changes.
Especially since I filed bugs for a couple of your packages prior to the
MBF to get the ball rolling.

This may have merit on its own. Though for the purpose of dgit's test
suite, I would like to challenge the rule-invocation-tracking bit from
#1092190 here:

The existing expectation from Debian packaging is that the package is
expected to recurse into the `build` target on its own as needed if you
call `binary` directly. Therefore, I think the rule-invocation-tracking
tests on its own is "buggy" (makes invalid assumptions) here.

The `dh` package even added support for self-recursing into explicit
`build` targets as a part of compat 9 align itself with expected
practices (I think it was https://bugs.debian.org/629139)

Therefore, I would like to approach this from what are these
rule-invocation-tracking test *expected* to validate and how are they
doing it?

I will leave this part to Guillem as the dpkg maintainer, since he will
be maintaining that feature.

Best regards,
Niels

#1092193#22
Date:
2025-01-06 12:20:25 UTC
From:
To:
Niels Thykier writes ("Re: Bug#1092193: option (or env) to request <=bookworm r-r-r behaviour"):

tl;dr: This consideration is indeed why I don't think the dgit test
 suite is a good motivation for the change I'm requesting in dpkg, and
 why I didn't make such a connection in the reasoning in my
 src:dpkg bug.

Longer answer:

Yes, I see your point.  However, what these particular tests are
trying to check is precisely which build targets get invoked by dgit's
own build subcommands.  Ie, it is testing the behaviour of build
tools: the way that dgit drives (say) pbuilder which then drives
dpkg-buildpackage.  I think an end-to-end test like this is probably
the best way to do that, even if it means updating the test cases
every decade or so :-).

Separately, though, I do think the compat option I am proposing for
dpkg-buildpackage makes sense for the reasons I've explained - ie, for
the benefit of old and out-of-Debian packages (ie for real packages,
not weird test packages like in dgit:tests/).  Without such an
option, we risk digging some users into a hole.

Given that, it seemed most sensible to have the conversation about
that first, since if that option is going to be provided it can be
conveniently (ab)used by src:dgit's tests.  If that option is not
going to be provided, I'm sure we can take another approach in the
tests.  In that case we'd unlink the two bugs.

To directly answer your question, here is what I wrote in the commit
message in 2015 (cfec91c99eff):

    Test suite: Provide tests which check that all our various build
    operations run the right targets as expected (ie, that we are
    massaging the arguments to dpkg-buildpackage, and suppressing our
    clean target, etc., correctly).

TBH I consider it unfortunate that dgit has all these build wrappers.
Debian really doesn't need more layers of build wrappers.  So I would
like to abolish them.  But the reasons which necessitate their
existence (which are a whole other topic) don't seem to be going away
soon.  It's possible that further along the git transition we'll be
able to clean this up but that's well beyond my planning horizon.

Thanks,
Ian.

#1092193#27
Date:
2025-01-06 15:05:58 UTC
From:
To:
Ian Jackson:

Indeed, I have no concerns about discussing the compat option on its own
merits. I do not really have a dog in that race since my sphere of
interest is primarily about packages aimed at Debian and I am not
maintaining the code affected (to be as frank as possible).

So I will leave that discussion between Guillem and you.

I am unsure if it is deliberately aimed at testing this praticular
implementation detail of dpkg calling d/rules build separately or not.
Like is there ever a case where dgit wants to call "build" without "binary"?

If it is deliberately testing dpkg calling d/rules build separately from
d/rules binary, then it is a question of test philosophy in dgit, which
I should step out of since I am not a dgit maintainer.

If it is not about that particular implementation details (but instead
ensuring clean is not run), then I think something like:

"""
build build-arch build-indep %:
	dh $@
"""

would be more robust in the test with only the d/rules of the test being
slightly more unsightly (example assumes debhelper compat 9+ semantics).

But again, if the test is also about doing implementation detail testing
of dpkg, then my proposal here is not helpful

Best regards,
Niels

#1092193#32
Date:
2025-01-07 04:14:47 UTC
From:
To:
Hi!

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).

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.

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.

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.

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

#1092193#37
Date:
2025-01-07 10:23:12 UTC
From:
To:
Guillem Jover writes ("Re: Bug#1092193: option (or env) to request <=bookworm r-r-r behaviour"):

Thanks for the attention.  I'm going to reply in the same spirit.

I want to emphasise that I am trying to persaude you not because this
issue is in any way a problem for me or for src;dgit.  Sean and I can
do something else in our tests.

I'm trying to persuade you for the benefit of our users - distant
users, whom I feel we have a moral obligation to.  Really, *your*
useres (some of whom may be using my software too, but that's wholly
irrelevant since there isn't any meaningful interaction).

So if you decide not to provide this option, I will be *sad* for our
users, but I won't be *inconvenienced*.  I'm having this conversation
for distant users' benefit, not mine.

Also, I think you're missing a category of possible failure modes.
With "Rules-Requires-Root: no", the "build*" target(s) are skipped.
Packages *ought* to cope with this, so that "binary*" does the work.
But packages that aren't using the dh sequencer can easily have such
bugs.

One piece of background that is heavily influencing my thinking is:

It is easy, when working within Debian, to radically overestimate the
likely quality of non-Debian packages.  I have done some work with
packages in the rpi ecosystem (I'm thinking of packages *not* part of
Raspbian, which has source from Debian), and also other upstreams.
My experience is that packages written by people not steeped in Debian
culture, and that aren't subjected to Debian's various QA processes,
often only resemble normal Debian practices in the vaguest sense.

This is to be expected.  Debian packaging is complicated, and can be
weird.  People working outside Debian are just tryilng to get shit
done and don't have time to learn how to do it properly.  They hack
something together until it works.

As the upstream for the tools, I think we ought to be kind to those
users.  That means that when we break things (for good reasons, as
here) we provide escape hatches, compatibility modes, etc., so that
our downstreams can fix things on their schedule rather than ours.

That requires modifying the package.  That's probably fine if one is
doing ad-hoc work on one (perhaps old) package, which one expects to
modify anyway.  But there are many other scenarios.

Some downstreams and users will have their own build processes.
CI jobs, rebuild robots, and the like, which build packages
automatically.  In such a scenario, an option or env var to restore
compatibility with existing packages, without having to add a step to
the build to mess with the source package, will be very helpful.

When trying to work with old code (or a mix), it is often the best
approach to try to use the newest tooling where possible.  Normally,
tooling developers try to avoid breaking stuff.

(C and C++ compilers are indeed a notable exception.  But C/C++
compilers are nowadays rightly notorious for being absurdly
user-hostile.  We shouldn't follow their example.)

No, we don't promise it.  But IMO we ought to support it - at least,
unless it's a great deal of work, or has other problems.  The option I
propose is very simple, and I don't understand what the downside is.

(Unless, of course, the idea is to punish people for doing it wrong.
I mention this only because I've sadly seen, elsewhere, such hostile
attitudes, and I wanted to explicitly name a pathology that I think
we're all trying to avoid.)

I'm not sure what "way to back off" we have provided *to our
downstreams, working with out-of-Debian packages*.  As far as I can
tell, the first these people will know about it is broken builds.
(I'm assuming they're not following highly-technical Debian-internal
discussions.  And I don't think "modify all the packages" is a good
answer, at least, not on an enforced timescale.)

What?  Certainly I do not intend for dgit to pass this option.

That would be entirely crazy.

I *do* think that *if* we have this option in dpkg-buildpackage, it
might be a useful, if somewhat unprincipled, workaround *in the
specific test cases in dgit's test suite*.  Those test cases are very
pernickety and, by their nature, rather fragile.  But, it would be
almost as easy to just change the weird test package.

So, in summary, please disregard the question of dgit when considering
this dpkg-buildpackage change request.  dgit is not going to pass this
option.  We may abuse it in a few (bizarre) test cases, but that's it.

I think the dgit test suite situation is a red herring for this
discussion.  The dgit test suite failure is why I looked at how
dpkg-buildpackage was changing.

But, having looked at how dpkg-buildpackage was changing, I feel we
are at risk of doing a disservice to downstream users.  That is my
sole motivation here in this bug report.

It's particularly bad because those downstream users who will suffer
at the ones least able to cope with the problem.  They're the ones who
are most distant from Debian, with the least knowledge and the fewest
helpful social connections to Debian experts.  (They're already users
Debian sometimes supports rather poorly.)

Ideologically, I want *all* computer users everywhere to be able to
modify the way their computers behave.  My goal when working on Debian
is to help make that possible.  That includes users I don't know, and
it includes distant users who don't have all the relevant information
and skills and who may have done some broken stuff.  We should try to
make the software we supply easy and forgiving.

Certainly, we should make our software easy and forgiving when it
doesn't compromise the quality in other ways.

I hope this explains my thinking.

Regards,
Ian.

#1092193#42
Date:
2025-01-07 10:33:30 UTC
From:
To:
On Tue, Jan 07, 2025 at 10:23:12AM +0000, Ian Jackson wrote:
[..]

[..]

I'm sympathetic to keeping existing out-of-Debian packaging working,
but I just have to note two thoughts:

1) actual downstreams are used to dealing with changes in Debian all
the time.

2) users with CI jobs are, too. Depending on what their exact setup
is they'll already have noticed, or they pay the cost when changing
the distribution name in their config.

3) users that have neither and just hack something together won't
set a new environment variable that they will not hear of. Worse, at
some point this environment variable will go away again, and then
they had to do work twice.

Best,
Chris

#1092193#47
Date:
2025-01-07 10:56:07 UTC
From:
To:
Chris Hofstaedtler writes ("Re: Bug#1092193: option (or env) to request <=bookworm r-r-r behaviour"):

I find this argument very weak.  It basically amounts to "these people
are already used to us not being kind to them, so being kind to them
doesn't matter".  The premise is sadly maybe true much of the time,
but I don't hink the conclusion follows.

Once again, I really don't understand why there is any opposition to
my suggestion.  Adding an option like I suggest carries a tiny cost
for us, and a tiny cost for our users (just another option in the long
list in the dpkg-buildpackage manpage and usage message).

What is the downside?  Why is anyone even bothering to argue against
my suggestion?  I've explained my motivation.  We could have added
this option with a fraction of the effort spent on trying to argue
that it's not necessary.

Ian.

#1092193#52
Date:
2025-01-07 11:02:32 UTC
From:
To:
* Ian Jackson <ijackson@chiark.greenend.org.uk> [250107 11:56]:

It is cost to both dpkg _and_ to the users you are seeking to
protect, and to everyone else maintaining tools or just reading the
dpkg documentation in the future.
Users need to do work anyway, so we have not saved them anything.
If the option goes away in the future, they're paying the cost
twice!

As always it is a tradeoff of supporting the past vs. being able to
keep maintaining the software in question in the future.

I hope you understand my explanation above. My personal, global
motivation is to avoid adding noise and complexity into a world that
is already complicated enough.

Chris

#1092193#59
Date:
2025-01-12 18:23:05 UTC
From:
To:
In order to validate the changes, I want to be build the package
before-and-after.  But of course the package doesn't build "before" in
sid, because of this behavioural change in dpkg-buildpackage.

I am currently doing my validation with
  sbuild --debbuildopt=--rules-requires-root
which is tolerable.

But *really* what I ought to do is build it with a dpkg-buildpackage
with the old behaviour, because part of the rewrite is to add
Rules-Requires-Root: no, which means that `--rules-requires-root` is
wrong for the new package.

IOW with the old package I must pass --rules-requires-root or it
doesn't build. and with the new package I should not pass it because I
want to know what the normal build output looks like. [2]

Ie, I want the semantics of precisely the compatibility option I am
requesting in this bug.  This situation hardly seems unusual or
surprising to me.

Ian.

[1] chiark-utils, #1089303.  The rewrite is by Niels, prompted by
looking at the package pursuant to R-R-R.  This overhaul is long
overdue, so a very welcome contribution.

[2] Another option for me of course would be to do my before-and-after
build tests on trixie or bookworm.  But, again, that doesn't actually
validate precisely the things I want to check.

#1092193#64
Date:
2025-03-07 12:39:33 UTC
From:
To:
Niels Thykier asked me to send my opinion here.

1/ I agree with Ian concern about build packages that are not in testing unstable.
Providing working package building tools and alowing users to build their own
packages is an important part of what make Debian free software.

2/ I consider --rules-requires-root to be a sufficient work-around _provided_ it is clearly
documented in the release notes (and not just dpkg-dev NEWS) that this option
can be used when a package FTBFS due to a permission issue. Also the manpage
need to be updated, it currently says

#1092193#69
Date:
2025-03-07 12:52:57 UTC
From:
To:
This is not a good line of argumentation, because it cuts both ways:
According to that, the option --rules-requires-root should not have been
added, and we could argue that the best way to avoid noise and complexity
is to avoid breaking backward compatibility.

What we should not do, in any case, is to ignore the transition problem.

Cheers

#1092193#74
Date:
2025-03-07 15:57:42 UTC
From:
To:
Bill Allombert writes ("Re: Bug#1092193: option (or env) to request <=bookworm r-r-r behaviour"):

I agree that it should be documented.

I don't agree that it is a completely sufficient workaround.  It can
be used in the case of a single package.  But a downstream might have
have multiple packges.  Perhaps very many packages.

If some of those packages are from Debian bookwork or earlier, then
indeed some of them will not build unless --rules-requires-root is
passed.  But, always passing --rules-requires-root will probably break
*other* packages that were adapted to rootless builds a long time ago.

I haven't done any kind of survey of the prevalence of this problem.
I don't think that'd be proportionate.  An option that precixely
changes *just the default* would suffice.

Ian.

#1092193#79
Date:
2025-03-07 21:31:17 UTC
From:
To:
I did not anticipate that. Do you have an example of such breakage ?

This could be --rules-requires-root=default instead of a new option.

Cheers,