8d419f
From 842c3bade0b593e5c4eabbe1c18dfab503683cc6 Mon Sep 17 00:00:00 2001
8d419f
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
8d419f
Date: Thu, 10 Mar 2022 21:33:25 +0100
8d419f
Subject: [PATCH] man: fix invalid description of template handling in
8d419f
 WantedBy=
8d419f
8d419f
We don't need to talk about Alias=. The approach of using Alias= to enable
8d419f
units is still supported, but hasn't been advertised as the way to do thing
8d419f
for many years. Using it as an explanation is just confusing.
8d419f
8d419f
Also, the description of templated units did not take DefaultInstance=
8d419f
into account. It is updated and extended.
8d419f
8d419f
(cherry picked from commit 17a2679e9925c9ec3c5764d01def92c5627973e4)
8d419f
8d419f
Related: #2082131
8d419f
---
8d419f
 man/systemd.unit.xml          | 53 +++++++++++++++++------------------
8d419f
 test/test-systemctl-enable.sh | 49 ++++++++++++++++++++++++++++++++
8d419f
 2 files changed, 74 insertions(+), 28 deletions(-)
8d419f
8d419f
diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml
8d419f
index 2e6261c1ed..caebaecfdc 100644
8d419f
--- a/man/systemd.unit.xml
8d419f
+++ b/man/systemd.unit.xml
8d419f
@@ -1906,34 +1906,31 @@
8d419f
         <term><varname>WantedBy=</varname></term>
8d419f
         <term><varname>RequiredBy=</varname></term>
8d419f
 
8d419f
-        <listitem><para>This option may be used more than once, or a
8d419f
-        space-separated list of unit names may be given. A symbolic
8d419f
-        link is created in the <filename>.wants/</filename> or
8d419f
-        <filename>.requires/</filename> directory of each of the
8d419f
-        listed units when this unit is installed by <command>systemctl
8d419f
-        enable</command>. This has the effect that a dependency of
8d419f
-        type <varname>Wants=</varname> or <varname>Requires=</varname>
8d419f
-        is added from the listed unit to the current unit. The primary
8d419f
-        result is that the current unit will be started when the
8d419f
-        listed unit is started. See the description of
8d419f
-        <varname>Wants=</varname> and <varname>Requires=</varname> in
8d419f
-        the [Unit] section for details.</para>
8d419f
-
8d419f
-        <para><command>WantedBy=foo.service</command> in a service
8d419f
-        <filename>bar.service</filename> is mostly equivalent to
8d419f
-        <command>Alias=foo.service.wants/bar.service</command> in the
8d419f
-        same file. In case of template units listing non template units,
8d419f
-        <command>systemctl enable</command> must be called with an
8d419f
-        instance name, and this instance will be added to the
8d419f
-        <filename>.wants/</filename> or
8d419f
-        <filename>.requires/</filename> list of the listed unit. E.g.
8d419f
-        <command>WantedBy=getty.target</command> in a service
8d419f
-        <filename>getty@.service</filename> will result in
8d419f
-        <command>systemctl enable getty@tty2.service</command>
8d419f
-        creating a
8d419f
-        <filename>getty.target.wants/getty@tty2.service</filename>
8d419f
-        link to <filename>getty@.service</filename>.
8d419f
-        </para></listitem>
8d419f
+        <listitem><para>This option may be used more than once, or a space-separated list of unit names may
8d419f
+        be given. A symbolic link is created in the <filename>.wants/</filename> or
8d419f
+        <filename>.requires/</filename> directory of each of the listed units when this unit is installed by
8d419f
+        <command>systemctl enable</command>. This has the effect of a dependency of type
8d419f
+        <varname>Wants=</varname> or <varname>Requires=</varname> being added from the listed unit to the
8d419f
+        current unit. The primary result is that the current unit will be started when the listed unit is
8d419f
+        started, see the description of <varname>Wants=</varname> and <varname>Requires=</varname> in the
8d419f
+        [Unit] section for details.</para>
8d419f
+
8d419f
+        <para>In case of template units listing non template units, the listing unit must have
8d419f
+        <varname>DefaultInstance=</varname> set, or <command>systemctl enable</command> must be called with
8d419f
+        an instance name. The instance (default or specified) will be added to the
8d419f
+        <filename>.wants/</filename> or <filename>.requires/</filename> list of the listed unit. For example,
8d419f
+        <command>WantedBy=getty.target</command> in a service <filename>getty@.service</filename> will result
8d419f
+        in <command>systemctl enable getty@tty2.service</command> creating a
8d419f
+        <filename>getty.target.wants/getty@tty2.service</filename> link to
8d419f
+        <filename>getty@.service</filename>. This also applies to listing specific instances of templated
8d419f
+        units: this specific instance will gain the dependency. A template unit may also list a template
8d419f
+        unit, in which case a generic dependency will be added where each instance of the listing unit will
8d419f
+        have a dependency on an instance of the listed template with the same instance value. For example,
8d419f
+        <command>WantedBy=container@.target</command> in a service <filename>monitor@.service</filename> will
8d419f
+        result in <command>systemctl enable monitor@.service</command> creating a
8d419f
+        <filename>container@.target.wants/monitor@.service</filename> link to
8d419f
+        <filename>monitor@.service</filename>, which applies to all instances of
8d419f
+        <filename>container@.target</filename>.</para></listitem>
8d419f
       </varlistentry>
