systemd-sysext: introduce a global config (#38250)

This PR implements what is proposed in
https://github.com/systemd/systemd/issues/37992.

Having a global config file that supports the same cmdline options for
sysext/confext allows the user to customize the behavior of
systemd-sysext.service unit too, without the need of hacking the service
manually.

The global config will live in
`CONF_PATHS_STRV()/systemd/{sysext/confext}.conf` and it will be
overridden by cmdline, so it is possible to customize a run if
`systemd-sysext` is executed manually.

For now support `--mutable=` (`Mutable`) and `--image-policy=`
(`ImagePolicy`).
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2025-09-17 15:13:11 +02:00
committed by GitHub
4 changed files with 148 additions and 1 deletions

View File

@@ -1138,6 +1138,7 @@ manpages = [
'systemd-sysext-initrd.service',
'systemd-sysext.service'],
'ENABLE_SYSEXT'],
['sysext.conf', '5', ['confext.conf'], 'ENABLE_SYSEXT'],
['systemd-system-update-generator', '8', [], ''],
['systemd-system.conf',
'5',

101
man/sysext.conf.xml Normal file
View File

@@ -0,0 +1,101 @@
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<!-- SPDX-License-Identifier: LGPL-2.1-or-later -->
<refentry id="sysext.conf" conditional='ENABLE_SYSEXT'
xmlns:xi="http://www.w3.org/2001/XInclude">
<refentryinfo>
<title>sysext.conf</title>
<productname>systemd</productname>
</refentryinfo>
<refmeta>
<refentrytitle>sysext.conf</refentrytitle>
<manvolnum>5</manvolnum>
</refmeta>
<refnamediv>
<refname>sysext.conf</refname>
<refname>confext.conf</refname>
<refname>sysext.conf.d</refname>
<refname>confext.conf.d</refname>
<refpurpose>Configuration files for systemd-sysext</refpurpose>
</refnamediv>
<refsynopsisdiv>
<para><filename>/etc/systemd/sysext.conf</filename></para>
<para><filename>/etc/systemd/sysext.conf.d/*.conf</filename></para>
<para><filename>/run/systemd/sysext.conf</filename></para>
<para><filename>/run/systemd/sysext.conf.d/*.conf</filename></para>
<para><filename>/usr/lib/systemd/sysext.conf</filename></para>
<para><filename>/usr/lib/systemd/sysext.conf.d/*.conf</filename></para>
<para><filename>/etc/systemd/confext.conf</filename></para>
<para><filename>/etc/systemd/confext.conf.d/*.conf</filename></para>
<para><filename>/run/systemd/confext.conf</filename></para>
<para><filename>/run/systemd/confext.conf.d/*.conf</filename></para>
<para><filename>/usr/lib/systemd/confext.conf</filename></para>
<para><filename>/usr/lib/systemd/confext.conf.d/*.conf</filename></para>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>These configuration files control the behavior of
<citerefentry><refentrytitle>systemd-sysext</refentrytitle><manvolnum>8</manvolnum></citerefentry> and
<citerefentry><refentrytitle>systemd-confext</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
They are especially useful when needing to customize the behavior of the
respective extension service units.</para>
</refsect1>
<xi:include href="standard-conf.xml" xpointer="main-conf" />
<refsect1>
<title>Options</title>
<para>The following options are understood in both the <literal>[Sysext]</literal> and
<literal>[Confext]</literal> sections:</para>
<refsect2>
<title>Section Options</title>
<variablelist class='config-directives'>
<varlistentry>
<term><varname>Mutable=</varname></term>
<listitem><para>Set the mutable mode for system extensions. Takes one of <literal>no</literal>,
<literal>yes</literal>, <literal>auto</literal>, <literal>import</literal>,
<literal>ephemeral</literal>, or <literal>ephemeral-import</literal>. For details about the modes,
see the <option>--mutable=</option> option in
<citerefentry><refentrytitle>systemd-sysext</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
Defaults to <literal>no</literal>.</para>
<xi:include href="version-info.xml" xpointer="v259"/>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>ImagePolicy=</varname></term>
<listitem><para>Set the image policy. Takes an image policy string as argument, as per
<citerefentry><refentrytitle>systemd.image-policy</refentrytitle><manvolnum>7</manvolnum></citerefentry>.
For details, see the <option>--image-policy=</option> option in
<citerefentry><refentrytitle>systemd-sysext</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
</para>
<xi:include href="version-info.xml" xpointer="v259"/>
</listitem>
</varlistentry>
</variablelist>
</refsect2>
</refsect1>
<refsect1>
<title>See Also</title>
<para><simplelist type="inline">
<member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-sysext</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd.syntax</refentrytitle><manvolnum>7</manvolnum></citerefentry></member>
</simplelist></para>
</refsect1>
</refentry>

View File

@@ -74,7 +74,12 @@
<para>System extension images are strictly read-only by default. On mutable host file systems,
<filename>/usr/</filename> and <filename>/opt/</filename> hierarchies become read-only while extensions
are merged, unless mutability is enabled. Mutability may be enabled via the <option>--mutable=</option>
option; see "Mutability" below for more information.</para>
option and the <varname>Mutable=</varname> option in the configuration file;
see "Mutability" below for more information.</para>
<para>Various command options can be configured globally via configuration files. See
<citerefentry><refentrytitle>sysext.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for details.</para>
<para>System extensions are supposed to be purely additive, i.e. they are supposed to include only files
that do not exist in the underlying basic OS image. However, the underlying mechanism (overlayfs) also
@@ -477,6 +482,7 @@
<title>See Also</title>
<para><simplelist type="inline">
<member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>sysext.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-stub</refentrytitle><manvolnum>7</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>importctl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>

View File

@@ -17,6 +17,7 @@
#include "bus-util.h"
#include "capability-util.h"
#include "chase.h"
#include "conf-parser.h"
#include "devnum-util.h"
#include "discover-image.h"
#include "dissect-image.h"
@@ -148,6 +149,37 @@ static int parse_mutable_mode(const char *p) {
return mutable_mode_from_string(p);
}
static DEFINE_CONFIG_PARSE_ENUM(config_parse_mutable_mode, mutable_mode, MutableMode);
static int parse_config_file(ImageClass image_class) {
const char *section = image_class == IMAGE_SYSEXT ? "SysExt" : "ConfExt";
const ConfigTableItem items[] = {
{ section, "Mutable", config_parse_mutable_mode, 0, &arg_mutable },
{ section, "ImagePolicy", config_parse_image_policy, 0, &arg_image_policy },
{}
};
_cleanup_free_ char *config_file = NULL;
int r;
config_file = strjoin("systemd/", image_class_info[image_class].short_identifier, ".conf");
if (!config_file)
return log_oom();
r = config_parse_standard_file_with_dropins_full(
arg_root,
config_file,
image_class == IMAGE_SYSEXT ? "SysExt\0" : "ConfExt\0",
config_item_table_lookup, items,
CONFIG_PARSE_WARN,
/* userdata = */ NULL,
/* ret_stats_by_path = */ NULL,
/* ret_dropin_files = */ NULL);
if (r < 0)
return r;
return 0;
}
static int is_our_mount_point(
ImageClass image_class,
const char *p) {
@@ -2590,6 +2622,7 @@ static int run(int argc, char *argv[]) {
arg_image_class = invoked_as(argv, "systemd-confext") ? IMAGE_CONFEXT : IMAGE_SYSEXT;
/* Parse environment variable first */
env_var = getenv(image_class_info[arg_image_class].mode_env);
if (env_var) {
r = parse_mutable_mode(env_var);
@@ -2600,6 +2633,12 @@ static int run(int argc, char *argv[]) {
arg_mutable = r;
}
/* Parse configuration file */
r = parse_config_file(arg_image_class);
if (r < 0)
log_warning_errno(r, "Failed to parse global config file, ignoring: %m");
/* Parse command line */
r = parse_argv(argc, argv);
if (r <= 0)
return r;