]> git.ipfire.org Git - telemetry.git/commitdiff
Add a check command so that we know which graphs can be rendered
authorMichael Tremer <michael.tremer@ipfire.org>
Thu, 9 Jul 2026 16:27:20 +0000 (16:27 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Thu, 9 Jul 2026 16:27:20 +0000 (16:27 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/client/main.c
src/daemon/graph-bus.c
src/daemon/graph.c
src/daemon/graph.h

index 1bedad7bf101fe770e7ddf6066cfec59daf782e9..9cd187a3f6d252eaf7f6db821497428da1569d8b 100644 (file)
@@ -64,6 +64,9 @@ typedef struct td_client_ctx {
 
        // Locale
        const char* locale;
+
+       // Check Only?
+       unsigned int check;
 } td_client_ctx;
 
 enum {
@@ -74,9 +77,12 @@ enum {
        OPT_UNTIL      = 5,
        OPT_OMIT_TITLE = 6,
        OPT_LOCALE     = 7,
+       OPT_CHECK      = 8,
 };
 
 static struct argp_option options[] = {
+       { "check",  OPT_CHECK,  NULL,     0, "Don't render, only check if it can be rendered", 0 },
+
        { "format", OPT_FORMAT, "FORMAT", 0, "Output Format", 0 },
        { "height", OPT_HEIGHT, "PIXELS", 0, "Height of the output image", 1 },
        { "width",  OPT_WIDTH,  "PIXELS", 0, "Width of the output image",  1 },
@@ -136,6 +142,10 @@ static error_t parse(int key, char* arg, struct argp_state* state) {
                        ctx->locale = arg;
                        break;
 
+               case OPT_CHECK:
+                       ctx->check = 1;
+                       break;
+
                // Called for each argument
                case ARGP_KEY_ARG:
                        // Take the graph name as first argument
@@ -253,6 +263,13 @@ static int render(td_client_ctx* ctx) {
                        goto ERROR;
        }
 
+       // Check Only?
+       if (ctx->check) {
+               r = sd_bus_message_append(m, "{sv}", "check", "b", 1);
+               if (r < 0)
+                       goto ERROR;
+       }
+
        // Close the array
        r = sd_bus_message_close_container(m);
        if (r < 0)
@@ -324,7 +341,7 @@ int main(int argc, char* argv[]) {
                goto ERROR;
        }
 
-       // Render the graph
+       // Render
        r = render(&ctx);
 
 ERROR:
index f37c27507f6e1b09388b4bfc4d3275d7e0307aba..f68aa3ef895eb3146f0a227397c6cb4ef574a74f 100644 (file)
@@ -18,6 +18,7 @@
 #                                                                             #
 #############################################################################*/
 
+#include <stdbool.h>
 #include <stdlib.h>
 
 #include <systemd/sd-bus.h>
@@ -113,6 +114,7 @@ static int td_graph_bus_render(sd_bus_message* m, void* data, sd_bus_error* erro
 
        // Flags
        int omit_title = 0;
+       int check = 0;
 
        // Open the options array
        r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{sv}");
@@ -199,6 +201,14 @@ static int td_graph_bus_render(sd_bus_message* m, void* data, sd_bus_error* erro
                        r = sd_bus_message_read(m, "v", "s", &options.locale);
                        if (r < 0)
                                goto ERROR;
+
+               } else if (td_string_equals(key, "check")) {
+                       r = sd_bus_message_read(m, "v", "b", &check);
+                       if (r < 0)
+                               goto ERROR;
+
+                       if (check)
+                               options.flags |= TD_GRAPH_CHECK;
                }
 
                // Leave the container
@@ -225,16 +235,37 @@ static int td_graph_bus_render(sd_bus_message* m, void* data, sd_bus_error* erro
                goto ERROR;
        }
 
-       // Render the graph
-       r = td_graph_render(graph, object, &options, &buffer, &length);
-       if (r < 0)
-               goto ERROR;
-
        // Make the reply message
        r = sd_bus_message_new_method_return(m, &reply);
        if (r < 0)
                goto ERROR;
 
+       // Check Only?
+       if (options.flags & TD_GRAPH_CHECK) {
+               r = td_graph_can_render(graph, object, &options);
+               switch (r) {
+                       // Can Render
+                       case 0:
+                               break;
+
+                       // Cannot Render
+                       case 1:
+                               break;
+
+                       // Raise any errors
+                       default:
+                               goto ERROR;
+               }
+               if (r < 0)
+                       goto ERROR;
+
+       // Render the graph
+       } else {
+               r = td_graph_render(graph, object, &options, &buffer, &length);
+               if (r < 0)
+                       goto ERROR;
+       }
+
        // Append the graph
        r = sd_bus_message_append_array(reply, 'y', buffer, length);
        if (r < 0)
@@ -257,7 +288,7 @@ static const sd_bus_vtable td_graph_vtable[] = {
        SD_BUS_VTABLE_START(0),
 
        // Operations
-       SD_BUS_METHOD_WITH_ARGS("Render", SD_BUS_ARGS("a{sv}", options), SD_BUS_RESULT("ay", graph),
+       SD_BUS_METHOD_WITH_ARGS("Render", SD_BUS_ARGS("a{sv}", options), SD_BUS_RESULT("a{sv}", graph),
                td_graph_bus_render, SD_BUS_VTABLE_UNPRIVILEGED),
 
        SD_BUS_VTABLE_END
index 5cfeff44f494b4fc711a4bef396c4eb1b9d76301..788a41fa855f5f4101d9343f2c5906498d6d9298 100644 (file)
@@ -369,6 +369,16 @@ static int td_graph_empty(td_graph* self, td_args* args) {
        return 0;
 }
 
+int td_graph_can_render(td_graph* self, const char* object,
+               const td_graph_render_options* options) {
+       // If we don't have a check function, we just assume that we can render
+       if (!self->impl->can_render)
+               return 1;
+
+       // Check if this can be rendered
+       return self->impl->can_render(self->ctx, self, options, object);
+}
+
 int td_graph_render(td_graph* self, const char* object,
                const td_graph_render_options* options, char** buffer, size_t* length) {
        td_args* args = NULL;
@@ -398,9 +408,19 @@ int td_graph_render(td_graph* self, const char* object,
                return -ENOTSUP;
 
        // Check if this can be rendered
-       if (self->impl->can_render) {
-               r = self->impl->can_render(self->ctx, self, options, object);
-               if (r < 0)
+       r = td_graph_can_render(self, object, options);
+       switch (r) {
+               // Cannot render
+               case 0:
+                       r = -ENODATA;
+                       break;
+
+               // Can render
+               case 1:
+                       break;
+
+               // Raise any errors
+               default:
                        goto ERROR;
        }
 
index 59300eb46ac8996e42e1221ddd0f279a786854f1..896986bcf9d5759b65327632febb472962c1101a 100644 (file)
@@ -49,7 +49,8 @@ typedef struct td_graph_render_options {
 
        // Flags
        enum {
-               TD_GRAPH_OMIT_TITLE = (1 << 0),
+               TD_GRAPH_CHECK      = (1 << 0),
+               TD_GRAPH_OMIT_TITLE = (1 << 1),
        } flags;
 } td_graph_render_options;
 
@@ -105,6 +106,8 @@ int td_graph_load_source(td_graph* self,
 int td_graph_load_sources(td_graph* self,
        td_args* args, const char* name, const char** objects);
 
+int td_graph_can_render(td_graph* self, const char* object,
+       const td_graph_render_options* options);
 int td_graph_render(td_graph* self, const char* object,
        const td_graph_render_options* options, char** buffer, size_t* length);