8d419f
 
8d419f
       <varlistentry>
8d419f
diff --git a/test/test-systemctl-enable.sh b/test/test-systemctl-enable.sh
8d419f
index 4117436462..3aa61222a8 100644
8d419f
--- a/test/test-systemctl-enable.sh
8d419f
+++ b/test/test-systemctl-enable.sh
8d419f
@@ -324,6 +324,31 @@ test ! -h "$root/etc/systemd/system/services.target.wants/templ1@333.service"
8d419f
 test ! -h "$root/etc/systemd/system/services.target.wants/templ1@one.service"
8d419f
 test ! -h "$root/etc/systemd/system/services.target.wants/templ1@two.service"
8d419f
 
8d419f
+: -------template enablement for another template-------------
8d419f
+cat >"$root/etc/systemd/system/templ2@.service" <
8d419f
+[Install]
8d419f
+RequiredBy=another-template@.target
8d419f
+EOF
8d419f
+
8d419f
+"$systemctl" --root="$root" enable 'templ2@.service'
8d419f
+islink "$root/etc/systemd/system/another-template@.target.requires/templ2@.service" "/etc/systemd/system/templ2@.service"
8d419f
+
8d419f
+"$systemctl" --root="$root" enable 'templ2@two.service'
8d419f
+islink "$root/etc/systemd/system/another-template@.target.requires/templ2@.service" "/etc/systemd/system/templ2@.service"
8d419f
+islink "$root/etc/systemd/system/another-template@.target.requires/templ2@two.service" "/etc/systemd/system/templ2@.service"
8d419f
+
8d419f
+"$systemctl" --root="$root" disable 'templ2@other.service'
8d419f
+islink "$root/etc/systemd/system/another-template@.target.requires/templ2@.service" "/etc/systemd/system/templ2@.service"
8d419f
+islink "$root/etc/systemd/system/another-template@.target.requires/templ2@two.service" "/etc/systemd/system/templ2@.service"
8d419f
+
8d419f
+"$systemctl" --root="$root" disable 'templ2@two.service'
8d419f
+islink "$root/etc/systemd/system/another-template@.target.requires/templ2@.service" "/etc/systemd/system/templ2@.service"
8d419f
+test ! -h "$root/etc/systemd/system/another-template@.target.requires/templ2@two.service"
8d419f
+
8d419f
+"$systemctl" --root="$root" disable 'templ2@.service'
8d419f
+test ! -h "$root/etc/systemd/system/another-template@.target.requires/templ2@.service"
8d419f
+test ! -h "$root/etc/systemd/system/another-template@.target.requires/templ2@two.service"
8d419f
+
8d419f
 : -------aliases w/ and w/o instance--------------------------
8d419f
 test ! -e "$root/etc/systemd/system/link4.service"
8d419f
 cat >"$root/etc/systemd/system/link4.service" <
8d419f
@@ -529,6 +554,30 @@ check_alias % '%' && { echo "Expected failure because % is not legal in unit nam
8d419f
 
8d419f
 check_alias z 'z' && { echo "Expected failure because %z is not known" >&2; exit 1; }
8d419f
 
8d419f
+: -------specifiers in WantedBy-------------------------------
8d419f
+# We don't need to repeat all the tests. Let's do a basic check that specifier
8d419f
+# expansion is performed.
8d419f
+
8d419f
+cat >"$root/etc/systemd/system/some-some-link7.socket" <
8d419f
+[Install]
8d419f
+WantedBy=target@%p.target
8d419f
+WantedBy=another-target@.target
8d419f
+RequiredBy=target2@%p.target
8d419f
+RequiredBy=another-target2@.target
8d419f
+EOF
8d419f
+
8d419f
+"$systemctl" --root="$root" enable 'some-some-link7.socket'
8d419f
+islink "$root/etc/systemd/system/target@some-some-link7.target.wants/some-some-link7.socket" "/etc/systemd/system/some-some-link7.socket"
8d419f
+islink "$root/etc/systemd/system/another-target@.target.wants/some-some-link7.socket" "/etc/systemd/system/some-some-link7.socket"
8d419f
+islink "$root/etc/systemd/system/target2@some-some-link7.target.requires/some-some-link7.socket" "/etc/systemd/system/some-some-link7.socket"
8d419f
+islink "$root/etc/systemd/system/another-target2@.target.requires/some-some-link7.socket" "/etc/systemd/system/some-some-link7.socket"
8d419f
+
8d419f
+"$systemctl" --root="$root" disable 'some-some-link7.socket'
8d419f
+test ! -h "$root/etc/systemd/system/target@some-some-link7.target.wants/some-some-link7.socket"
8d419f
+test ! -h "$root/etc/systemd/system/another-target@.target.wants/some-some-link7.socket"
8d419f
+test ! -h "$root/etc/systemd/system/target2@some-some-link7.target.requires/some-some-link7.socket"
8d419f
+test ! -h "$root/etc/systemd/system/another-target2@.target.requires/some-some-link7.socket"
8d419f
+
8d419f
 # TODO: repeat the tests above for presets
8d419f
 
8d419f
 : -------SYSTEMD_OS_RELEASE relative to root------------------