sysext: refresh sysexts and confexts on completed system update
Bind the io.systemd.SysUpdate.Notify.OnCompletedUpdate() method in the sysext Varlink server. systemd-sysext provides a single Varlink service covering both the sysext and confext image classes, so one notification refreshes both (equivalent to "systemd-sysext refresh" plus "systemd-confext refresh"). Hook a socket into /run/systemd/sysupdate/notify/ via systemd-sysupdate-notify-sysext.socket, enabled by default via the preset.
This commit is contained in:
@@ -42,6 +42,7 @@ enable systemd-resolved.service
|
||||
enable systemd-sysext.service
|
||||
enable systemd-sysupdate-notify-bootctl.socket
|
||||
enable systemd-sysupdate-notify-pcrlock.socket
|
||||
enable systemd-sysupdate-notify-sysext.socket
|
||||
enable systemd-timesyncd.service
|
||||
enable systemd-tpm2-clear.service
|
||||
enable systemd-userdbd.socket
|
||||
|
||||
+44
-3
@@ -68,6 +68,7 @@
|
||||
#include "strv.h"
|
||||
#include "time-util.h"
|
||||
#include "unit-name.h"
|
||||
#include "varlink-io.systemd.SysUpdate.Notify.h"
|
||||
#include "varlink-io.systemd.sysext.h"
|
||||
#include "varlink-util.h"
|
||||
#include "verbs.h"
|
||||
@@ -2898,6 +2899,42 @@ static int vl_method_refresh(sd_varlink *link, sd_json_variant *parameters, sd_v
|
||||
return sd_varlink_reply(link, NULL);
|
||||
}
|
||||
|
||||
static int refresh_class(ImageClass image_class) {
|
||||
_cleanup_strv_free_ char **hierarchies = NULL;
|
||||
int r;
|
||||
|
||||
r = parse_env_extension_hierarchies(&hierarchies, image_class_info[image_class].name_env);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to determine %s hierarchies: %m", image_class_info[image_class].short_identifier);
|
||||
|
||||
return refresh(image_class, hierarchies, arg_force, arg_no_reload, arg_always_refresh, arg_noexec);
|
||||
}
|
||||
|
||||
static int vl_method_on_completed_update(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
|
||||
/* Only honour update notifications if they come from root */
|
||||
r = varlink_check_privileged_peer(link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* Triggered by systemd-sysupdate after an update completed. We deliberately ignore all parameters
|
||||
* (we don't even dispatch them). This method is reached through the sysext socket, but a single
|
||||
* notification refreshes both image classes, so freshly downloaded sysexts and confexts are both
|
||||
* picked up, equivalent to "systemd-sysext refresh" plus "systemd-confext refresh". We attempt both
|
||||
* classes and only fail afterwards, so a problem with one does not prevent refreshing the other. */
|
||||
|
||||
r = 0;
|
||||
RET_GATHER(r, refresh_class(IMAGE_SYSEXT));
|
||||
RET_GATHER(r, refresh_class(IMAGE_CONFEXT));
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return sd_varlink_reply(link, NULL);
|
||||
}
|
||||
|
||||
VERB_NOARG(verb_list, "list", "List installed extensions");
|
||||
static int verb_list(int argc, char *argv[], uintptr_t _data, void *userdata) {
|
||||
_cleanup_hashmap_free_ Hashmap *images = NULL;
|
||||
@@ -3184,16 +3221,20 @@ static int run(int argc, char *argv[]) {
|
||||
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_sysext);
|
||||
r = sd_varlink_server_add_interface_many(
|
||||
varlink_server,
|
||||
&vl_interface_io_systemd_sysext,
|
||||
&vl_interface_io_systemd_SysUpdate_Notify);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add Varlink interface: %m");
|
||||
return log_error_errno(r, "Failed to add Varlink interfaces: %m");
|
||||
|
||||
r = sd_varlink_server_bind_method_many(
|
||||
varlink_server,
|
||||
"io.systemd.sysext.Merge", vl_method_merge,
|
||||
"io.systemd.sysext.Unmerge", vl_method_unmerge,
|
||||
"io.systemd.sysext.Refresh", vl_method_refresh,
|
||||
"io.systemd.sysext.List", vl_method_list);
|
||||
"io.systemd.sysext.List", vl_method_list,
|
||||
"io.systemd.SysUpdate.Notify.OnCompletedUpdate", vl_method_on_completed_update);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to bind Varlink methods: %m");
|
||||
|
||||
|
||||
@@ -823,6 +823,14 @@ units = [
|
||||
'conditions' : ['ENABLE_SYSEXT'],
|
||||
'symlinks' : ['sockets.target.wants/'],
|
||||
},
|
||||
{
|
||||
'file' : 'systemd-sysupdate-notify-sysext@.service',
|
||||
'conditions' : ['ENABLE_SYSEXT'],
|
||||
},
|
||||
{
|
||||
'file' : 'systemd-sysupdate-notify-sysext.socket',
|
||||
'conditions' : ['ENABLE_SYSEXT'],
|
||||
},
|
||||
{
|
||||
'file' : 'systemd-sysext@.service',
|
||||
'conditions' : ['ENABLE_SYSEXT'],
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
# 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 Extension and Configuration Refresh on Completed System Update
|
||||
Documentation=man:systemd-sysext(8)
|
||||
DefaultDependencies=no
|
||||
After=local-fs.target
|
||||
Before=sockets.target
|
||||
ConditionCapability=CAP_SYS_ADMIN
|
||||
|
||||
[Socket]
|
||||
ListenStream=/run/systemd/sysupdate/notify/io.systemd.sysext
|
||||
FileDescriptorName=varlink
|
||||
SocketMode=0644
|
||||
Accept=yes
|
||||
MaxConnectionsPerSource=16
|
||||
XAttrEntryPoint=user.varlink=entrypoint
|
||||
XAttrListen=user.varlink=listen
|
||||
XAttrAccept=user.varlink=server
|
||||
|
||||
[Install]
|
||||
WantedBy=sockets.target
|
||||
@@ -0,0 +1,19 @@
|
||||
# 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 Extension and Configuration Refresh on Completed System Update
|
||||
Documentation=man:systemd-sysext(8)
|
||||
DefaultDependencies=no
|
||||
Conflicts=shutdown.target initrd-switch-root.target
|
||||
After=local-fs.target
|
||||
Before=shutdown.target initrd-switch-root.target
|
||||
|
||||
[Service]
|
||||
ExecStart=-systemd-sysext
|
||||
Reference in New Issue
Block a user