]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
portable: log structured message when attach/detach succeeds
authorLuca Boccassi <bluca@debian.org>
Thu, 18 Jan 2024 19:32:47 +0000 (19:32 +0000)
committerLennart Poettering <lennart@poettering.net>
Fri, 19 Jan 2024 16:03:04 +0000 (17:03 +0100)
Currently portabled is completely silent (when not using debug level). But
when the system state is changed (ie: a portable is attached or detached)
there are no traces left in the journal. Log at info level when either of
those operations succeed, as they are effectively changing the state of
the system.

Create new MESSAGE_IDs for these logs, and also append PORTABLE_ROOT=
(and PORTABLE_EXTENSION= if any), like the units themselves are
configured to do via LogExtraFields=, so that the same metadata can
be found in the attach/detach messages and in logs from the units
themselves.

catalog/systemd.catalog.in
src/portable/portable.c
src/systemd/sd-messages.h

index 8591a654aa5b6ebac7aa1181437355cff3a2dde3..04e90e0b75fdbddd26b78f069dd4efb7f9024d80 100644 (file)
@@ -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'.
index d4b448a6274ab2f892716e24da75a1f10eb435fd..6054f0f17f8de20f2e8c09795309166169e1c0a7 100644 (file)
@@ -2,6 +2,8 @@
 
 #include <linux/loop.h>
 
+#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:
index b220fa0113d62a7944618b8b2db99b5b1219c2ab..e3f68068a8437caedd4cdee78bdffedd4ade479f 100644 (file)
@@ -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