Bug#880920: RFC: Support for selective usage of (fake)root during package build (R³)
Niels Thykier:
>
> Sean Whitton:
>> Hello,
>>
>> On Sun, Jan 21 2018, Guillem Jover wrote:
>>
>>> Ok, there were some comments provided, and some important omissions
>>> were spotted. I'm attaching the diff for those changes, which mark now
>>> the spec as a stable recommendation with 1.19.0.5.
>>
>> Sounds like this invalidates Niels' patch against Policy?
>>
>
> Indeed, my patch will require some editorial changes.
>
> Thanks,
> ~Niels
>
>
Hi,
Attached is my updated draft along with a changes since the previous draft.
Please CC me on remarks/request for changes: I nearly missed the
comments about making it explicit that "gain root command" should
preserve the environment variables.
Thanks,
~Niels
>From 1ef3ac1141c08361f4e2da81b9a0994ade411ff9 Mon Sep 17 00:00:00 2001
From: Niels Thykier <niels@thykier.net>
Date: Fri, 29 Dec 2017 11:28:08 +0000
Subject: [PATCH] Initial draft for Rules-Requires-Root
Signed-off-by: Niels Thykier <niels@thykier.net>
---
policy/ch-controlfields.rst | 110 ++++++++++++++++++++++++++++++++++++++++++++
policy/ch-source.rst | 53 ++++++++++++++++++++-
2 files changed, 162 insertions(+), 1 deletion(-)
diff --git a/policy/ch-controlfields.rst b/policy/ch-controlfields.rst
index 0771346..7fc9216 100644
--- a/policy/ch-controlfields.rst
+++ b/policy/ch-controlfields.rst
@@ -129,6 +129,8 @@ package) are:
- :ref:`Testsuite <s-f-Testsuite>`
+- :ref:`Rules-Requires-Root <s-f-Rules-Requires-Root>`
+
The fields in the binary package paragraphs are:
- :ref:`Package <s-f-Package>` (mandatory)
@@ -1020,6 +1022,114 @@ This field is automatically added to Debian source control files
field may also be used in source package control files
(``debian/control``) if needed in other situations.
+.. _s-f-Rules-Requires-Root:
+
+``Rules-Requires-Root``
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Simple field that defines if the source package requires access to
+root (or fakeroot) during selected targets in the :ref:`Main building
+script: debian/rules <s-debianrules>`.
+
+The field can consist of exactly one of either of the following:
+
+ - ``no``: Declares that neither root nor fakeroot is required.
+ Package builders (e.g. dpkg-buildpackage) may choose to invoke any
+ target in ``debian/rules`` with an unprivileged user.
+
+ - ``binary-targets`` (default): Declares that the package will need
+ the root (or fakeroot) when either of the ``binary``,
+ ``binary-arch`` or ``binary-indep`` targets are called. This is
+ how every tool behaved before this field was defined.
+
+ - A space separated list of keywords described below. These must
+ always contain a forward slash, which sets them apart from the
+ other values. When this list is provided, the builder must provide
+ a `gain root command` (as defined in :ref:`debian/rules - Gain root
+ api for Rules-Requires-Root <s-debianrules-gainrootapi>`) *or*
+ pretend that the value was set to ``binary-targets`` and both
+ parties must degrade accordingly (see below).
+
+If the package builder supports the field and want to enable the
+feature, then it must set the environment variable
+``DEB_RULES_REQUIRES_ROOT`` when invoking the package building script
+``debian/rules``. The value of ``DEB_RULES_REQUIRES_ROOT`` should be
+one of:
+
+ * The same value as the ``Rules-Requires-Root`` if the builder can
+ provide the necessary support. The builder may trim unnecessary
+ whitespace used to format the field for readability.
+
+ * The value ``binary-targets`` if it cannot provide the necessary
+ support.
+
+All packages and builders must support ``binary-targets`` as this was
+the historical behaviour prior to the introduction of this field.
+
+Please note that any tool (partiularly older versions of them) may be
+unaware of this field and behave like the field was set to
+``binary-targets``. The package build must gracefully cope with this
+and produce the same semantical result regardless.
+
+A compliant builder may also leave ``DEB_RULES_REQUIRES_ROOT`` unset
+or set it to ``binary-targets`` if it has been requested to test
+whether the package it builds correctly implements the fall-back for
+legacy builders.
+
+This field intentionally does not enable a package to request a true
+root over fakeroot.
+
+**Definition of the keywords**:
+
+The keywords have the format ``<namespace>/<case>``, where:
+
+ * ``<namespace>`` must consist entirely of printable ASCII characters
+ except for any whitespace and the forward slash (``/``). It must
+ consist of at least 2 characters.
+
+ * ``/`` (between ``<namespace>`` and ``<case>``) is a single ASCII
+ forward slash.
+
+ * ``<case>`` must consist entirely of printable ASCII characters
+ except for any whitespace. It must consist of at least 2
+ characters.
+
+These keywords define where the package build script (or the tools
+called from it) will need access to root or fakeroot. If ``debian/rules``
+directly needs to invoke a tool as root or under fakeroot, then it must
+use the keyword ``dpkg/target-subcommand``.
+
+Furthermore, each tool or package may claim its own namespace named
+after it and create keywords based on that namespace. The tool may
+use the `gain root command` to perform a given action as root or under
+fakeroot if (but only if) a package lists of said keyword in the
+``Rules-Requires-Root`` field.
+
+All tools must ignore keywords with namespaces they do not know or
+own. A tool may choose warn or abort with an error if it finds
+unknown keywords in namespaces it provides or owns (but it is not
+required to do this for all keywords in the namespace).
+
+
+**Provided keywords**:
+
+The following incomplete list of keywords are defined:
+
+ * ``dpkg/target-subcommand``: When the package needs to run a given
+ command under (fake)root within the ``debian/rules`` files
+ directly, this must be declared via this keyword.
+
+ * ``dpkg/target/<target-name>``: When a specific "debian/rules"
+ unofficial target (none of the root-requiring ``binary-indep``,
+ ``binary-arch``, ``binary``, ``clean``, nor the non-root-requiring
+ ``build-indep``, ``build-arch``, ``build``) needs to be run under
+ (fake)root, this must be declared via this dynamic keyword, where
+ ``<target-name>`` is the name of the ``debian/rules`` target.
+
+The policy is not intended to contain a complete list of these
+keywords. Please consult the documentation of the tool or package in
+question for which keywords it defines and when they are needed.
+
.. _s5.7:
User-defined fields
diff --git a/policy/ch-source.rst b/policy/ch-source.rst
index e3b1981..009716c 100644
--- a/policy/ch-source.rst
+++ b/policy/ch-source.rst
@@ -346,7 +346,9 @@ The targets are as follows:
architecture-dependent or not), it must still exist and must always
succeed.
- The ``binary`` targets must be invoked as root. [#]_
+ The ``binary`` targets may be invoked as root depending on the
+ value of the :ref:`Rules-Requires-Root <s-f-Rules-Requires-Root>`
+ field. [#]_
``clean`` (required)
This must undo any effects that the ``build`` and ``binary``
@@ -435,6 +437,12 @@ should not be used to get the CPU or system information; the
that. GNU style variables should generally only be used with upstream
build systems.
+The builder should set ``DEB_RULES_REQUIRES_ROOT`` environment
+variable when calling any of the mandatory targets as defined in
+:ref:`Rules-Requires-Root <s-f-Rules-Requires-Root>`. If the variable
+is not set, the package must behave as if it was set to
+``binary-targets``.
+
.. _s-debianrules-options:
``debian/rules`` and ``DEB_BUILD_OPTIONS``
@@ -525,6 +533,49 @@ order to make it work for your package.
# Code to run the package test suite.
endif
+
+.. _s-debianrules-gainrootapi:
+
+``debian/rules`` - Gain root api for ``Rules-Requires-Root``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Depending on the value of the :ref:`Rules-Requires-Root
+<s-f-Rules-Requires-Root>` field, the package builder
+(e.g. dpkg-buildpackage) may run the ``debian/rules`` target as an
+unprivileged user and provide a `gain root command`.
+
+The `gain root command` is passed to the build script via the
+``DEB_GAIN_ROOT_CMD`` environment variable. It is space separated
+list with the first word being the command (which should available be
+in PATH) and additional words being arguments. The `gain root
+command` might not be used via a shell and accordingly it must not
+rely on shell features.
+
+The `gain root command` must not prompt or require human interaction
+(as the build script itself must not require interaction). The `gain
+root command` must be possible to preprend the command to an existing
+command without having to alter or quote the command being invoked.
+Furthermore, it must retain the environment variables without the
+caller having to explicitly request it.
+
+The following are examples of valid defitions root commands (in the sh
+syntax) provided the tools are available and properly configured::
+
+ # Command "sudo", with arguments "-nE" and "--"
+ export DEB_GAIN_ROOT_CMD='sudo -nE --'
+ # Command "fakeroot" with the single argument "--"
+ export DEB_GAIN_ROOT_CMD='fakeroot --'
+
+Examples of valid use of the `gain root command`::
+
+ # sh-syntax (assumes set -e semantics for error handling)
+ $DEB_GAIN_ROOT_CMD some-cmd --which-requires-root
+
+ # perl
+ my @cmd = ('some-cmd', '--which-requires-root');
+ unshift(@cmd, split(' ', $ENV{DEB_GAIN_ROOT_CMD})) if $ENV{DEB_GAIN_ROOT_CMD};
+ system(@cmd) == or die("@cmd failed");
+
.. _s-substvars:
Variable substitutions: ``debian/substvars``
--
2.16.1
diff --git a/policy/ch-controlfields.rst b/policy/ch-controlfields.rst
index 5310813..7fc9216 100644
--- a/policy/ch-controlfields.rst
+++ b/policy/ch-controlfields.rst
@@ -1050,11 +1050,31 @@ The field can consist of exactly one of either of the following:
pretend that the value was set to ``binary-targets`` and both
parties must degrade accordingly (see below).
+If the package builder supports the field and want to enable the
+feature, then it must set the environment variable
+``DEB_RULES_REQUIRES_ROOT`` when invoking the package building script
+``debian/rules``. The value of ``DEB_RULES_REQUIRES_ROOT`` should be
+one of:
+
+ * The same value as the ``Rules-Requires-Root`` if the builder can
+ provide the necessary support. The builder may trim unnecessary
+ whitespace used to format the field for readability.
+
+ * The value ``binary-targets`` if it cannot provide the necessary
+ support.
+
+All packages and builders must support ``binary-targets`` as this was
+the historical behaviour prior to the introduction of this field.
+
Please note that any tool (partiularly older versions of them) may be
unaware of this field and behave like the field was set to
``binary-targets``. The package build must gracefully cope with this
-and produce the same semantical result regardless. The value of this
-field must not degrade if a builder tool invokes the package build
+and produce the same semantical result regardless.
+
+A compliant builder may also leave ``DEB_RULES_REQUIRES_ROOT`` unset
+or set it to ``binary-targets`` if it has been requested to test
+whether the package it builds correctly implements the fall-back for
+legacy builders.
This field intentionally does not enable a package to request a true
root over fakeroot.
@@ -1088,7 +1108,7 @@ fakeroot if (but only if) a package lists of said keyword in the
All tools must ignore keywords with namespaces they do not know or
own. A tool may choose warn or abort with an error if it finds
unknown keywords in namespaces it provides or owns (but it is not
-required to this for all keywords in the namespace).
+required to do this for all keywords in the namespace).
**Provided keywords**:
diff --git a/policy/ch-source.rst b/policy/ch-source.rst
index 21e10f3..009716c 100644
--- a/policy/ch-source.rst
+++ b/policy/ch-source.rst
@@ -437,6 +437,12 @@ should not be used to get the CPU or system information; the
that. GNU style variables should generally only be used with upstream
build systems.
+The builder should set ``DEB_RULES_REQUIRES_ROOT`` environment
+variable when calling any of the mandatory targets as defined in
+:ref:`Rules-Requires-Root <s-f-Rules-Requires-Root>`. If the variable
+is not set, the package must behave as if it was set to
+``binary-targets``.
+
.. _s-debianrules-options:
``debian/rules`` and ``DEB_BUILD_OPTIONS``
@@ -539,34 +545,35 @@ Depending on the value of the :ref:`Rules-Requires-Root
unprivileged user and provide a `gain root command`.
The `gain root command` is passed to the build script via the
-``DPKG_GAIN_ROOT_CMD`` environment variable. It is space separated
+``DEB_GAIN_ROOT_CMD`` environment variable. It is space separated
list with the first word being the command (which should available be
in PATH) and additional words being arguments. The `gain root
-command` may not be used via a shell and accordingly it must not rely
-on shell features.
+command` might not be used via a shell and accordingly it must not
+rely on shell features.
The `gain root command` must not prompt or require human interaction
-(as the build script itself must not require interaction).
-Furthermore, it must be possible to preprend the command to an
-existing command without having to alter or quote the command being
-invoked.
+(as the build script itself must not require interaction). The `gain
+root command` must be possible to preprend the command to an existing
+command without having to alter or quote the command being invoked.
+Furthermore, it must retain the environment variables without the
+caller having to explicitly request it.
The following are examples of valid defitions root commands (in the sh
syntax) provided the tools are available and properly configured::
# Command "sudo", with arguments "-nE" and "--"
- export DPKG_GAIN_ROOT_CMD='sudo -nE --'
+ export DEB_GAIN_ROOT_CMD='sudo -nE --'
# Command "fakeroot" with the single argument "--"
- export DPKG_GAIN_ROOT_CMD='fakeroot --'
+ export DEB_GAIN_ROOT_CMD='fakeroot --'
Examples of valid use of the `gain root command`::
# sh-syntax (assumes set -e semantics for error handling)
- $DPKG_GAIN_ROOT_CMD some-cmd --which-requires-root
+ $DEB_GAIN_ROOT_CMD some-cmd --which-requires-root
# perl
my @cmd = ('some-cmd', '--which-requires-root');
- unshift(@cmd, split(' ', $ENV{DPKG_GAIN_ROOT_CMD})) if $ENV{DPKG_GAIN_ROOT_CMD};
+ unshift(@cmd, split(' ', $ENV{DEB_GAIN_ROOT_CMD})) if $ENV{DEB_GAIN_ROOT_CMD};
system(@cmd) == or die("@cmd failed");
.. _s-substvars:
Reply to: