core: add [State|Runtime|Cache|Logs]Directory symlink as second parameter

When combined with a tmpfs on /run or /var/lib, allows to create
arbitrary and ephemeral symlinks for StateDirectory or RuntimeDirectory.
This is especially useful when sharing these directories between
different services, to make the same state/runtime directory 'backend'
appear as different names to each service, so that they can be added/removed
to a sharing agreement transparently, without code changes.

An example (simplified, but real) use case:

foo.service:
StateDirectory=foo

bar.service:
StateDirectory=bar

foo.service.d/shared.conf:
StateDirectory=
StateDirectory=shared:foo

bar.service.d/shared.conf:
StateDirectory=
StateDirectory=shared:bar

foo and bar use respectively /var/lib/foo and /var/lib/bar. Then
the orchestration layer decides to stop this sharing, the drop-in
can be removed. The services won't need any update and will keep
working and being able to store state, transparently.

To keep backward compatibility, new DBUS messages are added.
This commit is contained in:
Luca Boccassi
2021-10-28 10:47:46 +01:00
parent df61e79a5d
commit 211a3d87fb
11 changed files with 713 additions and 157 deletions
+14 -1
View File
@@ -1327,6 +1327,13 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
configuration or lifetime guarantees, please consider using
<citerefentry><refentrytitle>tmpfiles.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
<para><varname>RuntimeDirectory=</varname>, <varname>StateDirectory=</varname>, <varname>CacheDirectory=</varname>
and <varname>LogsDirectory=</varname> optionally support a second parameter, separated by <literal>:</literal>.
The second parameter will be interpreted as a destination path that will be created as a symlink to the directory.
The symlinks will be created after any <varname>BindPaths=</varname> or <varname>TemporaryFileSystem=</varname>
options have been set up, to make ephemeral symlinking possible. The same source can have multiple symlinks, by
using the same first parameter, but a diferent second parameter.</para></listitem>
<para>The directories defined by these options are always created under the standard paths used by systemd
(<filename>/var/</filename>, <filename>/run/</filename>, <filename>/etc/</filename>, …). If the service needs
directories in a different location, a different mechanism has to be used to create them.</para>
@@ -1355,7 +1362,13 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
<programlisting>RuntimeDirectory=foo/bar
StateDirectory=aaa/bbb ccc</programlisting>
then the environment variable <literal>RUNTIME_DIRECTORY</literal> is set with <literal>/run/foo/bar</literal>, and
<literal>STATE_DIRECTORY</literal> is set with <literal>/var/lib/aaa/bbb:/var/lib/ccc</literal>.</para></listitem>
<literal>STATE_DIRECTORY</literal> is set with <literal>/var/lib/aaa/bbb:/var/lib/ccc</literal>.</para>
<para>Example: if a system service unit has the following,
<programlisting>RuntimeDirectory=foo:bar foo:baz</programlisting>
the service manager creates <filename index='false'>/run/foo</filename> (if it does not exist), and
<filename index='false'>/run/bar</filename> plus <filename index='false'>/run/baz</filename> as symlinks to
<filename index='false'>/run/foo</filename>.</para>
</varlistentry>
<varlistentry>