summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelix Fietkau2025-09-30 17:47:03 +0000
committerFelix Fietkau2025-09-30 17:47:04 +0000
commit94bfb9cf423886a838027b4efcfe717077a23451 (patch)
treee71a6a07d2b9afd14ca426c83e3af899a5ed4b16
parentace5f272e139b5b1f98e992b2590ed1384e2774e (diff)
downloadprocd-94bfb9cf423886a838027b4efcfe717077a23451.tar.gz
service: implement set_data ubus method
This can be used to update service and instance data explicitly. Without this change, instances could only be updated by sending the full instance data again. Signed-off-by: Felix Fietkau <nbd@nbd.name>
-rw-r--r--service/service.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/service/service.c b/service/service.c
index f8d9c40..f40a1f1 100644
--- a/service/service.c
+++ b/service/service.c
@@ -305,6 +305,19 @@ static const struct blobmsg_policy get_data_policy[] = {
};
enum {
+ SET_DATA_NAME,
+ SET_DATA_INSTANCE,
+ SET_DATA_DATA,
+ __SET_DATA_MAX
+};
+
+static const struct blobmsg_policy set_data_policy[__SET_DATA_MAX] = {
+ [SET_DATA_NAME] = { "name", BLOBMSG_TYPE_STRING },
+ [SET_DATA_INSTANCE] = { "instance", BLOBMSG_TYPE_STRING },
+ [SET_DATA_DATA] = { "data", BLOBMSG_TYPE_TABLE },
+};
+
+enum {
CONTAINER_CONSOLE_NAME,
CONTAINER_CONSOLE_INSTANCE,
__CONTAINER_CONSOLE_MAX,
@@ -880,6 +893,48 @@ service_get_data(struct ubus_context *ctx, struct ubus_object *obj,
}
static int
+service_handle_set_data(struct ubus_context *ctx, struct ubus_object *obj,
+ struct ubus_request_data *req, const char *method,
+ struct blob_attr *msg)
+{
+ struct blob_attr *tb[__SET_DATA_MAX];
+ struct service *s;
+ struct service_instance *in;
+ const char *name;
+ const char *instance = NULL;
+
+ blobmsg_parse(set_data_policy, __SET_DATA_MAX, tb,
+ blobmsg_data(msg), blobmsg_data_len(msg));
+
+ if (!tb[SET_DATA_NAME] || !tb[SET_DATA_DATA])
+ return UBUS_STATUS_INVALID_ARGUMENT;
+
+ name = blobmsg_get_string(tb[SET_DATA_NAME]);
+
+ s = avl_find_element(&services, name, s, avl);
+ if (!s)
+ return UBUS_STATUS_NOT_FOUND;
+
+ if (tb[SET_DATA_INSTANCE])
+ instance = blobmsg_get_string(tb[SET_DATA_INSTANCE]);
+
+ if (instance) {
+ in = vlist_find(&s->instances, instance, in, node);
+ if (!in)
+ return UBUS_STATUS_NOT_FOUND;
+
+ blobmsg_list_free(&in->data);
+ blobmsg_list_fill(&in->data, blobmsg_data(tb[SET_DATA_DATA]),
+ blobmsg_data_len(tb[SET_DATA_DATA]), false);
+ } else {
+ if (service_update_data(s, tb[SET_DATA_DATA]) < 0)
+ return UBUS_STATUS_UNKNOWN_ERROR;
+ }
+
+ return UBUS_STATUS_OK;
+}
+
+static int
container_handle_console(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
@@ -1013,6 +1068,7 @@ static struct ubus_method main_object_methods[] = {
UBUS_METHOD("event", service_handle_event, event_policy),
UBUS_METHOD("validate", service_handle_validate, validate_policy),
UBUS_METHOD("get_data", service_get_data, get_data_policy),
+ UBUS_METHOD("set_data", service_handle_set_data, set_data_policy),
UBUS_METHOD("state", service_handle_state, service_state_attrs),
UBUS_METHOD("watchdog", service_handle_watchdog, service_watchdog_policy),
};