diff --git a/catalog/systemd.catalog.in b/catalog/systemd.catalog.in index 8591a654aa..04e90e0b75 100644 --- a/catalog/systemd.catalog.in +++ b/catalog/systemd.catalog.in @@ -748,3 +748,23 @@ Compatibility support for System V services in systemd is deprecated. Please make sure to update the package in question to provide proper, native systemd unit files. Contact vendor if necessary. Compatibility support for System V services is deprecated and will be removed soon. + +-- 187c62eb1e7f463bb530394f52cb090f +Subject: A Portable Service has been attached +Defined-By: systemd +Support: %SUPPORT_URL% +Documentation: https://systemd.io/PORTABLE_SERVICES/ + +A new Portable Service @PORTABLE_ROOT@ (with extensions: @PORTABLE_EXTENSION@) has +been attached to the system and is now available for use. The list of attached +Portable Services can be queried with 'portablectl list'. + +-- 76c5c754d628490d8ecba4c9d042112b +Subject: A Portable Service has been detached +Defined-By: systemd +Support: %SUPPORT_URL% +Documentation: https://systemd.io/PORTABLE_SERVICES/ + +A Portable Service @PORTABLE_ROOT@ (with extensions: @PORTABLE_EXTENSION@) has been +detached from the system and is no longer available for use. The list of attached +Portable Services can be queried with 'portablectl list'. diff --git a/src/portable/portable.c b/src/portable/portable.c index d4b448a627..6054f0f17f 100644 --- a/src/portable/portable.c +++ b/src/portable/portable.c @@ -2,6 +2,8 @@ #include +#include "sd-messages.h" + #include "bus-common-errors.h" #include "bus-error.h" #include "bus-locator.h" @@ -1430,6 +1432,78 @@ static bool prefix_matches_compatible(char **matches, char **valid_prefixes) { return true; } +static void log_portable_verb( + const char *verb, + const char *message_id, + const char *image_path, + OrderedHashmap *extension_images, + char **extension_image_paths, + PortableFlags flags) { + + _cleanup_free_ char *root_base_name = NULL, *extensions_joined = NULL; + _cleanup_strv_free_ char **extension_base_names = NULL; + Image *ext; + int r; + + assert(verb); + assert(message_id); + assert(image_path); + assert(!extension_images || !extension_image_paths); + + /* Use the same structured metadata as it is attached to units via LogExtraFields=. The main image + * is logged as PORTABLE_ROOT= and extensions, if any, as individual PORTABLE_EXTENSION= fields. */ + + r = path_extract_filename(image_path, &root_base_name); + if (r < 0) + log_debug_errno(r, "Failed to extract basename from '%s', ignoring: %m", image_path); + + ORDERED_HASHMAP_FOREACH(ext, extension_images) { + _cleanup_free_ char *extension_base_name = NULL; + + r = path_extract_filename(ext->path, &extension_base_name); + if (r < 0) { + log_debug_errno(r, "Failed to extract basename from '%s', ignoring: %m", ext->path); + continue; + } + + r = strv_extendf(&extension_base_names, "PORTABLE_EXTENSION=%s", extension_base_name); + if (r < 0) + log_oom_debug(); + + if (!strextend_with_separator(&extensions_joined, ", ", ext->path)) + log_oom_debug(); + } + + STRV_FOREACH(e, extension_image_paths) { + _cleanup_free_ char *extension_base_name = NULL; + + r = path_extract_filename(*e, &extension_base_name); + if (r < 0) { + log_debug_errno(r, "Failed to extract basename from '%s', ignoring: %m", *e); + continue; + } + + r = strv_extendf(&extension_base_names, "PORTABLE_EXTENSION=%s", extension_base_name); + if (r < 0) + log_oom_debug(); + + if (!strextend_with_separator(&extensions_joined, ", ", *e)) + log_oom_debug(); + } + + LOG_CONTEXT_PUSH_STRV(extension_base_names); + + log_struct(LOG_INFO, + LOG_MESSAGE("Successfully %s%s '%s%s%s'", + verb, + FLAGS_SET(flags, PORTABLE_RUNTIME) ? " ephemeral" : "", + image_path, + isempty(extensions_joined) ? "" : "' and its extension(s) '", + strempty(extensions_joined)), + message_id, + "PORTABLE_ROOT=%s", strna(root_base_name)); +} + int portable_attach( sd_bus *bus, const char *name_or_path, @@ -1538,6 +1612,14 @@ int portable_attach( * operation otherwise. */ (void) install_image_and_extensions_symlinks(image, extension_images, flags, changes, n_changes); + log_portable_verb( + "attached", + "MESSAGE_ID=" SD_MESSAGE_PORTABLE_ATTACHED_STR, + image->path, + extension_images, + /* extension_image_paths= */ NULL, + flags); + return 0; } @@ -1861,6 +1943,14 @@ int portable_detach( if (rmdir(where) >= 0) portable_changes_add(changes, n_changes, PORTABLE_UNLINK, where, NULL); + log_portable_verb( + "detached", + "MESSAGE_ID=" SD_MESSAGE_PORTABLE_DETACHED_STR, + name_or_path, + /* extension_images= */ NULL, + extension_image_paths, + flags); + return ret; not_found: diff --git a/src/systemd/sd-messages.h b/src/systemd/sd-messages.h index b220fa0113..e3f68068a8 100644 --- a/src/systemd/sd-messages.h +++ b/src/systemd/sd-messages.h @@ -267,6 +267,11 @@ _SD_BEGIN_DECLARATIONS; #define SD_MESSAGE_SYSV_GENERATOR_DEPRECATED SD_ID128_MAKE(a8,fa,8d,ac,db,1d,44,3e,95,03,b8,be,36,7a,6a,db) #define SD_MESSAGE_SYSV_GENERATOR_DEPRECATED_STR SD_ID128_MAKE_STR(a8,fa,8d,ac,db,1d,44,3e,95,03,b8,be,36,7a,6a,db) +#define SD_MESSAGE_PORTABLE_ATTACHED SD_ID128_MAKE(18,7c,62,eb,1e,7f,46,3b,b5,30,39,4f,52,cb,09,0f) +#define SD_MESSAGE_PORTABLE_ATTACHED_STR SD_ID128_MAKE_STR(18,7c,62,eb,1e,7f,46,3b,b5,30,39,4f,52,cb,09,0f) +#define SD_MESSAGE_PORTABLE_DETACHED SD_ID128_MAKE(76,c5,c7,54,d6,28,49,0d,8e,cb,a4,c9,d0,42,11,2b) +#define SD_MESSAGE_PORTABLE_DETACHED_STR SD_ID128_MAKE_STR(76,c5,c7,54,d6,28,49,0d,8e,cb,a4,c9,d0,42,11,2b) + _SD_END_DECLARATIONS; #endif