diff --git a/commons/zenoh-config/src/lib.rs b/commons/zenoh-config/src/lib.rs index b0857f2caf..faaf362b95 100644 --- a/commons/zenoh-config/src/lib.rs +++ b/commons/zenoh-config/src/lib.rs @@ -46,11 +46,12 @@ use zenoh_protocol::{ use zenoh_result::{bail, zerror, ZResult}; use zenoh_util::LibLoader; -pub type ValidationFunction = std::sync::Arc< +type ValidationFunction = std::sync::Arc< dyn Fn( - &str, - &serde_json::Map, - &serde_json::Map, + &str, // plugin name + &str, // `path`, the relative path from the plugin's configuration root to the changed value. + &serde_json::Map, // `current`, the current configuration of the plugin (from its root). + &serde_json::Map, // `new`, the proposed new configuration of the plugin. ) -> ZResult>> + Send + Sync, @@ -949,6 +950,7 @@ impl PluginsConfig { } let new_conf = if let Some(validator) = validator { match validator( + plugin, &key[("plugins/".len() + plugin.len())..], old_conf.as_object().unwrap(), new_conf.as_object().unwrap(), diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index 99b48367cd..97a276ad6b 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -13,7 +13,7 @@ use super::routing::face::Face; use super::Runtime; use crate::key_expr::KeyExpr; -use crate::plugins::sealed as plugins; +use crate::plugins::sealed::{self as plugins, ValidationFunction}; use crate::prelude::sync::{Sample, SyncResolve}; use crate::queryable::Query; use crate::queryable::QueryInner; @@ -64,6 +64,18 @@ enum PluginDiff { Start(crate::config::PluginLoad), } +fn make_plugin_validator(admin: &Arc) -> ValidationFunction { + let admin = admin.clone(); + Arc::new(move |name: &_, path: &_, old: &_, new: &_| { + let plugins_mgr = zlock!(admin.context.plugins_mgr); + if let Some(plugin) = plugins_mgr.plugin(name) { + plugin.config_checker(path, old, new) + } else { + Err(format!("Plugin {name} not found").into()) + } + }) +} + impl AdminSpace { pub async fn start(runtime: &Runtime, plugins_mgr: plugins::PluginsManager, version: String) { let zid_str = runtime.state.zid.to_string(); @@ -128,6 +140,11 @@ impl AdminSpace { context, }); + let mut config_guard = admin.context.runtime.state.config.lock(); + for (name, (_, plugin)) in plugins.running_plugins() { + config_guard.add_plugin_validator(name, make_plugin_validator(&admin)) + } + let cfg_rx = admin.context.runtime.state.config.subscribe(); task::spawn({ let admin = admin.clone(); @@ -196,24 +213,9 @@ impl AdminSpace { active_plugins.insert(name.into(), path.into()); let mut cfg_guard = admin.context.runtime.state.config.lock(); - let validation_function = { - let name = name.clone(); - let admin = admin.clone(); - Arc::new(move |path: &_, old: &_, new: &_| { - let plugins_mgr = - zlock!(admin.context.plugins_mgr); - if let Some(plugin) = - plugins_mgr.plugin(name.as_str()) - { - plugin.config_checker(path, old, new) - } else { - Err("Plugin not found".into()) - } - }) - }; cfg_guard.add_plugin_validator( name, - validation_function, + make_plugin_validator(&admin), ); log::info!( "Successfully started plugin `{}` from {}", diff --git a/zenohd/src/main.rs b/zenohd/src/main.rs index 5c9396e3d8..28df513a46 100644 --- a/zenohd/src/main.rs +++ b/zenohd/src/main.rs @@ -136,14 +136,6 @@ clap::Arg::new("adminspace-permissions").long("adminspace-permissions").value_na } log::info!("Finished loading plugins"); - { - let mut config_guard = runtime.config().lock(); - for (name, (_, plugin)) in plugins.running_plugins() { - let hook = plugin.config_checker(); - config_guard.add_plugin_validator(name, hook) - } - } - AdminSpace::start(&runtime, plugins, LONG_VERSION.clone()).await; future::pending::<()>().await;