report: fold io.systemd.Basic facts into metrics

We removed the concept of facts, so we need to update the existing
io.systemd.Basic facts provider to metrics. This commit does just
that. Its mostly mechanical.

This also means that facts.{c,h} and varlink-io.systemd.Facts.{c,h}
are gone now.
This commit is contained in:
Michael Vogt
2026-05-05 18:13:28 +02:00
committed by Zbigniew Jędrzejewski-Szmek
parent ffd4e7ab01
commit 628ab0040e
11 changed files with 63 additions and 267 deletions
+10 -3
View File
@@ -4,12 +4,12 @@
#include "ansi-color.h"
#include "build.h"
#include "facts.h"
#include "format-table.h"
#include "log.h"
#include "main-func.h"
#include "options.h"
#include "report-basic.h"
#include "varlink-io.systemd.Metrics.h"
#include "varlink-util.h"
static int vl_server(void) {
@@ -20,9 +20,16 @@ static int vl_server(void) {
if (r < 0)
return log_error_errno(r, "Failed to allocate Varlink server: %m");
r = facts_add_to_varlink_server(vs, vl_method_list_facts, vl_method_describe_facts);
r = sd_varlink_server_add_interface(vs, &vl_interface_io_systemd_Metrics);
if (r < 0)
return log_error_errno(r, "Failed to register Facts varlink interface: %m");
return log_error_errno(r, "Failed to add Varlink interface: %m");
r = sd_varlink_server_bind_method_many(
vs,
"io.systemd.Metrics.List", vl_method_list_metrics,
"io.systemd.Metrics.Describe", vl_method_describe_metrics);
if (r < 0)
return log_error_errno(r, "Failed to bind Varlink methods: %m");
r = sd_varlink_server_loop_auto(vs);
if (r < 0)
+43 -31
View File
@@ -8,21 +8,22 @@
#include "alloc-util.h"
#include "architecture.h"
#include "facts.h"
#include "hostname-setup.h"
#include "metrics.h"
#include "report-basic.h"
#include "virt.h"
static int architecture_generate(FactFamilyContext *context, void *userdata) {
static int architecture_generate(MetricFamilyContext *context, void *userdata) {
assert(context);
return fact_build_send_string(
return metric_build_send_string(
context,
/* object= */ NULL,
architecture_to_string(uname_architecture()));
architecture_to_string(uname_architecture()),
/* fields= */ NULL);
}
static int boot_id_generate(FactFamilyContext *context, void *userdata) {
static int boot_id_generate(MetricFamilyContext *context, void *userdata) {
sd_id128_t id;
int r;
@@ -32,13 +33,14 @@ static int boot_id_generate(FactFamilyContext *context, void *userdata) {
if (r < 0)
return r;
return fact_build_send_string(
return metric_build_send_string(
context,
/* object= */ NULL,
SD_ID128_TO_STRING(id));
SD_ID128_TO_STRING(id),
/* fields= */ NULL);
}
static int hostname_generate(FactFamilyContext *context, void *userdata) {
static int hostname_generate(MetricFamilyContext *context, void *userdata) {
_cleanup_free_ char *hostname = NULL;
int r;
@@ -48,26 +50,28 @@ static int hostname_generate(FactFamilyContext *context, void *userdata) {
if (r < 0)
return r;
return fact_build_send_string(
return metric_build_send_string(
context,
/* object= */ NULL,
hostname);
hostname,
/* fields= */ NULL);
}
static int kernel_version_generate(FactFamilyContext *context, void *userdata) {
static int kernel_version_generate(MetricFamilyContext *context, void *userdata) {
struct utsname u;
assert(context);
assert_se(uname(&u) >= 0);
return fact_build_send_string(
return metric_build_send_string(
context,
/* object= */ NULL,
u.release);
u.release,
/* fields= */ NULL);
}
static int machine_id_generate(FactFamilyContext *context, void *userdata) {
static int machine_id_generate(MetricFamilyContext *context, void *userdata) {
sd_id128_t id;
int r;
@@ -77,13 +81,14 @@ static int machine_id_generate(FactFamilyContext *context, void *userdata) {
if (r < 0)
return r;
return fact_build_send_string(
return metric_build_send_string(
context,
/* object= */ NULL,
SD_ID128_TO_STRING(id));
SD_ID128_TO_STRING(id),
/* fields= */ NULL);
}
static int virtualization_generate(FactFamilyContext *context, void *userdata) {
static int virtualization_generate(MetricFamilyContext *context, void *userdata) {
Virtualization v;
assert(context);
@@ -92,51 +97,58 @@ static int virtualization_generate(FactFamilyContext *context, void *userdata) {
if (v < 0)
return v;
return fact_build_send_string(
return metric_build_send_string(
context,
/* object= */ NULL,
virtualization_to_string(v));
virtualization_to_string(v),
/* fields= */ NULL);
}
static const FactFamily fact_family_table[] = {
/* Keep facts ordered alphabetically */
static const MetricFamily metric_family_table[] = {
/* Keep entries ordered alphabetically */
{
.name = FACT_IO_SYSTEMD_BASIC "Architecture",
.name = METRIC_IO_SYSTEMD_BASIC_PREFIX "Architecture",
.description = "CPU architecture",
.type = METRIC_FAMILY_TYPE_STRING,
.generate = architecture_generate,
},
{
.name = FACT_IO_SYSTEMD_BASIC "BootID",
.name = METRIC_IO_SYSTEMD_BASIC_PREFIX "BootID",
.description = "Current boot ID",
.type = METRIC_FAMILY_TYPE_STRING,
.generate = boot_id_generate,
},
{
.name = FACT_IO_SYSTEMD_BASIC "Hostname",
.name = METRIC_IO_SYSTEMD_BASIC_PREFIX "Hostname",
.description = "System hostname",
.type = METRIC_FAMILY_TYPE_STRING,
.generate = hostname_generate,
},
{
.name = FACT_IO_SYSTEMD_BASIC "KernelVersion",
.name = METRIC_IO_SYSTEMD_BASIC_PREFIX "KernelVersion",
.description = "Kernel version",
.type = METRIC_FAMILY_TYPE_STRING,
.generate = kernel_version_generate,
},
{
.name = FACT_IO_SYSTEMD_BASIC "MachineID",
.name = METRIC_IO_SYSTEMD_BASIC_PREFIX "MachineID",
.description = "Machine ID",
.type = METRIC_FAMILY_TYPE_STRING,
.generate = machine_id_generate,
},
{
.name = FACT_IO_SYSTEMD_BASIC "Virtualization",
.name = METRIC_IO_SYSTEMD_BASIC_PREFIX "Virtualization",
.description = "Virtualization type",
.type = METRIC_FAMILY_TYPE_STRING,
.generate = virtualization_generate,
},
{}
};
int vl_method_describe_facts(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
return facts_method_describe(fact_family_table, link, parameters, flags, userdata);
int vl_method_describe_metrics(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
return metrics_method_describe(metric_family_table, link, parameters, flags, userdata);
}
int vl_method_list_facts(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
return facts_method_list(fact_family_table, link, parameters, flags, userdata);
int vl_method_list_metrics(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
return metrics_method_list(metric_family_table, link, parameters, flags, userdata);
}
+3 -3
View File
@@ -3,7 +3,7 @@
#include "shared-forward.h"
#define FACT_IO_SYSTEMD_BASIC "io.systemd.Basic."
#define METRIC_IO_SYSTEMD_BASIC_PREFIX "io.systemd.Basic."
int vl_method_list_facts(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata);
int vl_method_describe_facts(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata);
int vl_method_list_metrics(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata);
int vl_method_describe_metrics(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata);
-151
View File
@@ -1,151 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "sd-varlink.h"
#include "facts.h"
#include "json-util.h"
#include "log.h"
#include "varlink-io.systemd.Facts.h"
int facts_add_to_varlink_server(
sd_varlink_server *server,
sd_varlink_method_t vl_method_list_cb,
sd_varlink_method_t vl_method_describe_cb) {
int r;
assert(server);
assert(vl_method_list_cb);
assert(vl_method_describe_cb);
r = sd_varlink_server_add_interface(server, &vl_interface_io_systemd_Facts);
if (r < 0)
return log_debug_errno(r, "Failed to add varlink facts interface to varlink server: %m");
r = sd_varlink_server_bind_method_many(
server,
"io.systemd.Facts.List", vl_method_list_cb,
"io.systemd.Facts.Describe", vl_method_describe_cb);
if (r < 0)
return log_debug_errno(r, "Failed to register varlink facts methods: %m");
return 0;
}
static int fact_family_build_json(const FactFamily *ff, sd_json_variant **ret) {
assert(ff);
return sd_json_buildo(
ret,
SD_JSON_BUILD_PAIR_STRING("name", ff->name),
SD_JSON_BUILD_PAIR_STRING("description", ff->description));
}
int facts_method_describe(
const FactFamily fact_family_table[],
sd_varlink *link,
sd_json_variant *parameters,
sd_varlink_method_flags_t flags,
void *userdata) {
int r;
assert(fact_family_table);
assert(link);
assert(parameters);
assert(FLAGS_SET(flags, SD_VARLINK_METHOD_MORE));
r = sd_varlink_dispatch(link, parameters, /* dispatch_table= */ NULL, /* userdata= */ NULL);
if (r != 0)
return r;
r = sd_varlink_set_sentinel(link, "io.systemd.Facts.NoSuchFact");
if (r < 0)
return r;
for (const FactFamily *ff = fact_family_table; ff && ff->name; ff++) {
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
r = fact_family_build_json(ff, &v);
if (r < 0)
return log_debug_errno(r, "Failed to describe fact family '%s': %m", ff->name);
r = sd_varlink_reply(link, v);
if (r < 0)
return log_debug_errno(r, "Failed to send varlink reply: %m");
}
return 0;
}
int facts_method_list(
const FactFamily fact_family_table[],
sd_varlink *link,
sd_json_variant *parameters,
sd_varlink_method_flags_t flags,
void *userdata) {
int r;
assert(fact_family_table);
assert(link);
assert(parameters);
assert(FLAGS_SET(flags, SD_VARLINK_METHOD_MORE));
r = sd_varlink_dispatch(link, parameters, /* dispatch_table= */ NULL, /* userdata= */ NULL);
if (r != 0)
return r;
r = sd_varlink_set_sentinel(link, "io.systemd.Facts.NoSuchFact");
if (r < 0)
return r;
FactFamilyContext ctx = { .link = link };
for (const FactFamily *ff = fact_family_table; ff && ff->name; ff++) {
assert(ff->generate);
ctx.fact_family = ff;
r = ff->generate(&ctx, userdata);
if (r < 0)
return log_debug_errno(
r, "Failed to list facts for fact family '%s': %m", ff->name);
}
return 0;
}
static int fact_build_send(FactFamilyContext *context, const char *object, sd_json_variant *value) {
assert(context);
assert(value);
assert(context->link);
assert(context->fact_family);
return sd_varlink_replybo(context->link,
SD_JSON_BUILD_PAIR_STRING("name", context->fact_family->name),
JSON_BUILD_PAIR_STRING_NON_EMPTY("object", object),
SD_JSON_BUILD_PAIR_VARIANT("value", value));
}
int fact_build_send_string(FactFamilyContext *context, const char *object, const char *value) {
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
int r;
assert(value);
r = sd_json_variant_new_string(&v, value);
if (r < 0)
return log_debug_errno(r, "Failed to allocate JSON string: %m");
return fact_build_send(context, object, v);
}
int fact_build_send_unsigned(FactFamilyContext *context, const char *object, uint64_t value) {
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
int r;
r = sd_json_variant_new_unsigned(&v, value);
if (r < 0)
return log_debug_errno(r, "Failed to allocate JSON unsigned: %m");
return fact_build_send(context, object, v);
}
-31
View File
@@ -1,31 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include "shared-forward.h"
typedef struct FactFamily FactFamily;
typedef struct FactFamilyContext {
const FactFamily *fact_family;
sd_varlink *link;
} FactFamilyContext;
typedef int (*fact_family_generate_func_t)(FactFamilyContext *ffc, void *userdata);
typedef struct FactFamily {
const char *name;
const char *description;
fact_family_generate_func_t generate;
} FactFamily;
/* Add io.systemd.Facts interface + methods to an existing varlink server */
int facts_add_to_varlink_server(
sd_varlink_server *server,
sd_varlink_method_t vl_method_list_cb,
sd_varlink_method_t vl_method_describe_cb);
int facts_method_describe(const FactFamily fact_family_table[], sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata);
int facts_method_list(const FactFamily fact_family_table[], sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata);
int fact_build_send_string(FactFamilyContext *context, const char *object, const char *value);
int fact_build_send_unsigned(FactFamilyContext *context, const char *object, uint64_t value);
-2
View File
@@ -80,7 +80,6 @@ shared_sources = files(
'exit-status.c',
'extension-util.c',
'factory-reset.c',
'facts.c',
'fdisk-util.c',
'fdset.c',
'fido2-util.c',
@@ -219,7 +218,6 @@ shared_sources = files(
'varlink-io.systemd.BootControl.c',
'varlink-io.systemd.Credentials.c',
'varlink-io.systemd.FactoryReset.c',
'varlink-io.systemd.Facts.c',
'varlink-io.systemd.Hostname.c',
'varlink-io.systemd.Import.c',
'varlink-io.systemd.InstanceMetadata.c',
-37
View File
@@ -1,37 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "sd-varlink-idl.h"
#include "varlink-io.systemd.Facts.h"
static SD_VARLINK_DEFINE_ERROR(NoSuchFact);
static SD_VARLINK_DEFINE_METHOD_FULL(
List,
SD_VARLINK_REQUIRES_MORE,
SD_VARLINK_FIELD_COMMENT("Fact family name, e.g. io.systemd.Basic.Hostname"),
SD_VARLINK_DEFINE_OUTPUT(name, SD_VARLINK_STRING, 0),
/* This is currently an unused placeholder. Add examples when we have them. */
SD_VARLINK_FIELD_COMMENT("Fact object name"),
SD_VARLINK_DEFINE_OUTPUT(object, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("Fact value"),
SD_VARLINK_DEFINE_OUTPUT(value, SD_VARLINK_ANY, 0));
static SD_VARLINK_DEFINE_METHOD_FULL(
Describe,
SD_VARLINK_REQUIRES_MORE,
SD_VARLINK_FIELD_COMMENT("Fact family name, e.g. io.systemd.Basic.Hostname"),
SD_VARLINK_DEFINE_OUTPUT(name, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("Fact family description"),
SD_VARLINK_DEFINE_OUTPUT(description, SD_VARLINK_STRING, 0));
SD_VARLINK_DEFINE_INTERFACE(
io_systemd_Facts,
"io.systemd.Facts",
SD_VARLINK_INTERFACE_COMMENT("Facts APIs"),
SD_VARLINK_SYMBOL_COMMENT("Method to get a list of facts and their values"),
&vl_method_List,
SD_VARLINK_SYMBOL_COMMENT("Method to get the fact families"),
&vl_method_Describe,
SD_VARLINK_SYMBOL_COMMENT("No such fact found"),
&vl_error_NoSuchFact);
-6
View File
@@ -1,6 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include "sd-varlink-idl.h"
extern const sd_varlink_interface vl_interface_io_systemd_Facts;
+5 -1
View File
@@ -43,8 +43,12 @@ varlinkctl list-methods /run/systemd/report/io.systemd.Network
varlinkctl --more call /run/systemd/report/io.systemd.Network io.systemd.Metrics.List {}
varlinkctl --more call /run/systemd/report/io.systemd.Network io.systemd.Metrics.Describe {}
# Make sure the service for "system facts" is enabled
# test io.systemd.Basic Metrics
systemctl start systemd-report-basic.socket
varlinkctl info /run/systemd/report/io.systemd.Basic
varlinkctl list-methods /run/systemd/report/io.systemd.Basic
varlinkctl --more call /run/systemd/report/io.systemd.Basic io.systemd.Metrics.List {}
varlinkctl --more call /run/systemd/report/io.systemd.Basic io.systemd.Metrics.Describe {}
# Test HTTP upload (plain http)
FAKE_SERVER=/usr/lib/systemd/tests/integration-tests/TEST-74-AUX-UTILS/TEST-74-AUX-UTILS.units/fake-report-server.py
+1 -1
View File
@@ -7,7 +7,7 @@
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=Report System Basic Facts Socket
Description=Report System Basic Metrics Socket
DefaultDependencies=no
Before=sockets.target
+1 -1
View File
@@ -7,7 +7,7 @@
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=Report System Basic Facts
Description=Report System Basic Metrics
DefaultDependencies=no
Conflicts=shutdown.target