Package: debian-policy X-Debbugs-CC: bi...@debian.org pkg-systemd-maintain...@lists.alioth.debian.org
It has come to my attention that there is one package in Debian using dpkg-divert to mask a systemd configuration file (an udev rule). Speaking as one of the maintainers, both upstream and downstream, I find this greatly undesirable for several reasons that I will outline later. Hence I would like to propose explicitly mentioning that dpkg- divert must not be used for systemd configuration files (units, rules, etc), and instead the supported workflow (drop-ins, masking, etc) must be used, both by packages and administrators. This is already standard practice, and again there is only one instance that needs correcting as far as I understand, and I have already provided a bug and a MR for that [1][2]. So the impact of this policy change should be minimal, and it's mostly to ensure more such instances are accidentally added in the future. I have a draft policy update, that adds a paragraph to the dpkg-divert section of the policy. It is attached here, and also available on Salsa on my fork [3]. The full reasoning below is what I provided on the MR for the one existing instance, and I'll copy it mostly unchanged as I hope it's exhaustive enough. It uses the one existing instance I found as concrete example. This is not intended to single out the maintainer or assign blame, but merely to illustrate the point with a concrete and real use case. Quoting from the MR: One of the main goals behind the systemd (and its udev component) project is to unify how the low-level userspace components of a Linux distro work, so that the exact same mechanisms, patterns, behaviours and interfaces apply to a multitude of use cases, implementations and tools. A core part of this is the configuration system. The configuration system supports a complex schema of main contents, overrides, drop-ins, masking and aliasing. This system is used and understood by all systemd components, across all Linux distributions, with the same interface, look and feel, so that users can feel at home and know how to work the system regardless of the vendor, and so that programs can rely on a stable and common interface that doesn't have to be endlessly customized depending on which vendor or distribution it is used by. The concept of 'masking' a configuration is well understood, ubiquitous and fully supported by all the tooling, including in input _and_ output, and logging, and so on. By using the supported mechanism for masking we ensure that there are no surprises for users, coders and vendors. When an unsupported masking mechanism is used, as in this case, the fact that the original item is masked is completely hidden to the systemd components, and thus to the interface provided to the user. This causes at best confusion and misunderstanding, and at worst bugs that will inevitably fall on the systemd maintainers, causing increased workload for an already over stretched team. A simple and obvious example of what I am referring to is already included in the git commit for this change. Consider what happens when udev parses the vanilla configuration (ie: without amazon-ec2-utils installed): $ udevadm test /dev/cdrom 2>&1 | grep 60-cdrom_id Reading rules file: /lib/udev/rules.d/60-cdrom_id.rules The user/system/log is clearly notified that the file is parsed, there are no errors, and thus is used. Now consider what happens when the current version of amazon-ec2-utils is installed: $ udevadm test /dev/cdrom 2>&1 | grep 60-cdrom_id Reading rules file: /lib/udev/rules.d/60-cdrom_id.rules It looks exactly the same. But something extremely different is actually happening, in fact the opposite! The file is empty, so the vanilla rule is effectively masked, but nothing and nobody is notified of this very important fact when udev is running. One would have to query dpkg-divert to figure this out, but this is something that even someone like me, who can reasonably consider myself a proficient Debian user, would not think of looking at. Now finally consider what happens if amazon-ec2-utils with my proposed change is installed: $ udevadm test /dev/cdrom 2>&1 | grep 60-cdrom_id Skipping overridden file '/lib/udev/rules.d/60-cdrom_id.rules'. Skipping empty file: /etc/udev/rules.d/60-cdrom_id.rules There is an extremely clear, obvious and expected indication that the original rule is ignored because it is overridden, _and_ that the override is empty, as it's a masking operation. Now udev is a bit older than the other components, so "masking" is not named explicitly as it would be for example by systemctl, but it is the same operation and the same result and the same interface. Something I should probably improve a bit upstream, I will take a note of this. Here's another example with systemctl and units. I have masked systemd- homed.service via `systemctl mask` and this is what the interface shows me when I check the status: $ systemctl status -l --no-pager systemd-homed.service ○ systemd-homed.service Loaded: masked (Reason: Unit systemd-homed.service is masked.) Active: inactive (dead) since Sun 2023-05-07 18:59:51 BST; 7s ago <snip> Message is clear and unambiguous, I masked the unit so it will not run. Here's what happens if I unmask it and instead dpkg-divert the vanilla unit with a /bin/true no-op: # systemctl status systemd-homed.service ○ systemd-homed.service Loaded: loaded (/usr/lib/systemd/system/systemd-homed.service; enabled; preset: enabled) Active: inactive (dead) since Sun 2023-05-07 18:59:51 BST; 4min 49s ago <snip> From the output, it's all good. The vanilla unit is enabled and should run and provide its services on the next boot or when I next start it, except it's not - it's been dpkg-diverted to a no-op, but there's no indication there. This is poor UI, poor experience, poor integration. And it's just the most basic, obvious example of what can go wrong: I cannot guarantee that there won't be more, higher severity issues, but I can certainly state that I will provide no support when they inevitably surface, as this is not a supported mechanism. The supported mechanism for masking, for both local admins and packages, is masking via symlinks to /dev/null in /etc. And again I must stress that packages configure things in /etc too, not only administrators! This is fully expected and supported. For example, deb- systemd-helper from init-system-helpers (https://sources.debian.org/src/init-system-helpers/1.65.2/script/deb-systemd-helper/ ) is used in Debian/Ubuntu and derivatives to enable/disable/mask/alias units, and these changes are performed from auto generated (by debhelper https://sources.debian.org/src/debhelper/13.11.4/dh_installsystemd/) maintainer script snippets not too dissimilar to what I have in this MR. And this does not only apply to files that the packages own! It also applies cross-packages. For example, by installing the 'dbus- broker' package, an alias to dbus.service that effectively masks and takes over dbus.service from the dbus-daemon package is installed in /etc by the maintainer script: $ ls -l /etc/systemd/system/dbus.service lrwxrwxrwx 1 root root 43 May 6 17:45 /etc/systemd/system/dbus.service -> /usr/lib/systemd/system/dbus-broker.service From `/var/lib/dpkg/info/dbus-broker.postinst`: # Automatically added by dh_installsystemd/13.11.4 if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ] || [ "$1" = "abort-deconfigure" ] || [ "$1" = "abort-remove" ] ; then # The following line should be removed in trixie or trixie+1 deb-systemd-helper unmask 'dbus-broker.service' >/dev/null || true # was-enabled defaults to true, so new installations run enable. if deb-systemd-helper --quiet was-enabled 'dbus-broker.service'; then # Enables the unit on first installation, creates new # symlinks on upgrades if the unit file has changed. deb-systemd-helper enable 'dbus-broker.service' >/dev/null || true else # Update the statefile to add new symlinks (if any), which need to be # cleaned up on purge. Also remove old symlinks. deb-systemd-helper update-state 'dbus-broker.service' >/dev/null || true fi fi # End automatically added section This is supported, intended and expected, as it's the correct mechanism to do aliasing and overriding. No local user action is performed, everything is done by the package being installed. In effect, the user action IS installing the package. Ensuring Debian packages use a supported, intended and expected mechanism to manage and configure systemd files is fundamental for the ability of the systemd downstream maintainers team to be able to fully and effectively support Debian and its users. Deviating from the expected path causes additional workload, unexpected incidents and general discomfort for an already over-worked and small team, while providing no tangible benefit, as the net result is the same. [0] https://salsa.debian.org/cloud-team/amazon-ec2-utils/-/merge_requests/2 [1] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1035667 [3] https://salsa.debian.org/bluca/policy/-/tree/systemd_overrides -- Kind regards, Luca Boccassi
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Luca Boccassi <bl...@debian.org> Date: Mon, 8 May 2023 03:21:14 +0100 Subject: [PATCH] Forbid using dpkg-divert for systemd configuration files The supported mechanism for augmenting, changing, overriding and disabling systemd configuration files is natively supported and fully integrated in Debian, via drop-ins, hierarchical overrides, and masking. dpkg-divert is not integrated in systemd tools so its use is completely hidden in logs and status interfaces, and it is specific to Debian and thus diverges from what users expect as implemented by all other distros, going against one of the core goals of the systemd project which is to provide a uniform interface regardless of distro vendor or flavour. --- policy/ap-pkg-diversions.rst | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/policy/ap-pkg-diversions.rst b/policy/ap-pkg-diversions.rst index fe360d1..00bbc04 100644 --- a/policy/ap-pkg-diversions.rst +++ b/policy/ap-pkg-diversions.rst @@ -81,3 +81,23 @@ when the file does not exist. Do not attempt to divert a conffile, as ``dpkg`` does not handle it well. +Do not divert systemd configuration files - `units, +<https://www.freedesktop.org/software/systemd/man/systemd.unit.html#Description>`_ +`udev rules, +<https://www.freedesktop.org/software/systemd/man/udev.html#Rules%20Files>`_ +`tmpfiles.d, +<https://www.freedesktop.org/software/systemd/man/tmpfiles.d.html#Configuration%20Directories%20and%20Precedence>`_ +`sysusers +<https://www.freedesktop.org/software/systemd/man/sysusers.d.html#Configuration%20Directories%20and%20Precedence>`_ +and other such files, including those specific to systemd daemons (e.g.: +`/etc/systemd/system.conf). +<https://www.freedesktop.org/software/systemd/man/systemd-system.conf.html>`_ +systemd and all its components natively support overriding configuration files +as they are shipped by the distribution, for both local administrator changes +and for changes applied from other packages, as specified in the documentation. +You must utilize those mechanisms to override, enhance or mask systemd +configuration files, as defined in the apposite systemd documentation. +Following upstream's best practices and supported workflows ensures that user +experience is streamlined and without surprises. It also simplifies support and +maintenance. +
signature.asc
Description: This is a digitally signed message part