diff --git a/src/plugin/mod.rs b/src/plugin/mod.rs index 4b605223872447ad90fe8d25f2eeb2a07c11e6de..38b2dc1c62e7c02a58f868c14e5574865efafe46 100644 --- a/src/plugin/mod.rs +++ b/src/plugin/mod.rs @@ -696,7 +696,7 @@ pub fn migration_down(ident: PluginIdentifier, timeout: Duration) -> traft::Resu /// 2) set `_pico_plugin.enable` to `true` /// 3) update routes in `_pico_service_route` pub fn enable_plugin( - ident: &PluginIdentifier, + plugin: &PluginIdentifier, on_start_timeout: Duration, timeout: Duration, ) -> traft::Result<()> { @@ -704,15 +704,32 @@ pub fn enable_plugin( let node = node::global()?; - let op = PluginRaftOp::EnablePlugin { - ident: ident.clone(), - on_start_timeout, + // FIXME: this must be done in a retry loop within reenterable_plugin_change_request + let services = node.storage.service.get_by_plugin(&plugin)?; + let op = PluginOp::EnablePlugin { + plugin: plugin.clone(), + // FIXME: we shouldn't need to send this list, it's already available on + // the governor, what is going on? + services, + timeout: on_start_timeout, }; + let dml = Dml::replace( + ClusterwideTable::Property, + &(&PropertyName::PendingPluginOperation, &op), + effective_user_id(), + )?; + + let ranges = vec![ + // Fail if someone proposes another plugin operation + Range::new(ClusterwideTable::Property).eq([PropertyName::PendingPluginOperation]), + // Fail if someone updates this plugin record + Range::new(ClusterwideTable::Plugin).eq([&plugin.name]), + ]; let mut index = do_plugin_cas( node, - Op::Plugin(op), - vec![Range::new(ClusterwideTable::Property).eq([PropertyName::PendingPluginOperation])], + Op::Dml(dml), + ranges, Some(|node| Ok(node.storage.properties.pending_plugin_op()?.is_some())), deadline, )?; @@ -724,7 +741,7 @@ pub fn enable_plugin( let plugin = node .storage .plugin - .get(ident)? + .get(plugin)? .ok_or(PluginError::EnablingAborted)?; if !plugin.enabled { diff --git a/src/traft/node.rs b/src/traft/node.rs index 83a609c08f7324393d5fda475d1cbdeff69c4bd7..ab284d6e4a43250d7363cff9d153e73c3644128a 100644 --- a/src/traft/node.rs +++ b/src/traft/node.rs @@ -732,7 +732,6 @@ impl NodeImpl { Op::Dml(op) => dml_is_governor_wakeup_worthy(op), Op::BatchDml { ops } => ops.iter().any(dml_is_governor_wakeup_worthy), Op::DdlPrepare { .. } => true, - Op::Plugin(PluginRaftOp::EnablePlugin { .. }) => true, // TODO: remove this once PluginOp::DisablePlugin is removed Op::Plugin(PluginRaftOp::DisablePlugin { .. }) => true, Op::Plugin(PluginRaftOp::UpdateServiceTopology { .. }) => true, @@ -1228,28 +1227,6 @@ impl NodeImpl { .expect("storage should not fail"); } - // TODO: remove this, just propose a DML into _pico_property directly - Op::Plugin(PluginRaftOp::EnablePlugin { - ident, - on_start_timeout, - }) => { - let services = self - .storage - .service - .get_by_plugin(&ident) - .expect("storage should not fail"); - - let op = PluginOp::EnablePlugin { - plugin: ident, - services, - timeout: on_start_timeout, - }; - self.storage - .properties - .put(PropertyName::PendingPluginOperation, &op) - .expect("storage should not fail"); - } - Op::Plugin(PluginRaftOp::UpdatePluginConfig { ident, service_name, diff --git a/src/traft/op.rs b/src/traft/op.rs index 77970c0ac3e201183bf17f2ca7072f0ffce5a456..f540948df0cee325d9e969107f4f9b7c7c565e71 100644 --- a/src/traft/op.rs +++ b/src/traft/op.rs @@ -12,7 +12,6 @@ use ::tarantool::space::{Field, SpaceId}; use ::tarantool::tlua; use ::tarantool::tuple::{ToTupleBuffer, TupleBuffer}; use serde::{Deserialize, Serialize}; -use std::time::Duration; use tarantool::index::IndexType; use tarantool::session::UserId; use tarantool::space::SpaceEngineType; @@ -219,9 +218,6 @@ impl std::fmt::Display for Op { object_type = priv_def.object_type(), privilege = priv_def.privilege(), ) } - Op::Plugin(PluginRaftOp::EnablePlugin { ident, .. }) => { - write!(f, "EnablePlugin({ident})") - } Op::Plugin(PluginRaftOp::UpdatePluginConfig { ident, service_name, @@ -815,14 +811,6 @@ impl Acl { #[serde(rename_all = "snake_case")] #[serde(tag = "op_kind")] pub enum PluginRaftOp { - /// Enable a plugin. - /// - /// Provided operation will be set as pending. - /// Only one operation can exist at the same time. - EnablePlugin { - ident: PluginIdentifier, - on_start_timeout: Duration, - }, /// Update plugin service configuration. UpdatePluginConfig { ident: PluginIdentifier,