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 ~~~~~~~