the symlink target. Previously, these were only expanded in the
source.
+ * As part of changes to systemd-sysupdate, the existing
+ "systemd-sysupdate.service" and "systemd-sysupdate.timer" units –
+ which periodically ran "systemd-sysupdate" to update the host system –
+ have been renamed to "systemd-sysupdate-update.service" and
+ "systemd-sysupdate-update.timer" respectively. Compatibility symlinks
+ have been provided. This clears the way for a new
+ "systemd-sysupdate@.service" unit for varlink activation of sysupdate.
+
CHANGES WITH 261:
Announcements of Future Feature Removals and Incompatible Changes:
'8',
['systemd-sysupdate-reboot.service',
'systemd-sysupdate-reboot.timer',
+ 'systemd-sysupdate-update.service',
+ 'systemd-sysupdate-update.timer',
'systemd-sysupdate.service',
'systemd-sysupdate.timer'],
'ENABLE_SYSUPDATE'],
<refnamediv>
<refname>systemd-sysupdate</refname>
- <refname>systemd-sysupdate.service</refname>
- <refname>systemd-sysupdate.timer</refname>
+ <refname>systemd-sysupdate-update.service</refname>
+ <refname>systemd-sysupdate-update.timer</refname>
<refname>systemd-sysupdate-reboot.service</refname>
<refname>systemd-sysupdate-reboot.timer</refname>
+
+ <!-- Compatibility symlinks for old names of systemd-sysupdate-update.{service,timer} -->
+ <refname>systemd-sysupdate.service</refname>
+ <refname>systemd-sysupdate.timer</refname>
+
<refpurpose>Automatically Update OS or Other Resources</refpurpose>
</refnamediv>
<arg choice="opt" rep="repeat">OPTIONS</arg>
</cmdsynopsis>
- <para><filename>systemd-sysupdate.service</filename></para>
+ <para><filename>systemd-sysupdate-update.service</filename></para>
</refsynopsisdiv>
<refsect1>
embedded in the disk images. For the latter, see <option>--image=</option> below. The latter is
particularly interesting to update container images or portable service images.</para>
- <para>The <filename>systemd-sysupdate.service</filename> system service will automatically update the
+ <para>The <filename>systemd-sysupdate-update.service</filename> system service will automatically update the
host OS based on the installed transfer files. It is triggered in regular intervals via
- <filename>systemd-sysupdate.timer</filename>. The <filename>systemd-sysupdate-reboot.service</filename>
+ <filename>systemd-sysupdate-update.timer</filename>. The <filename>systemd-sysupdate-reboot.service</filename>
will automatically reboot the system after a new version is installed. It is triggered via
<filename>systemd-sysupdate-reboot.timer</filename>. The two services are separate from each other as it
is typically advisable to download updates regularly while the system is up, but delay reboots until the
#include "varlink-io.systemd.Resolve.Monitor.h"
#include "varlink-io.systemd.Shutdown.h"
#include "varlink-io.systemd.StorageProvider.h"
+#include "varlink-io.systemd.SysUpdate.h"
#include "varlink-io.systemd.SysUpdate.Notify.h"
#include "varlink-io.systemd.Udev.h"
#include "varlink-io.systemd.Unit.h"
&vl_interface_io_systemd_Resolve_Monitor,
&vl_interface_io_systemd_Shutdown,
&vl_interface_io_systemd_StorageProvider,
+ &vl_interface_io_systemd_SysUpdate,
&vl_interface_io_systemd_SysUpdate_Notify,
&vl_interface_io_systemd_Udev,
&vl_interface_io_systemd_Unit,
'varlink-io.systemd.Resolve.Monitor.c',
'varlink-io.systemd.Shutdown.c',
'varlink-io.systemd.StorageProvider.c',
+ 'varlink-io.systemd.SysUpdate.c',
'varlink-io.systemd.SysUpdate.Notify.c',
'varlink-io.systemd.Udev.c',
'varlink-io.systemd.Unit.c',
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "bus-polkit.h"
+#include "varlink-io.systemd.SysUpdate.h"
+
+SD_VARLINK_DEFINE_INTERFACE(
+ io_systemd_SysUpdate,
+ "io.systemd.SysUpdate",
+ SD_VARLINK_INTERFACE_COMMENT("APIs to manage system updates"));
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include "sd-varlink-idl.h"
+
+extern const sd_varlink_interface vl_interface_io_systemd_SysUpdate;
#include <unistd.h>
+#include "sd-bus.h"
#include "sd-daemon.h"
#include "sd-json.h"
#include "sd-varlink.h"
#include "build.h"
+#include "bus-polkit.h"
#include "conf-files.h"
#include "constants.h"
#include "dissect-image.h"
#include "help-util.h"
#include "hexdecoct.h"
#include "image-policy.h"
+#include "json-util.h"
#include "loop-util.h"
#include "main-func.h"
#include "mount-util.h"
#include "sysupdate-transfer.h"
#include "sysupdate-update-set.h"
#include "sysupdate-util.h"
+#include "varlink-io.systemd.SysUpdate.h"
#include "varlink-util.h"
#include "verbs.h"
static ImagePolicy *arg_image_policy = NULL;
static bool arg_offline = false;
static char *arg_transfer_source = NULL;
+static bool arg_varlink = false;
STATIC_DESTRUCTOR_REGISTER(arg_definitions, freep);
STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
return 0;
}
+/* Stores any long-running server state which needs to persist between varlink calls, such as state for
+ * pending polkit requests */
+typedef struct Server {
+ sd_bus *system_bus;
+ Hashmap *polkit_registry;
+} Server;
+
+#define SERVER_NULL \
+ (Server) { \
+ /* all fields fine with being initialised to NULL */ \
+ }
+
+static void server_done(Server *s) {
+ assert(s);
+
+ s->polkit_registry = hashmap_free(s->polkit_registry);
+ s->system_bus = sd_bus_flush_close_unref(s->system_bus);
+}
+
static DEFINE_POINTER_ARRAY_FREE_FUNC(Transfer*, transfer_free);
static int read_definitions(
return 1;
}
+static int verify_polkit(Context *context, sd_varlink *link, const char *action, const char **details) {
+ int r;
+ Server *s = ASSERT_PTR(sd_varlink_get_userdata(ASSERT_PTR(link)));
+
+ assert(context);
+
+ if (!s->system_bus) {
+ r = sd_bus_open_system_with_description(&s->system_bus, "sysupdate-system");
+ if (r < 0)
+ return log_error_errno(r, "Failed to get system bus connection: %m");
+
+ r = sd_bus_attach_event(s->system_bus, sd_varlink_get_event(link), SD_EVENT_PRIORITY_NORMAL);
+ if (r < 0)
+ return log_error_errno(r, "Failed to attach system bus to event loop: %m");
+ }
+
+ return varlink_verify_polkit_async(link,
+ s->system_bus,
+ action,
+ details,
+ &s->polkit_registry);
+}
+
VERB(verb_list, "list", "[VERSION]", VERB_ANY, 2, VERB_DEFAULT,
"Show installed and available versions");
static int verb_list(int argc, char *argv[], uintptr_t _data, void *userdata) {
if (arg_definitions && arg_component)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "The --definitions= and --component= switches may not be combined.");
+ r = sd_varlink_invocation(SD_VARLINK_ALLOW_ACCEPT);
+ if (r < 0)
+ return log_error_errno(r, "Failed to check if invoked in Varlink mode: %m");
+ if (r > 0)
+ arg_varlink = true;
+
*remaining_args = option_parser_get_args(&opts);
return 1;
}
+static int vl_server(void) {
+ _cleanup_(sd_varlink_server_unrefp) sd_varlink_server *varlink_server = NULL;
+ _cleanup_(server_done) Server server = SERVER_NULL;
+ int r;
+
+ r = varlink_server_new(&varlink_server,
+ SD_VARLINK_SERVER_ACCOUNT_UID|SD_VARLINK_SERVER_INHERIT_USERDATA,
+ &server);
+ if (r < 0)
+ return log_error_errno(r, "Failed to allocate Varlink server: %m");
+
+ r = sd_varlink_server_add_interface(varlink_server, &vl_interface_io_systemd_SysUpdate);
+ if (r < 0)
+ return log_error_errno(r, "Failed to add Varlink interface: %m");
+
+ r = sd_varlink_server_bind_method_many(
+ varlink_server);
+ if (r < 0)
+ return log_error_errno(r, "Failed to bind Varlink method: %m");
+
+ r = sd_varlink_server_loop_auto(varlink_server);
+ if (r < 0)
+ return log_error_errno(r, "Failed to run Varlink event loop: %m");
+
+ return 0;
+}
+
static int run(int argc, char *argv[]) {
int r;
if (r <= 0)
return r;
+ if (arg_varlink)
+ return vl_server(); /* Invocation as Varlink service */
+
return dispatch_verb(args, NULL);
}
'conditions' : ['ENABLE_SYSUPDATE'],
},
{
- 'file' : 'systemd-sysupdate.service',
+ 'file' : 'systemd-sysupdate-update.service',
'conditions' : ['ENABLE_SYSUPDATE'],
+ 'symlinks' : ['systemd-sysupdate.service'], # compatibility after rename
},
{
- 'file' : 'systemd-sysupdate.timer',
+ 'file' : 'systemd-sysupdate@.service',
'conditions' : ['ENABLE_SYSUPDATE'],
},
+ {
+ 'file' : 'systemd-sysupdate.socket',
+ 'conditions' : ['ENABLE_SYSUPDATE'],
+ 'symlinks' : ['sockets.target.wants/'],
+ },
+ {
+ 'file' : 'systemd-sysupdate-update.timer',
+ 'conditions' : ['ENABLE_SYSUPDATE'],
+ 'symlinks' : ['systemd-sysupdate.timer'], # compatibility after rename
+ },
{
'file' : 'systemd-sysupdated.service.in',
'conditions' : ['ENABLE_SYSUPDATED'],
[Unit]
Description=Automatic System Update
-Documentation=man:systemd-sysupdate.service(8)
+Documentation=man:systemd-sysupdate-update.service(8)
Wants=network-online.target
After=network-online.target
ConditionVirtualization=!container
Type=simple
NotifyAccess=main
ExecStart=systemd-sysupdate update --cleanup=yes
+
+# Keep this sandboxing synchronised with systemd-sysupdate@.service
CapabilityBoundingSet=CAP_CHOWN CAP_FOWNER CAP_FSETID CAP_MKNOD CAP_SETFCAP CAP_SYS_ADMIN CAP_SETPCAP CAP_DAC_OVERRIDE CAP_LINUX_IMMUTABLE
NoNewPrivileges=yes
MemoryDenyWriteExecute=yes
LockPersonality=yes
[Install]
-Also=systemd-sysupdate.timer
+Also=systemd-sysupdate-update.timer
[Unit]
Description=Automatic System Update
-Documentation=man:systemd-sysupdate.service(8)
+Documentation=man:systemd-sysupdate-update.service(8)
# For containers we assume that the manager will handle updates. And we likely
# can't even access our backing block device anyway.
--- /dev/null
+# 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 Updates
+Documentation=man:systemd-sysupdate(8)
+DefaultDependencies=no
+Before=sockets.target
+
+[Socket]
+ListenStream=/run/systemd/io.systemd.SysUpdate
+Symlinks=/run/varlink/registry/io.systemd.SysUpdate
+FileDescriptorName=varlink
+SocketMode=0666
+Accept=yes
+MaxConnectionsPerSource=16
+XAttrEntryPoint=user.varlink=entrypoint
+XAttrListen=user.varlink=listen
+XAttrAccept=user.varlink=server
+
+[Install]
+WantedBy=sockets.target
--- /dev/null
+# 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 Updates
+Documentation=man:systemd-sysupdate(8)
+DefaultDependencies=no
+Conflicts=shutdown.target
+Before=shutdown.target
+
+[Service]
+ExecStart=-systemd-sysupdate
+
+# Keep this sandboxing synchronised with systemd-sysupdate-update.service
+CapabilityBoundingSet=CAP_CHOWN CAP_FOWNER CAP_FSETID CAP_MKNOD CAP_SETFCAP CAP_SYS_ADMIN CAP_SETPCAP CAP_DAC_OVERRIDE CAP_LINUX_IMMUTABLE
+NoNewPrivileges=yes
+MemoryDenyWriteExecute=yes
+ProtectHostname=yes
+RestrictRealtime=yes
+RestrictNamespaces=net
+RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
+SystemCallFilter=@system-service @mount
+SystemCallErrorNumber=EPERM
+SystemCallArchitectures=native
+LockPersonality=yes