]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
report: separate report generation from upload
authorLennart Poettering <lennart@amutable.com>
Sun, 14 Jun 2026 05:48:36 +0000 (07:48 +0200)
committerLennart Poettering <lennart@amutable.com>
Fri, 19 Jun 2026 03:00:06 +0000 (05:00 +0200)
Let's split report generation from uploading, as prepatory step for
adding signing for reports.

No real code changes, just moving things around.

src/report/meson.build
src/report/report-generate.c [new file with mode: 0644]
src/report/report-generate.h [new file with mode: 0644]
src/report/report-upload.c
src/report/report-upload.h [new file with mode: 0644]
src/report/report.c
src/report/report.h

index 5f05382999eb81aa2983e8e284b2696c44e30c3f..e64f74ee4ef4977a694d36b5da4b6c364b2638a4 100644 (file)
@@ -6,6 +6,7 @@ executables += [
                 'public' : true,
                 'sources' : files(
                         'report.c',
+                        'report-generate.c',
                         'report-upload.c',
                 ),
         },
diff --git a/src/report/report-generate.c b/src/report/report-generate.c
new file mode 100644 (file)
index 0000000..edac44a
--- /dev/null
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "sd-json.h"
+
+#include "log.h"
+#include "report.h"
+#include "report-generate.h"
+#include "time-util.h"
+
+int context_build_report(Context *context, sd_json_variant **ret) {
+        int r;
+
+        /* Convert the variant array to a JSON report. */
+
+        assert(context);
+        assert(ret);
+
+        usec_t ts = now(CLOCK_REALTIME);
+
+        _cleanup_(sd_json_variant_unrefp) sd_json_variant *report = NULL;
+        r = sd_json_buildo(&report,
+                           SD_JSON_BUILD_PAIR_STRING("mediaType", "application/vnd.io.systemd.report"),
+                           SD_JSON_BUILD_PAIR("timestamp",
+                                              SD_JSON_BUILD_STRING(FORMAT_TIMESTAMP_STYLE(ts, TIMESTAMP_UTC))),
+                           SD_JSON_BUILD_PAIR("metrics",
+                                              SD_JSON_BUILD_VARIANT_ARRAY(context->metrics, context->n_metrics)));
+        if (r < 0)
+                return log_error_errno(r, "Failed to build JSON data: %m");
+
+        *ret = TAKE_PTR(report);
+        return 0;
+}
+
+int context_generate_report(Context *context) {
+        int r;
+
+        assert(context);
+
+        /* Make a structured report and either print it or upload it. */
+
+        _cleanup_(sd_json_variant_unrefp) sd_json_variant *report = NULL;
+        r = context_build_report(context, &report);
+        if (r < 0)
+                return r;
+
+        r = sd_json_variant_dump(report, arg_json_format_flags, /* f= */ NULL, /* prefix= */ NULL);
+        if (r < 0)
+                return log_error_errno(r, "Failed to dump json object: %m");
+
+        return 0;
+}
diff --git a/src/report/report-generate.h b/src/report/report-generate.h
new file mode 100644 (file)
index 0000000..acde3db
--- /dev/null
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include "report.h"
+
+int context_build_report(Context *context, sd_json_variant **ret);
+
+int context_generate_report(Context *context);
index 02f15cba61091d19cac0295bfd009a5d4ce1c981..17ef327db0140809da4b10863c8c45149ebf6226 100644 (file)
@@ -6,6 +6,8 @@
 #include "errno-util.h"
 #include "log.h"
 #include "report.h"
+#include "report-generate.h"
+#include "report-upload.h"
 #include "string-util.h"
 #include "strv.h"
 #include "time-util.h"
 #include "varlink-util.h"
 #include "version.h"
 
+#define REPORT_UPLOAD_DIR "/run/systemd/report.upload"
+#define SERVER_ANSWER_MAX (1U * 1024U * 1024U)
+
 #if HAVE_LIBCURL
 #include "curl-util.h"
 
