machined: make registration of unpriv user's VMs/containers work (#37855)

This adds missing glue to reasonably allow unpriv users VMs/containers
to register with the system machined.

This primarily adds two things:

1. machined can now properly track VMs/containers residing in subcgroups
of units, because that's effectively what happens for per-user
VMs/containers: they are placed below the system unit `user@….service`
in some user unit.

2. machines registered with machined now have an owning UID: users can
operate on their own machines withour re-authentication, but not on
others.

Note that this is only a first step regarding machined's hookup of
nspawn/vmspawn in the long run for unpriv operation.

I think eventually we should make it so that there's both a per-user and
a per-system machined instance (so far, and even with this PR there's
still one per-system instance), and per-user containers/VMs would
registering with *both*. Having two instances makes sense I think,
because it would mean we can make machined reasonably manage the
per-user image discovery, and also do the per-system network/hostname
handling.
This commit is contained in:
Lennart Poettering
2025-07-11 21:10:08 +02:00
committed by GitHub
38 changed files with 1492 additions and 336 deletions
+4 -6
View File
@@ -595,12 +595,10 @@
<varlistentry>
<term><option>--kill-whom=</option></term>
<listitem><para>When used with <command>kill</command>, choose
which processes to kill. Must be one of
<option>leader</option>, or <option>all</option> to select
whether to kill only the leader process of the machine or all
processes of the machine. If omitted, defaults to
<option>all</option>.</para>
<listitem><para>When used with <command>kill</command>, choose which processes to kill. Must be one
of <option>leader</option>, <option>supervisor</option>, or <option>all</option> to select whether to
kill only the leader process of the machine, the supervisor process of the machine, or all processes
of the machine. If omitted, defaults to <option>all</option>.</para>
<xi:include href="version-info.xml" xpointer="v206"/></listitem>
</varlistentry>
+35 -3
View File
@@ -506,10 +506,16 @@ node /org/freedesktop/machine1/machine/rawhide {
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s Unit = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s Subgroup = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly u Leader = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t LeaderPIDFDId = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly u Supervisor = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t SupervisorPIDFDId = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s Class = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s RootDirectory = '...';
@@ -523,6 +529,8 @@ node /org/freedesktop/machine1/machine/rawhide {
readonly s SSHPrivateKeyPath = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly s State = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly u UID = ...;
};
interface org.freedesktop.DBus.Peer { ... };
interface org.freedesktop.DBus.Introspectable { ... };
@@ -598,10 +606,16 @@ node /org/freedesktop/machine1/machine/rawhide {
<variablelist class="dbus-property" generated="True" extra-ref="Unit"/>
<variablelist class="dbus-property" generated="True" extra-ref="Subgroup"/>
<variablelist class="dbus-property" generated="True" extra-ref="Leader"/>
<variablelist class="dbus-property" generated="True" extra-ref="LeaderPIDFDId"/>
<variablelist class="dbus-property" generated="True" extra-ref="Supervisor"/>
<variablelist class="dbus-property" generated="True" extra-ref="SupervisorPIDFDId"/>
<variablelist class="dbus-property" generated="True" extra-ref="Class"/>
<variablelist class="dbus-property" generated="True" extra-ref="RootDirectory"/>
@@ -616,6 +630,8 @@ node /org/freedesktop/machine1/machine/rawhide {
<variablelist class="dbus-property" generated="True" extra-ref="State"/>
<variablelist class="dbus-property" generated="True" extra-ref="UID"/>
<!--End of Autogenerated section-->
<refsect2>
@@ -647,11 +663,20 @@ node /org/freedesktop/machine1/machine/rawhide {
<para><varname>Unit</varname> is the systemd scope or service unit name for the machine.</para>
<para><varname>Leader</varname> is the PID of the leader process of the machine.</para>
<para><varname>Leader</varname> is the PID of the leader process of the machine. (The leader process is the
top-level process of the payload of the machine, i.e. for containers PID 1 inside the container, and
for VMs the process encapsulating the VM. Its lifetime defines the lifetime of the machine.)</para>
<para><varname>LeaderPIDFDId</varname> encodes the Linux pidfd inode ID of the leader process of the
machine.</para>
<para><varname>Supervisor</varname> is the PID of the supervisor process of the machine. (The
supervisor process is the process that manages the machine, if there's a separate one for it. A
supervisor process is not always defined, and does not define the machine's lifetime.)</para>
<para><varname>SupervisorPIDFDId</varname> encodes the Linux pidfd inode ID of the supervisor process of the
machine.</para>
<para><varname>Class</varname> is the class of the machine and is either the string "vm" (for real VMs
based on virtualized hardware) or "container" (for lightweight userspace virtualization sharing the
same kernel as the host).</para>
@@ -676,6 +701,11 @@ node /org/freedesktop/machine1/machine/rawhide {
<literal>running</literal>, or <literal>closing</literal>. Note that the state machine is not considered
part of the API and states might be removed or added without this being considered API breakage.
</para>
<para><varname>Subgroup</varname> contains the sub-control-group path this machine's processes reside
in, relative to the specified unit's control group.</para>
<para><varname>UID</varname> contains the numeric UNIX UID of the user who registered the machine.</para>
</refsect2>
</refsect1>
@@ -717,9 +747,11 @@ $ gdbus introspect --system \
<title>Machine Objects</title>
<para><function>CopyFromWithFlags()</function> and
<function>CopyToWithFlags()</function> were added in version 252.</para>
<para><function>GetSSHInfo()</function>, <varname>VSockCID</varname>, <varname>SSHAddress</varname>
<para><function>GetSSHInfo()</function>, <varname>VSockCID</varname>, <varname>SSHAddress</varname>,
and <varname>SSHPrivateKeyPath</varname> were added in version 256.</para>
<para><varname>LeaderPIDFDId</varname> was added in version 258.</para>
<para><varname>LeaderPIDFDId</varname>, <varname>Supervisor</varname>,
<varname>SupervisorPIDFDId</varname>, <varname>Subgroup</varname>, and <varname>UID</varname> were added
in version 258.</para>
</refsect2>
</refsect1>
+9 -7
View File
@@ -651,13 +651,15 @@
<term><option>--notify-ready=</option></term>
<listitem><para>Configures support for notifications from the container's init process.
<option>--notify-ready=</option> takes a boolean (<option>no</option> and <option>yes</option>).
With option <option>no</option> systemd-nspawn notifies systemd
with a <literal>READY=1</literal> message when the init process is created.
With option <option>yes</option> systemd-nspawn waits for the
<literal>READY=1</literal> message from the init process in the container
before sending its own to systemd. For more details about notifications
see <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
<option>--notify-ready=</option> takes a boolean. If false <command>systemd-vmpawn</command>
notifies the calling service manager with a <literal>READY=1</literal> message when the init process is
created. If true it waits for a <literal>READY=1</literal> message from the init process in the VM
before sending its own to the service manager. For more details about notifications see
<citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
<para>Defaults to false. (Note that this is unlike the option of the same name to
<citerefentry><refentrytitle>systemd-vmspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>
that defaults to true.)</para>
<xi:include href="version-info.xml" xpointer="v231"/></listitem>
</varlistentry>
+44
View File
@@ -303,6 +303,25 @@
<xi:include href="version-info.xml" xpointer="v258"/></listitem>
</varlistentry>
<varlistentry>
<term><option>--notify-ready=</option></term>
<listitem><para>Configures support for notifications from the VM's init process to
<command>systemd-vmspawn</command>. If true, <command>systemd-vmspawn</command> will consider the
machine as ready only when it has received a <literal>READY=1</literal> message from the init
process in the VM. If false, <command>systemd-vmspawn</command> will consider the machine as ready
immediately after creation. In either case, <command>systemd-vmspawn</command> sends its own
readiness notification to its manager after the spawned VM is ready. For more details about
notifications see
<citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
<para>Defaults to true. (Note that this is unlike the option of the same name to
<citerefentry><refentrytitle>systemd-vmspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>
that defaults to false.)</para>
<xi:include href="version-info.xml" xpointer="v258"/></listitem>
</varlistentry>
</variablelist>
</refsect2>
@@ -343,6 +362,30 @@
<title>Property Options</title>
<variablelist>
<varlistentry>
<term><option>-S</option></term>
<term><option>--slice=</option></term>
<listitem><para>Make the VM part of the specified slice, instead of the default
<filename>machine.slice</filename>. This applies only if the machine is run in its own scope unit,
i.e. if <option>--keep-unit</option> is not used.</para>
<xi:include href="version-info.xml" xpointer="v258"/>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--property=</option></term>
<listitem><para>Set a unit property on the scope unit to register for the machine. This applies
only if the machine is run in its own scope unit, i.e. if <option>--keep-unit</option> is not
used. Takes unit property assignments in the same format as <command>systemctl
set-property</command>. This is useful to set memory limits and similar for the VM.</para>
<xi:include href="version-info.xml" xpointer="v258"/>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--register=</option></term>
@@ -532,6 +575,7 @@
<xi:include href="standard-options.xml" xpointer="no-pager" />
<xi:include href="standard-options.xml" xpointer="help" />
<xi:include href="standard-options.xml" xpointer="version" />
<xi:include href="standard-options.xml" xpointer="no-ask-password" />
</variablelist>
</refsect2>
</refsect1>