summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2023-11-07 13:54:54 +0100
committerÍñigo Huguet <ihuguet@redhat.com>2024-02-21 11:49:14 +0100
commitad5b3b38db6b8d983a842461ba2cb6b60012febf (patch)
tree4b737b00f11e67458a8d3138ec4c12feffc94f0d
parent10041294fef3a76b37ee90be08adc054328b0faf (diff)
dispatcher: add Action2() D-Bus method
Currently, the dispatcher service implements an Action() method to dispatch events. In the next commits, we'll need to add new parameters, which is not possible with the current signature. Introduce a new Action2() method, similar to the existing one but with the following changes: - it accepts an additional "options" input parameter of type a{sv}; - for each script executed, it also returns a dictionary of type a{sv}. The new parameters will allow to easily extend functionality in the future without having to implement an Action3(). (cherry picked from commit abf0f03d25c810b4c7b2910b34c84e4fd29496f9)
-rw-r--r--src/nm-dispatcher/nm-dispatcher.c169
1 files changed, 126 insertions, 43 deletions
diff --git a/src/nm-dispatcher/nm-dispatcher.c b/src/nm-dispatcher/nm-dispatcher.c
index c16b9d7c0a..722d6e290d 100644
--- a/src/nm-dispatcher/nm-dispatcher.c
+++ b/src/nm-dispatcher/nm-dispatcher.c
@@ -85,6 +85,7 @@ struct Request {
char *iface;
char **envp;
gboolean debug;
+ gboolean is_action2;
GPtrArray *scripts; /* list of ScriptInfo */
guint idx;
@@ -286,18 +287,35 @@ request_dbus_method_return(Request *request)
GVariantBuilder results;
guint i;
- g_variant_builder_init(&results, G_VARIANT_TYPE("a(sus)"));
+ if (request->is_action2) {
+ g_variant_builder_init(&results, G_VARIANT_TYPE("a(susa{sv})"));
+ } else {
+ g_variant_builder_init(&results, G_VARIANT_TYPE("a(sus)"));
+ }
+
for (i = 0; i < request->scripts->len; i++) {
ScriptInfo *script = g_ptr_array_index(request->scripts, i);
- g_variant_builder_add(&results,
- "(sus)",
- script->script,
- script->result,
- script->error ?: "");
+ if (request->is_action2) {
+ g_variant_builder_add(&results,
+ "(sus@a{sv})",
+ script->script,
+ script->result,
+ script->error ?: "",
+ nm_g_variant_singleton_aLsvI());
+ } else {
+ g_variant_builder_add(&results,
+ "(sus)",
+ script->script,
+ script->result,
+ script->error ?: "");
+ }
}
- g_dbus_method_invocation_return_value(request->context, g_variant_new("(a(sus))", &results));
+ g_dbus_method_invocation_return_value(request->context,
+ request->is_action2
+ ? g_variant_new("(a(susa{sv}))", &results)
+ : g_variant_new("(a(sus))", &results));
}
/**
@@ -708,7 +726,7 @@ script_must_wait(const char *path)
}
static void
-_handle_action(GDBusMethodInvocation *invocation, GVariant *parameters)
+_handle_action(GDBusMethodInvocation *invocation, GVariant *parameters, gboolean is_action2)
{
const char *action;
gs_unref_variant GVariant *connection = NULL;
@@ -724,6 +742,7 @@ _handle_action(GDBusMethodInvocation *invocation, GVariant *parameters)
gs_unref_variant GVariant *vpn_proxy_properties = NULL;
gs_unref_variant GVariant *vpn_ip4_config = NULL;
gs_unref_variant GVariant *vpn_ip6_config = NULL;
+ gs_unref_variant GVariant *options = NULL;
gboolean debug;
GSList *sorted_scripts = NULL;
GSList *iter;
@@ -732,45 +751,84 @@ _handle_action(GDBusMethodInvocation *invocation, GVariant *parameters)
guint i, num_nowait = 0;
const char *error_message = NULL;
- g_variant_get(parameters,
- "("
- "&s" /* action */
- "@a{sa{sv}}" /* connection */
- "@a{sv}" /* connection_properties */
- "@a{sv}" /* device_properties */
- "@a{sv}" /* device_proxy_properties */
- "@a{sv}" /* device_ip4_config */
- "@a{sv}" /* device_ip6_config */
- "@a{sv}" /* device_dhcp4_config */
- "@a{sv}" /* device_dhcp6_config */
- "&s" /* connectivity_state */
- "&s" /* vpn_ip_iface */
- "@a{sv}" /* vpn_proxy_properties */
- "@a{sv}" /* vpn_ip4_config */
- "@a{sv}" /* vpn_ip6_config */
- "b" /* debug */
- ")",
- &action,
- &connection,
- &connection_properties,
- &device_properties,
- &device_proxy_properties,
- &device_ip4_config,
- &device_ip6_config,
- &device_dhcp4_config,
- &device_dhcp6_config,
- &connectivity_state,
- &vpn_ip_iface,
- &vpn_proxy_properties,
- &vpn_ip4_config,
- &vpn_ip6_config,
- &debug);
+ if (is_action2) {
+ g_variant_get(parameters,
+ "("
+ "&s" /* action */
+ "@a{sa{sv}}" /* connection */
+ "@a{sv}" /* connection_properties */
+ "@a{sv}" /* device_properties */
+ "@a{sv}" /* device_proxy_properties */
+ "@a{sv}" /* device_ip4_config */
+ "@a{sv}" /* device_ip6_config */
+ "@a{sv}" /* device_dhcp4_config */
+ "@a{sv}" /* device_dhcp6_config */
+ "&s" /* connectivity_state */
+ "&s" /* vpn_ip_iface */
+ "@a{sv}" /* vpn_proxy_properties */
+ "@a{sv}" /* vpn_ip4_config */
+ "@a{sv}" /* vpn_ip6_config */
+ "b" /* debug */
+ "@a{sv}" /* options */
+ ")",
+ &action,
+ &connection,
+ &connection_properties,
+ &device_properties,
+ &device_proxy_properties,
+ &device_ip4_config,
+ &device_ip6_config,
+ &device_dhcp4_config,
+ &device_dhcp6_config,
+ &connectivity_state,
+ &vpn_ip_iface,
+ &vpn_proxy_properties,
+ &vpn_ip4_config,
+ &vpn_ip6_config,
+ &debug,
+ &options);
+ } else {
+ g_variant_get(parameters,
+ "("
+ "&s" /* action */
+ "@a{sa{sv}}" /* connection */
+ "@a{sv}" /* connection_properties */
+ "@a{sv}" /* device_properties */
+ "@a{sv}" /* device_proxy_properties */
+ "@a{sv}" /* device_ip4_config */
+ "@a{sv}" /* device_ip6_config */
+ "@a{sv}" /* device_dhcp4_config */
+ "@a{sv}" /* device_dhcp6_config */
+ "&s" /* connectivity_state */
+ "&s" /* vpn_ip_iface */
+ "@a{sv}" /* vpn_proxy_properties */
+ "@a{sv}" /* vpn_ip4_config */
+ "@a{sv}" /* vpn_ip6_config */
+ "b" /* debug */
+ ")",
+ &action,
+ &connection,
+ &connection_properties,
+ &device_properties,
+ &device_proxy_properties,
+ &device_ip4_config,
+ &device_ip6_config,
+ &device_dhcp4_config,
+ &device_dhcp6_config,
+ &connectivity_state,
+ &vpn_ip_iface,
+ &vpn_proxy_properties,
+ &vpn_ip4_config,
+ &vpn_ip6_config,
+ &debug);
+ }
request = g_slice_new0(Request);
request->request_id = ++gl.request_id_counter;
request->debug = debug || gl.log_verbose;
request->context = invocation;
request->action = g_strdup(action);
+ request->is_action2 = is_action2;
request->envp = nm_dispatcher_utils_construct_envp(action,
connection,
@@ -908,8 +966,12 @@ _bus_method_call(GDBusConnection *connection,
return;
}
if (nm_streq(interface_name, NM_DISPATCHER_DBUS_INTERFACE)) {
+ if (nm_streq(method_name, "Action2")) {
+ _handle_action(invocation, parameters, TRUE);
+ return;
+ }
if (nm_streq(method_name, "Action")) {
- _handle_action(invocation, parameters);
+ _handle_action(invocation, parameters, FALSE);
return;
}
if (nm_streq(method_name, "Ping")) {
@@ -950,7 +1012,28 @@ static GDBusInterfaceInfo *const interface_info = NM_DEFINE_GDBUS_INTERFACE_INFO
NM_DEFINE_GDBUS_ARG_INFO("vpn_ip6_config", "a{sv}"),
NM_DEFINE_GDBUS_ARG_INFO("debug", "b"), ),
.out_args =
- NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("results", "a(sus)"), ), ), ), );
+ NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("results", "a(sus)"), ), ),
+ NM_DEFINE_GDBUS_METHOD_INFO(
+ "Action2",
+ .in_args = NM_DEFINE_GDBUS_ARG_INFOS(
+ NM_DEFINE_GDBUS_ARG_INFO("action", "s"),
+ NM_DEFINE_GDBUS_ARG_INFO("connection", "a{sa{sv}}"),
+ NM_DEFINE_GDBUS_ARG_INFO("connection_properties", "a{sv}"),
+ NM_DEFINE_GDBUS_ARG_INFO("device_properties", "a{sv}"),
+ NM_DEFINE_GDBUS_ARG_INFO("device_proxy_properties", "a{sv}"),
+ NM_DEFINE_GDBUS_ARG_INFO("device_ip4_config", "a{sv}"),
+ NM_DEFINE_GDBUS_ARG_INFO("device_ip6_config", "a{sv}"),
+ NM_DEFINE_GDBUS_ARG_INFO("device_dhcp4_config", "a{sv}"),
+ NM_DEFINE_GDBUS_ARG_INFO("device_dhcp6_config", "a{sv}"),
+ NM_DEFINE_GDBUS_ARG_INFO("connectivity_state", "s"),
+ NM_DEFINE_GDBUS_ARG_INFO("vpn_ip_iface", "s"),
+ NM_DEFINE_GDBUS_ARG_INFO("vpn_proxy_properties", "a{sv}"),
+ NM_DEFINE_GDBUS_ARG_INFO("vpn_ip4_config", "a{sv}"),
+ NM_DEFINE_GDBUS_ARG_INFO("vpn_ip6_config", "a{sv}"),
+ NM_DEFINE_GDBUS_ARG_INFO("debug", "b"),
+ NM_DEFINE_GDBUS_ARG_INFO("options", "a{sv}"), ),
+ .out_args = NM_DEFINE_GDBUS_ARG_INFOS(
+ NM_DEFINE_GDBUS_ARG_INFO("results", "a(susa{sv})"), ), ), ), );
static gboolean
_bus_register_service(void)