sysinstall: Add varlink interface

Allow graphical installers to use system sysinstall.
This will be used by gnome-setup to install GNOME OS and ideally installers
of other distributions talk to the same varlink interface.
This commit is contained in:
Julian Sparber
2026-07-03 11:16:46 +02:00
parent 98b875b2ac
commit c17d0c7e85
12 changed files with 1152 additions and 145 deletions
+1
View File
@@ -251,6 +251,7 @@ shared_sources = files(
'varlink-io.systemd.Resolve.Monitor.c',
'varlink-io.systemd.Shutdown.c',
'varlink-io.systemd.StorageProvider.c',
'varlink-io.systemd.SysInstall.c',
'varlink-io.systemd.SysUpdate.c',
'varlink-io.systemd.SysUpdate.Notify.c',
'varlink-io.systemd.Udev.c',
+5 -5
View File
@@ -29,7 +29,7 @@ static SD_VARLINK_DEFINE_ENUM_TYPE(
SD_VARLINK_FIELD_COMMENT("Always create a new partition table, potentially overwriting an existing table"),
SD_VARLINK_DEFINE_ENUM_VALUE(force));
static SD_VARLINK_DEFINE_ENUM_TYPE(
SD_VARLINK_DEFINE_ENUM_TYPE(
BlockDeviceAction,
SD_VARLINK_FIELD_COMMENT("The device is currently present and a candidate. Emitted both during the initial enumeration and for live uevents (any action other than 'remove' is propagated as 'add', including the synthesized transitions when a device becomes empty or read-only and a relevant ignore* input is in effect)."),
SD_VARLINK_DEFINE_ENUM_VALUE(add),
@@ -93,9 +93,9 @@ static SD_VARLINK_DEFINE_METHOD_FULL(
SD_VARLINK_DEFINE_OUTPUT(subsystem, SD_VARLINK_STRING, SD_VARLINK_NULLABLE));
static SD_VARLINK_DEFINE_ERROR(NoCandidateDevices);
static SD_VARLINK_DEFINE_ERROR(ConflictingDiskLabelPresent);
static SD_VARLINK_DEFINE_ERROR(
SD_VARLINK_DEFINE_ERROR(NoCandidateDevices);
SD_VARLINK_DEFINE_ERROR(ConflictingDiskLabelPresent);
SD_VARLINK_DEFINE_ERROR(
InsufficientFreeSpace,
SD_VARLINK_FIELD_COMMENT("Minimal size of the disk required for the installation."),
SD_VARLINK_DEFINE_FIELD(minimalSizeBytes, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
@@ -103,7 +103,7 @@ static SD_VARLINK_DEFINE_ERROR(
SD_VARLINK_DEFINE_FIELD(needFreeBytes, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("Size of the selected block device."),
SD_VARLINK_DEFINE_FIELD(currentSizeBytes, SD_VARLINK_INT, SD_VARLINK_NULLABLE));
static SD_VARLINK_DEFINE_ERROR(
SD_VARLINK_DEFINE_ERROR(
DiskTooSmall,
SD_VARLINK_FIELD_COMMENT("Minimal size of the disk required for the installation."),
SD_VARLINK_DEFINE_FIELD(minimalSizeBytes, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
+6
View File
@@ -4,3 +4,9 @@
#include "sd-varlink-idl.h"
extern const sd_varlink_interface vl_interface_io_systemd_Repart;
extern const sd_varlink_symbol vl_type_BlockDeviceAction;
extern const sd_varlink_symbol vl_error_NoCandidateDevices;
extern const sd_varlink_symbol vl_error_ConflictingDiskLabelPresent;
extern const sd_varlink_symbol vl_error_InsufficientFreeSpace;
extern const sd_varlink_symbol vl_error_DiskTooSmall;
+125
View File
@@ -0,0 +1,125 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "sd-varlink-idl.h"
#include "varlink-io.systemd.SysInstall.h"
#include "varlink-io.systemd.Repart.h"
static SD_VARLINK_DEFINE_ENUM_TYPE(
ProgressPhase,
SD_VARLINK_DEFINE_ENUM_VALUE(encrypt_credentials),
SD_VARLINK_DEFINE_ENUM_VALUE(install_partitions),
SD_VARLINK_DEFINE_ENUM_VALUE(mount_partitions),
SD_VARLINK_DEFINE_ENUM_VALUE(install_kernel),
SD_VARLINK_DEFINE_ENUM_VALUE(install_bootloader),
SD_VARLINK_DEFINE_ENUM_VALUE(unmount_partitions));
static SD_VARLINK_DEFINE_ENUM_TYPE(
DeviceFit,
SD_VARLINK_DEFINE_ENUM_VALUE(enough_free_space),
SD_VARLINK_DEFINE_ENUM_VALUE(insufficent_free_space),
SD_VARLINK_DEFINE_ENUM_VALUE(disk_too_small),
SD_VARLINK_DEFINE_ENUM_VALUE(conflicting_disk_label_present));
static SD_VARLINK_DEFINE_STRUCT_TYPE(
Credential,
SD_VARLINK_FIELD_COMMENT("The id of the credential."),
SD_VARLINK_DEFINE_FIELD(id, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("The value of the credential in base64 encoding."),
SD_VARLINK_DEFINE_FIELD(value, SD_VARLINK_STRING, 0));
static SD_VARLINK_DEFINE_METHOD_FULL(
Run,
SD_VARLINK_SUPPORTS_MORE,
SD_VARLINK_FIELD_COMMENT("Full path to the block device node to operate on."),
SD_VARLINK_DEFINE_INPUT(node, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("Path to directory containing definition files."),
SD_VARLINK_DEFINE_INPUT(definitions, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("If true, fully erase the target block device."),
SD_VARLINK_DEFINE_INPUT(erase, SD_VARLINK_BOOL, 0),
SD_VARLINK_FIELD_COMMENT("If true, EFI variables are modified to register the installed boot loader in the firmware's boot options database."),
SD_VARLINK_DEFINE_INPUT(variables, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("The path to a kernel image, if missing the current kernel is dedected and used."),
SD_VARLINK_DEFINE_INPUT(kernelImagePath, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("If true, the current locale is copied to target system"),
SD_VARLINK_DEFINE_INPUT(copyLocale, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("If true, the current keymap is copied to target system"),
SD_VARLINK_DEFINE_INPUT(copyKeymap, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("If true, the current timezone is copied to target system"),
SD_VARLINK_DEFINE_INPUT(copyTimezone, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("A list of credentials to be installed to target system."),
SD_VARLINK_DEFINE_INPUT_BY_TYPE(credentials, Credential, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("If used with the 'more' flag, a phase identifier is sent in progress updates."),
SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(phase, ProgressPhase, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("If used with the 'more' flag, an object identifier string is sent in progress updates."),
SD_VARLINK_DEFINE_OUTPUT(object, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("If used with the 'more' flag, a progress percentage (specific to the work done for the specified phase+object is sent in progress updates)."),
SD_VARLINK_DEFINE_OUTPUT(progress, SD_VARLINK_INT, SD_VARLINK_NULLABLE));
static SD_VARLINK_DEFINE_METHOD_FULL(
ListCandidateDevices,
SD_VARLINK_REQUIRES_MORE,
SD_VARLINK_FIELD_COMMENT("Path to directory containing definition files, used to evaluate the fit of the target OS for each block device."),
SD_VARLINK_DEFINE_INPUT(definitions, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("If true, keep the call open after the initial enumeration and stream live add/remove notifications as block-subsystem uevents arrive. The end of the initial enumeration is marked by exactly one notification with action='ready' and no other fields. Defaults to false."),
SD_VARLINK_DEFINE_INPUT(subscribe, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("Discriminator field. Only set in subscribe mode. 'add' carries the full device record, 'remove' carries only node, 'ready' carries no other fields and is sent once after the initial enumeration."),
SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(action, BlockDeviceAction, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("The device node path of the block device."),
SD_VARLINK_DEFINE_OUTPUT(node, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("List of symlinks pointing to the device node, if any."),
SD_VARLINK_DEFINE_OUTPUT(symlinks, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("The Linux kernel disk sequence number identifying the medium."),
SD_VARLINK_DEFINE_OUTPUT(diskseq, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("The size of the block device in bytes."),
SD_VARLINK_DEFINE_OUTPUT(sizeBytes, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("The device vendor string if known."),
SD_VARLINK_DEFINE_OUTPUT(vendor, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("The device model string if known."),
SD_VARLINK_DEFINE_OUTPUT(model, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("The subsystem the block device belongs to if known."),
SD_VARLINK_DEFINE_OUTPUT(subsystem, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("The fit indicating whether the OS would have enough available space on the device."),
SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(fit, DeviceFit, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("Minimal size of the disk required for the installation."),
SD_VARLINK_DEFINE_OUTPUT(minimalSizeBytes, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("Additional free space needed for the installation."),
SD_VARLINK_DEFINE_OUTPUT(needFreeBytes, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("Current allocated size of this block device."),
SD_VARLINK_DEFINE_OUTPUT(currentSizeBytes, SD_VARLINK_INT, SD_VARLINK_NULLABLE));
SD_VARLINK_DEFINE_INTERFACE(
io_systemd_SysInstall,
"io.systemd.SysInstall",
SD_VARLINK_INTERFACE_COMMENT("API for installing the OS to another block device."),
SD_VARLINK_SYMBOL_COMMENT("Progress phase identifiers. Note that we might add more phases here, and thus identifiers. Frontends can choose to display the phase to the user in some human readable form, or not do that, but if they do it and they receive a notification for a so far unknown phase, they should just ignore it."),
&vl_type_ProgressPhase,
SD_VARLINK_SYMBOL_COMMENT("Description about the fit of an OS on a block device."),
&vl_type_DeviceFit,
SD_VARLINK_SYMBOL_COMMENT("Discriminator on streamed ListCandidateDevices replies in subscribe mode."),
&vl_type_BlockDeviceAction,
SD_VARLINK_SYMBOL_COMMENT("A credential to install to target OS."),
&vl_type_Credential,
SD_VARLINK_SYMBOL_COMMENT("Invoke the actual installation of the OS. If invoked with 'more' enabled will report progress, otherwise will just report completion."),
&vl_method_Run,
SD_VARLINK_SYMBOL_COMMENT("An incompatible disk label present, and not told to erase it."),
&vl_error_ConflictingDiskLabelPresent,
SD_VARLINK_SYMBOL_COMMENT("The target disk has insufficient free space to fit all requested partitions. (But the disk would fit, if emptied.)"),
&vl_error_InsufficientFreeSpace,
SD_VARLINK_SYMBOL_COMMENT("The target disk is too small to fit the installation. (Regardless if emptied or not.)"),
&vl_error_DiskTooSmall,
SD_VARLINK_SYMBOL_COMMENT("Return a list of candidate block devices, i.e. that support partition scanning and other requirements for successful operation."),
&vl_method_ListCandidateDevices,
SD_VARLINK_SYMBOL_COMMENT("Not a single candidate block device could be found."),
&vl_error_NoCandidateDevices);
@@ -0,0 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include "sd-varlink-idl.h"
extern const sd_varlink_interface vl_interface_io_systemd_SysInstall;
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?> <!--*-nxml-*-->
<!DOCTYPE policyconfig PUBLIC "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
"https://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
<!--
SPDX-License-Identifier: LGPL-2.1-or-later
This file is part of systemd.
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
-->
<policyconfig>
<vendor>The systemd Project</vendor>
<vendor_url>https://systemd.io</vendor_url>
<action id="io.systemd.sysinstall.Run">
<description gettext-domain="systemd">Install OS to disk</description>
<message gettext-domain="systemd">Authentication is required to install an OS to disk.</message>
<defaults>
<allow_any>auth_admin</allow_any>
<allow_inactive>auth_admin</allow_inactive>
<allow_active>auth_admin_keep</allow_active>
</defaults>
</action>
<action id="io.systemd.sysinstall.ListCandidateDevices">
<description gettext-domain="systemd">List candidate devices</description>
<message gettext-domain="systemd">Authentication is required to list device candidates.</message>
<defaults>
<allow_any>auth_admin</allow_any>
<allow_inactive>auth_admin</allow_inactive>
<allow_active>auth_admin_keep</allow_active>
</defaults>
</action>
</policyconfig>
+5
View File
@@ -8,3 +8,8 @@ executables += [
'sources' : files('sysinstall.c'),
},
]
if conf.get('ENABLE_SYSINSTALL') == 1
install_data('io.systemd.sysinstall.policy',
install_dir : polkitpolicydir)
endif
File diff suppressed because it is too large Load Diff
+9
View File
@@ -840,6 +840,15 @@ units = [
'conditions' : ['ENABLE_SYSINSTALL'],
'symlinks' : ['system-install.target.wants/'],
},
{
'file' : 'systemd-sysinstall.socket',
'conditions' : ['ENABLE_SYSINSTALL'],
'symlinks' : ['sockets.target.wants/'],
},
{
'file' : 'systemd-sysinstall@.service',
'conditions' : ['ENABLE_SYSINSTALL'],
},
{
'file' : 'systemd-sysupdate-reboot.service',
'conditions' : ['ENABLE_SYSUPDATE'],
+2
View File
@@ -14,6 +14,8 @@ Wants=systemd-logind.service
After=systemd-logind.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=systemd-sysinstall --variables=yes --reboot=yes --mute-console=yes
StandardOutput=tty
StandardInput=tty
+27
View File
@@ -0,0 +1,27 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=System Install Tool
Documentation=man:systemd-sysinstall(8)
DefaultDependencies=no
Before=sockets.target
Conflicts=shutdown.target
Before=shutdown.target
[Socket]
ListenStream=/run/systemd/io.systemd.SysInstall
Symlinks=/run/varlink/registry/io.systemd.SysInstall
FileDescriptorName=varlink
SocketMode=0666
Accept=yes
MaxConnectionsPerSource=16
XAttrEntryPoint=user.varlink=entrypoint
XAttrListen=user.varlink=listen
XAttrAccept=user.varlink=server
+20
View File
@@ -0,0 +1,20 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=System Install Tool
Documentation=man:systemd-sysinstall(8)
DefaultDependencies=no
Wants=modprobe@loop.service modprobe@dm_mod.service
After=modprobe@loop.service modprobe@dm_mod.service systemd-tpm2-setup-early.service
Conflicts=shutdown.target
Before=shutdown.target
[Service]
ExecStart=systemd-sysinstall