From d7b27e9a930c916d7ceb8449803959bdd3e92153 Mon Sep 17 00:00:00 2001 From: Yihau Chen Date: Tue, 4 Feb 2025 18:54:04 +0800 Subject: [PATCH] agave-validator: extract plugin (#4772) * extract exit * fmt * extract plugin --- validator/src/cli.rs | 35 +-------- validator/src/commands/mod.rs | 1 + validator/src/commands/plugin/mod.rs | 104 +++++++++++++++++++++++++++ validator/src/main.rs | 73 +------------------ 4 files changed, 108 insertions(+), 105 deletions(-) create mode 100644 validator/src/commands/plugin/mod.rs diff --git a/validator/src/cli.rs b/validator/src/cli.rs index cbce29c94c9299..186914ceae3521 100644 --- a/validator/src/cli.rs +++ b/validator/src/cli.rs @@ -1826,40 +1826,7 @@ pub fn app<'a>(version: &'a str, default_args: &'a DefaultArgs) -> App<'a, 'a> { ) .subcommand(commands::monitor::command(default_args)) .subcommand(SubCommand::with_name("run").about("Run the validator")) - .subcommand( - SubCommand::with_name("plugin") - .about("Manage and view geyser plugins") - .setting(AppSettings::SubcommandRequiredElseHelp) - .setting(AppSettings::InferSubcommands) - .subcommand( - SubCommand::with_name("list").about("List all current running gesyer plugins"), - ) - .subcommand( - SubCommand::with_name("unload") - .about( - "Unload a particular gesyer plugin. You must specify the gesyer \ - plugin name", - ) - .arg(Arg::with_name("name").required(true).takes_value(true)), - ) - .subcommand( - SubCommand::with_name("reload") - .about( - "Reload a particular gesyer plugin. You must specify the gesyer \ - plugin name and the new config path", - ) - .arg(Arg::with_name("name").required(true).takes_value(true)) - .arg(Arg::with_name("config").required(true).takes_value(true)), - ) - .subcommand( - SubCommand::with_name("load") - .about( - "Load a new gesyer plugin. You must specify the config path. Fails if \ - overwriting (use reload)", - ) - .arg(Arg::with_name("config").required(true).takes_value(true)), - ), - ) + .subcommand(commands::plugin::command(default_args)) .subcommand( SubCommand::with_name("set-identity") .about("Set the validator identity") diff --git a/validator/src/commands/mod.rs b/validator/src/commands/mod.rs index 48f99287ef25fd..d2f0065a3ca7e2 100644 --- a/validator/src/commands/mod.rs +++ b/validator/src/commands/mod.rs @@ -1,4 +1,5 @@ pub mod authorized_voter; pub mod exit; pub mod monitor; +pub mod plugin; pub mod wait_for_restart_window; diff --git a/validator/src/commands/plugin/mod.rs b/validator/src/commands/plugin/mod.rs new file mode 100644 index 00000000000000..f5141355911a1d --- /dev/null +++ b/validator/src/commands/plugin/mod.rs @@ -0,0 +1,104 @@ +use { + crate::{admin_rpc_service, cli::DefaultArgs}, + clap::{value_t, App, AppSettings, Arg, ArgMatches, SubCommand}, + std::{path::Path, process::exit}, +}; + +pub fn command(_default_args: &DefaultArgs) -> App<'_, '_> { + SubCommand::with_name("plugin") + .about("Manage and view geyser plugins") + .setting(AppSettings::SubcommandRequiredElseHelp) + .setting(AppSettings::InferSubcommands) + .subcommand(SubCommand::with_name("list").about("List all current running gesyer plugins")) + .subcommand( + SubCommand::with_name("unload") + .about( + "Unload a particular gesyer plugin. You must specify the gesyer \ + plugin name", + ) + .arg(Arg::with_name("name").required(true).takes_value(true)), + ) + .subcommand( + SubCommand::with_name("reload") + .about( + "Reload a particular gesyer plugin. You must specify the gesyer \ + plugin name and the new config path", + ) + .arg(Arg::with_name("name").required(true).takes_value(true)) + .arg(Arg::with_name("config").required(true).takes_value(true)), + ) + .subcommand( + SubCommand::with_name("load") + .about( + "Load a new gesyer plugin. You must specify the config path. Fails if \ + overwriting (use reload)", + ) + .arg(Arg::with_name("config").required(true).takes_value(true)), + ) +} + +pub fn execute(matches: &ArgMatches, ledger_path: &Path) { + match matches.subcommand() { + ("list", _) => { + let admin_client = admin_rpc_service::connect(ledger_path); + let plugins = admin_rpc_service::runtime() + .block_on(async move { admin_client.await?.list_plugins().await }) + .unwrap_or_else(|err| { + println!("Failed to list plugins: {err}"); + exit(1); + }); + if !plugins.is_empty() { + println!("Currently the following plugins are loaded:"); + for (plugin, i) in plugins.into_iter().zip(1..) { + println!(" {i}) {plugin}"); + } + } else { + println!("There are currently no plugins loaded"); + } + } + ("unload", Some(subcommand_matches)) => { + if let Ok(name) = value_t!(subcommand_matches, "name", String) { + let admin_client = admin_rpc_service::connect(ledger_path); + admin_rpc_service::runtime() + .block_on(async { admin_client.await?.unload_plugin(name.clone()).await }) + .unwrap_or_else(|err| { + println!("Failed to unload plugin {name}: {err:?}"); + exit(1); + }); + println!("Successfully unloaded plugin: {name}"); + } + } + ("load", Some(subcommand_matches)) => { + if let Ok(config) = value_t!(subcommand_matches, "config", String) { + let admin_client = admin_rpc_service::connect(ledger_path); + let name = admin_rpc_service::runtime() + .block_on(async { admin_client.await?.load_plugin(config.clone()).await }) + .unwrap_or_else(|err| { + println!("Failed to load plugin {config}: {err:?}"); + exit(1); + }); + println!("Successfully loaded plugin: {name}"); + } + } + ("reload", Some(subcommand_matches)) => { + if let Ok(name) = value_t!(subcommand_matches, "name", String) { + if let Ok(config) = value_t!(subcommand_matches, "config", String) { + let admin_client = admin_rpc_service::connect(ledger_path); + admin_rpc_service::runtime() + .block_on(async { + admin_client + .await? + .reload_plugin(name.clone(), config.clone()) + .await + }) + .unwrap_or_else(|err| { + println!("Failed to reload plugin {name}: {err:?}"); + exit(1); + }); + println!("Successfully reloaded plugin: {name}"); + } + } + } + _ => unreachable!(), + } +} diff --git a/validator/src/main.rs b/validator/src/main.rs index 2e99a0231d22ad..aaf88cafeeda0c 100644 --- a/validator/src/main.rs +++ b/validator/src/main.rs @@ -196,77 +196,8 @@ pub fn main() { return; } ("plugin", Some(plugin_subcommand_matches)) => { - match plugin_subcommand_matches.subcommand() { - ("list", _) => { - let admin_client = admin_rpc_service::connect(&ledger_path); - let plugins = admin_rpc_service::runtime() - .block_on(async move { admin_client.await?.list_plugins().await }) - .unwrap_or_else(|err| { - println!("Failed to list plugins: {err}"); - exit(1); - }); - if !plugins.is_empty() { - println!("Currently the following plugins are loaded:"); - for (plugin, i) in plugins.into_iter().zip(1..) { - println!(" {i}) {plugin}"); - } - } else { - println!("There are currently no plugins loaded"); - } - return; - } - ("unload", Some(subcommand_matches)) => { - if let Ok(name) = value_t!(subcommand_matches, "name", String) { - let admin_client = admin_rpc_service::connect(&ledger_path); - admin_rpc_service::runtime() - .block_on(async { - admin_client.await?.unload_plugin(name.clone()).await - }) - .unwrap_or_else(|err| { - println!("Failed to unload plugin {name}: {err:?}"); - exit(1); - }); - println!("Successfully unloaded plugin: {name}"); - } - return; - } - ("load", Some(subcommand_matches)) => { - if let Ok(config) = value_t!(subcommand_matches, "config", String) { - let admin_client = admin_rpc_service::connect(&ledger_path); - let name = admin_rpc_service::runtime() - .block_on(async { - admin_client.await?.load_plugin(config.clone()).await - }) - .unwrap_or_else(|err| { - println!("Failed to load plugin {config}: {err:?}"); - exit(1); - }); - println!("Successfully loaded plugin: {name}"); - } - return; - } - ("reload", Some(subcommand_matches)) => { - if let Ok(name) = value_t!(subcommand_matches, "name", String) { - if let Ok(config) = value_t!(subcommand_matches, "config", String) { - let admin_client = admin_rpc_service::connect(&ledger_path); - admin_rpc_service::runtime() - .block_on(async { - admin_client - .await? - .reload_plugin(name.clone(), config.clone()) - .await - }) - .unwrap_or_else(|err| { - println!("Failed to reload plugin {name}: {err:?}"); - exit(1); - }); - println!("Successfully reloaded plugin: {name}"); - } - } - return; - } - _ => unreachable!(), - } + commands::plugin::execute(plugin_subcommand_matches, &ledger_path); + return; } ("contact-info", Some(subcommand_matches)) => { let output_mode = subcommand_matches.value_of("output");