On Sun, 10 Sept 2023 at 11:31, Simon McVittie <s...@debian.org> wrote:
>
> On Sat, 09 Sep 2023 at 19:51:50 -0700, Russ Allbery wrote:
> > Luca, am I right that service directories are specific to, well, services?
> > If so, what would you think of moving them to Policy 9.3 alongside the
> > other discussion of systemd units?  They feel out of place here, since
> > packages that do not use services cannot use this functionality
>
> I'm not Luca, but I think you're correct here.

Moved as suggested. Also incorporated your suggestion on the versioned
virtual package dependency verbatim.

> > Luca Boccassi <bl...@debian.org> writes:
> > > +Packages might need additional files or directories to implement their
> > > +functionality. Directories that are located under ``/var/`` or
> > > +``/etc/``, and files that are located under ``/var/``, should not be
> > > +created manually via maintainer scripts, but instead be declaratively
> > > +defined via the `tmpfiles.d
> > > +<https://www.freedesktop.org/software/systemd/man/tmpfiles.d.html>`_
> > > +interface.  Files and directories under ephemeral filesystems such as
> > > +``/tmp/`` may also be created and managed via ``tmpfiles.d`` snippets.
> >
> > I understand the empty directory part, but I don't believe "files that are
> > located under /var" is correct unless you specifically mean *empty* files
> > (and even then, I'm not clear on precisely when this would be needed).
> > For example, /var/lib/gnubg/gnubg_ts0.bd is created by the gnubg package
> > maintainer script, and I can see no possible way that action could (or
> > should) be handled by the tmpfiles.d mechanism.
>
> In general tmpfiles.d handles files that exist only as metadata: symbolic
> links (for which the target is the only interesting fact), empty files
> (for which the existence and ownership/permissions are the only interesting
> facts), directories (ditto) and so on.
>
> It can also handle files that have static initial contents that do not
> vary between systems, but can change in a system-specific way later,
> with initial contents either hard-coded in the tmpfiles.d snippet (for
> short text strings) or copied from somewhere below /usr (canonically
> /usr/share/factory).
>
> Files generated by non-trivial imperative code, like machine-specific
> initial contents (/var/lib/dbus/machine-id) or some sort of compiler
> (/var/lib/gnubg/gnubg_ts0.bd, as far as I can tell), are out of scope for
> tmpfiles.d, so I think you're right to be concerned that Luca's wording
> as written is asking gnubg to do something that is unimplementable.
> ch-maintainerscripts.rst has the same issue.
>
> Perhaps "files with trivial contents that are located under /var" would be
> a good wording that is not overly specific about implementation details,
> covers the 90% case, and leaves room for exceptions by declaring packages
> like dbus and gnubg to be non-trivial?

I have reworded as suggested, citing symlinks or short fixed strings
as examples.

> If /var/lib/gnubg/gnubg_ts0.bd is deterministically compiled from
> files shipped in the .deb as a time/space trade-off, is only written
> during package management operations, and is otherwise read-only, then
> perhaps it should live in /usr, but that's orthogonal to wanting to use
> tmpfiles.d where feasible. (Prior art for similar situations includes
> Python bytecode, glibc locales, GLib gschemas.compiled and giomodule.cache,
> and so on.)

We don't have to handle it with this change/bug and as mentioned I've
already reworded it as suggested, but to clarify my thinking there,
the place I was coming from was the factory reset and first boot
angle. When doing a first boot with only the OS vendor tree under /usr
and nothing else, you want to get to a working system, and if there
are complex files created under /var by maintainer scripts, that's
kinda of a problem. This is where tmpfiles.d plus Credentials
(https://systemd.io/CREDENTIALS/ see examples toward the end
especially) can come in and help, even with non-trivial files, such as
users, passwords and ssh keys.
Perhaps those complex binaries should be created by oneshot services
that run at boot with a ConditionPathExists=!/var/some/complex/binary
other than maintainer scripts? That way if /var is blown away, you
still get a working system on next boot.

But again, happy to shelve this for now, as it's a more complex topic.
See attached file for new revision, also pushed to Salsa.
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Luca Boccassi <bl...@debian.org>
Date: Tue, 9 May 2023 01:38:13 +0100
Subject: [PATCH] Define service directories and tmpfiles.d interfaces and
 usage

---
 policy/ch-files.rst             | 49 +++++++++++++++++++++++++++++++++
 policy/ch-maintainerscripts.rst |  7 +++++
 policy/ch-opersys.rst           | 21 ++++++++++++++
 3 files changed, 77 insertions(+)

diff --git a/policy/ch-files.rst b/policy/ch-files.rst
index b34c183..7d0837c 100644
--- a/policy/ch-files.rst
+++ b/policy/ch-files.rst
@@ -722,6 +722,55 @@ The name of the files and directories installed by binary packages
 outside the system PATH must be encoded in UTF-8 and should be
 restricted to ASCII when it is possible to do so.
 
+.. _s-tmpfiles.d:
+
+tmpfiles.d
+----------
+
+Packages might need additional files or directories to implement their
+functionality. Directories that are located under ``/var/`` or ``/etc/``, and
+files with trivial content (for example, but not limited to, symlinks or short
+fixed strings) that are located under ``/var/``, should not be created manually
+via maintainer scripts, but instead be declaratively defined via the `tmpfiles.d
+<https://www.freedesktop.org/software/systemd/man/tmpfiles.d.html>`_ interface.
+Files and directories under ephemeral filesystems such as ``/tmp/`` may also be
+created and managed via ``tmpfiles.d`` snippets.
+
+When ownership of a directory can be clearly tied to a specific service,
+``Service Directories`` should be preferred to ``tmpfiles.d`` snippets. See the
+:doc:`Service Directories section <ch-opersys>` for more details.
+
+The ``tmpfiles.d`` file format is defined by the ``systemd`` project, and is
+guaranteed to be stable. Details about the syntax and installation paths are
+defined by its `reference implementation's documentation,
+<https://www.freedesktop.org/software/systemd/man/tmpfiles.d.html>`_ and will
+not be redefined here.
+
+``tmpfiles.d`` snippets should be usable on systems that do not boot (such as a
+very minimal chroot image), and also on systems booting with init systems other
+than ``systemd``.
+
+``tmpfiles.d`` snippets should be integrated in packages using automated shared
+tooling rather than by manually writing package-specific code in maintainers
+scripts. For example, packages built using ``debhelper`` should make use of the
+``dh_installtmpfiles`` addon. Packages shipping ``tmpfiles.d`` snippets should
+depend on the appropriate virtual packages in the following order:
+``default-systemd-tmpfiles (>= v) | systemd-tmpfiles (>= v)``, where *v* is a
+version of systemd that provides all ``tmpfiles.d`` features that are required.
+The version constraint may be omitted if it is satisfied by all implementations
+of the ``systemd-tmpfiles`` virtual package supported in the previous stable
+release.
+
+Init systems are required to integrate with ``tmpfiles.d`` and run the service
+that applies them on boot, and regularly for cleanup purposes, depending on the
+appropriate package providing the appropriate implementation that best
+integrates with each system. For example, ``systemd`` will make the reference
+implementation available when its main package is installed. The documentation
+for the reference implementation, `systemd-tmpfiles,
+<https://www.freedesktop.org/software/systemd/man/systemd-tmpfiles.html>`_
+explains how to call the program so that the appropriate ``tmpfiles.d`` snippets
+are applied at the appropriate time.
+
 .. [#]
    If you are using GCC, ``-fPIC`` produces code with relocatable
    position independent code, which is required for most architectures
diff --git a/policy/ch-maintainerscripts.rst b/policy/ch-maintainerscripts.rst
index 724074c..3734deb 100644
--- a/policy/ch-maintainerscripts.rst
+++ b/policy/ch-maintainerscripts.rst
@@ -50,6 +50,13 @@ absolute pathname. Maintainer scripts should also not reset the
 appending package-specific directories. These considerations really
 apply to all shell scripts.
 
+Maintainer scripts should not be used to create or remove auxiliary files and/or
+directories that packages may need, such as those in ``/var/`` or ``/etc/``.
+Instead, :ref:`s-tmpfiles.d` snippets should be shipped, with the ones provided
+by the upstream sources, if any, to be preferred over Debian-specific ones when
+possible. For more details about the ``tmpfiles.d`` interface, see
+:ref:`s-tmpfiles.d`.
+
 .. _s-idempotency:
 
 Maintainer scripts idempotency
diff --git a/policy/ch-opersys.rst b/policy/ch-opersys.rst
index 207b3c0..42771e1 100644
--- a/policy/ch-opersys.rst
+++ b/policy/ch-opersys.rst
@@ -595,6 +595,27 @@ This section has been deleted.
 
 .. _s9.3.5:
 
+Service Directories
+~~~~~~~~~~~~~~~~~~~
+
+Services might need auxiliary directories under ``/var/``, ``/run/`` or
+``/etc``. Instead of shipping empty directories in packages, or creating them
+with custom code in maintainer scripts, services should use ``systemd``'s native
+settings to ensure the required directories are created regardless of the
+privilege level under which the services are running. The relevant settings are
+`RuntimeDirectory=, StateDirectory=, CacheDirectory=, LogsDirectory= and
+ConfigurationDirectory=
+<https://freedesktop.org/software/systemd/man/systemd.exec.html#RuntimeDirectory=>`_,
+covering respectively ``/run/``, ``/var/lib/``, ``/var/cache/``, ``/var/log/``
+and ``/etc/`` for system services, and the equivalent XDG-defined location for
+user services.
+
+Init systems other than ``systemd`` should allow providing the same
+functionality as appropriate for each system, for example managing the
+directories from the appropriate service startup configuration.
+
+.. _s9.3.6:
+
 Example
 ~~~~~~~
 

Reply via email to