-#define SERVER_ANSWER_MAX (1*1024*1024u)
-
 static size_t output_callback(char *buf,
                               size_t size,
                               size_t nmemb,
@@ -54,26 +57,6 @@ static size_t output_callback(char *buf,
 }
 #endif
 
-static int build_json_report(Context *context, sd_json_variant **ret) {
-        /* Convert the variant array to a JSON report. */
-
-        assert(context);
-        assert(ret);
-
-        usec_t ts = now(CLOCK_REALTIME);
-        int r;
-
-        r = sd_json_buildo(ret,
-                           SD_JSON_BUILD_PAIR_STRING("mediaType", "application/vnd.io.systemd.report"),
-                           SD_JSON_BUILD_PAIR("timestamp",
-                                              SD_JSON_BUILD_STRING(FORMAT_TIMESTAMP_STYLE(ts, TIMESTAMP_UTC))),
-                           SD_JSON_BUILD_PAIR("metrics",
-                                              SD_JSON_BUILD_VARIANT_ARRAY(context->metrics, context->n_metrics)));
-        if (r < 0)
-                return log_error_errno(r, "Failed to build JSON data: %m");
-        return 0;
-}
-
 static int http_upload_collected(Context *context, sd_json_variant *report) {
 #if HAVE_LIBCURL
         _cleanup_(curl_slist_free_allp) struct curl_slist *header = NULL;
@@ -235,9 +218,14 @@ static int execute_dir_reply(
         return 0;
 }
 
-static int upload_collected(Context *context, sd_json_variant *report) {
+int context_upload_report(Context *context) {
         int r;
 
+        _cleanup_(sd_json_variant_unrefp) sd_json_variant *report = NULL;
+        r = context_build_report(context, &report);
+        if (r < 0)
+                return r;
+
         if (arg_url)
                 return http_upload_collected(context, report);
 
@@ -267,23 +255,3 @@ static int upload_collected(Context *context, sd_json_variant *report) {
         log_debug("Upload via %s finished successfully.", REPORT_UPLOAD_DIR);
         return 0;
 }
-
-/* Make a structured report and either print it or upload it. */
-int report_collected(Context *context) {
-        _cleanup_(sd_json_variant_unrefp) sd_json_variant *report = NULL;
-        int r;
-
-        r = build_json_report(context, &report);
-        if (r < 0)
-                return r;
-
-        if (context->action == ACTION_UPLOAD)
-                return upload_collected(context, report);
-
-        /* Just print the report for now. */
-        assert(context->action == ACTION_GENERATE);
-        r = sd_json_variant_dump(report, arg_json_format_flags, /* f= */ NULL, /* prefix= */ NULL);
-        if (r < 0)
-                return log_error_errno(r, "Failed to dump json object: %m");
-        return 0;
-}
diff --git a/src/report/report-upload.h b/src/report/report-upload.h
new file mode 100644 (file)
index 0000000..eb4cb87
--- /dev/null
@@ -0,0 +1,6 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include "report.h"
+
+int context_upload_report(Context *context);
index 9c951f983231094d9afa6cefc72a49df2807a1fc..c3af61f01ddcf87eb75352068931776bed7de04b 100644 (file)
@@ -16,6 +16,8 @@
 #include "path-lookup.h"
 #include "recurse-dir.h"
 #include "report.h"
+#include "report-generate.h"
+#include "report-upload.h"
 #include "runtime-scope.h"
 #include "set.h"
 #include "sort-util.h"
@@ -656,10 +658,24 @@ static int verb_metrics(int argc, char *argv[], uintptr_t data, void *userdata)
                 if (r < 0)
                         return log_error_errno(r, "Failed to run event loop: %m");
 
-                if (IN_SET(action, ACTION_GENERATE, ACTION_UPLOAD))
-                        r = report_collected(&context);
-                else
+                switch (action) {
+
+                case ACTION_LIST_METRICS:
+                case ACTION_DESCRIBE_METRICS:
                         r = output_collected(&context);
+                        break;
+
+                case ACTION_GENERATE:
+                        r = context_generate_report(&context);
+                        break;
+
+                case ACTION_UPLOAD:
+                        r = context_upload_report(&context);
+                        break;
+
+                default:
+                        assert_not_reached();
+                }
                 if (r < 0)
                         return r;
         }
index 343175523378e2d9498e7424bf5dbd56b966d761..51d55344f965bc24825fc1daf6f56c12cdc5e4b5 100644 (file)
@@ -9,8 +9,6 @@
 #define REPORT_CERT_FILE     CERTIFICATE_ROOT "/certs/systemd-report.pem"
 #define REPORT_TRUST_FILE    CERTIFICATE_ROOT "/ca/trusted.pem"
 
-#define REPORT_UPLOAD_DIR "/run/systemd/report.upload"
-
 extern sd_json_format_flags_t arg_json_format_flags;
 extern char *arg_url, *arg_key, *arg_cert, *arg_trust;
 extern char **arg_extra_headers;
@@ -36,5 +34,3 @@ typedef struct Context {
         int upload_result;
         struct iovec_wrapper upload_answer;
 } Context;
-
-int report_collected(Context *context);