From 439a8dea5f54c689095cf0cdd74dc1eeb598f354 Mon Sep 17 00:00:00 2001 From: PG Herveou <pgherveou@gmail.com> Date: Tue, 7 Nov 2023 22:00:46 +0100 Subject: [PATCH] Expose Top level API through zombienet-sdk crate (#126) Following up on take 1 https://github.com/paritytech/zombienet-sdk/pull/124 Apart from better logs, I realize that one of the only thing missing now for us to start consuming this project is a top level package available (with it's dependencies) on crates.io. This PR serves mainly as a discussion point to get there. It would be great if we could publish an early version (0.0.1?) on crates.io so that we can start using this asap. --- Cargo.toml | 1 + crates/examples/Cargo.toml | 7 +---- .../examples/simple_network_example.rs | 18 +++-------- crates/examples/examples/small_network.rs | 2 +- .../examples/small_network_with_default.rs | 18 ++++------- .../examples/small_network_with_para.rs | 18 ++++------- crates/orchestrator/src/lib.rs | 4 +-- crates/orchestrator/src/network.rs | 21 +++++++++---- crates/provider/src/lib.rs | 2 +- crates/sdk/Cargo.toml | 16 ++++++++++ crates/sdk/src/lib.rs | 31 +++++++++++++++++++ 11 files changed, 85 insertions(+), 53 deletions(-) create mode 100644 crates/sdk/Cargo.toml create mode 100644 crates/sdk/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 83512b9..90b06f5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,7 @@ [workspace] resolver = "2" members = [ + "crates/sdk", "crates/examples", "crates/support", "crates/configuration", diff --git a/crates/examples/Cargo.toml b/crates/examples/Cargo.toml index a39fd0e..ca65ee1 100644 --- a/crates/examples/Cargo.toml +++ b/crates/examples/Cargo.toml @@ -6,12 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -configuration = { path = "../configuration" } -orchestrator = { path = "../orchestrator" } -provider = { path = "../provider" } -# TODO: we shouldn't need to pull from support, we need -# to review the exports for neeeded types -support = { path = "../support" } +zombienet-sdk = { path = "../sdk" } tokio = { workspace = true } futures = { workspace = true } subxt = { workspace = true } diff --git a/crates/examples/examples/simple_network_example.rs b/crates/examples/examples/simple_network_example.rs index a8731cc..5464c99 100644 --- a/crates/examples/examples/simple_network_example.rs +++ b/crates/examples/examples/simple_network_example.rs @@ -1,21 +1,13 @@ -// use std::time::Duration; - -use configuration::NetworkConfig; use futures::stream::StreamExt; -use orchestrator::Orchestrator; -use provider::NativeProvider; -use support::{fs::local::LocalFileSystem, process::os::OsProcessManager}; +use zombienet_sdk::{NetworkConfig, NetworkConfigExt}; #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> { - let config = NetworkConfig::load_from_toml("./crates/examples/examples/0001-simple.toml") - .expect("errored?"); + let network = NetworkConfig::load_from_toml("./crates/examples/examples/0001-simple.toml") + .expect("errored?") + .spawn_native() + .await?; - let fs = LocalFileSystem; - let pm = OsProcessManager; - let provider = NativeProvider::new(fs.clone(), pm); - let orchestrator = Orchestrator::new(fs, provider); - let network = orchestrator.spawn(config).await?; println!("🚀🚀🚀🚀 network deployed"); let client = network diff --git a/crates/examples/examples/small_network.rs b/crates/examples/examples/small_network.rs index bb44ece..6cef33d 100644 --- a/crates/examples/examples/small_network.rs +++ b/crates/examples/examples/small_network.rs @@ -1,4 +1,4 @@ -use configuration::NetworkConfigBuilder; +use zombienet_sdk::NetworkConfigBuilder; fn main() { let config = NetworkConfigBuilder::new() diff --git a/crates/examples/examples/small_network_with_default.rs b/crates/examples/examples/small_network_with_default.rs index 663eb6c..5a32d76 100644 --- a/crates/examples/examples/small_network_with_default.rs +++ b/crates/examples/examples/small_network_with_default.rs @@ -1,11 +1,8 @@ -use configuration::NetworkConfigBuilder; -use orchestrator::{AddNodeOpts, Orchestrator}; -use provider::NativeProvider; -use support::{fs::local::LocalFileSystem, process::os::OsProcessManager}; +use zombienet_sdk::{AddNodeOpts, NetworkConfigBuilder, NetworkConfigExt}; #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> { - let config = NetworkConfigBuilder::new() + let mut network = NetworkConfigBuilder::new() .with_relaychain(|r| { r.with_chain("rococo-local") .with_default_command("polkadot") @@ -18,13 +15,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> { .with_collator(|n| n.with_name("collator").with_command("polkadot-parachain")) }) .build() - .unwrap(); + .unwrap() + .spawn_native() + .await?; - let fs = LocalFileSystem; - let pm = OsProcessManager; - let provider = NativeProvider::new(fs.clone(), pm); - let orchestrator = Orchestrator::new(fs, provider); - let mut network = orchestrator.spawn(config).await?; println!("🚀🚀🚀🚀 network deployed"); // add a new node let opts = AddNodeOpts { @@ -36,7 +30,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> { // TODO: add check to ensure if unique network.add_node("new1", opts, None).await?; - // Example of some opertions that you can do + // Example of some operations that you can do // with `nodes` (e.g pause, resume, restart) // Get a ref to the node diff --git a/crates/examples/examples/small_network_with_para.rs b/crates/examples/examples/small_network_with_para.rs index 81ac29c..d11b8a3 100644 --- a/crates/examples/examples/small_network_with_para.rs +++ b/crates/examples/examples/small_network_with_para.rs @@ -1,13 +1,10 @@ use std::time::Duration; -use configuration::{NetworkConfigBuilder, RegistrationStrategy}; -use orchestrator::{AddNodeOpts, Orchestrator}; -use provider::NativeProvider; -use support::{fs::local::LocalFileSystem, process::os::OsProcessManager}; +use zombienet_sdk::{AddNodeOpts, NetworkConfigBuilder, NetworkConfigExt, RegistrationStrategy}; #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> { - let config = NetworkConfigBuilder::new() + let mut network = NetworkConfigBuilder::new() .with_relaychain(|r| { r.with_chain("rococo-local") .with_default_command("polkadot") @@ -21,13 +18,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> { .with_collator(|n| n.with_name("collator").with_command("polkadot-parachain")) }) .build() - .unwrap(); + .unwrap() + .spawn_native() + .await?; - let fs = LocalFileSystem; - let pm = OsProcessManager; - let provider = NativeProvider::new(fs.clone(), pm); - let orchestrator = Orchestrator::new(fs, provider); - let mut network = orchestrator.spawn(config).await?; println!("🚀🚀🚀🚀 network deployed"); // add a new node let opts = AddNodeOpts { @@ -41,7 +35,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> { tokio::time::sleep(Duration::from_secs(2)).await; - // Example of some opertions that you can do + // Example of some operations that you can do // with `nodes` (e.g pause, resume, restart) tokio::time::sleep(Duration::from_secs(10)).await; diff --git a/crates/orchestrator/src/lib.rs b/crates/orchestrator/src/lib.rs index df24292..a705b72 100644 --- a/crates/orchestrator/src/lib.rs +++ b/crates/orchestrator/src/lib.rs @@ -1,9 +1,9 @@ // TODO(Javier): Remove when we implement the logic in the orchestrator to spawn with the provider. #![allow(dead_code)] -mod errors; +pub mod errors; mod generators; -mod network; +pub mod network; mod network_helper; mod network_spec; mod shared; diff --git a/crates/orchestrator/src/network.rs b/crates/orchestrator/src/network.rs index 27ddc23..20edbd8 100644 --- a/crates/orchestrator/src/network.rs +++ b/crates/orchestrator/src/network.rs @@ -182,13 +182,22 @@ impl<T: FileSystem> Network<T> { // deregister and stop the collator? // remove_parachain() - pub fn get_node(&self, node_name: impl Into<String>) -> Result<&NetworkNode, anyhow::Error> { - let node_name = node_name.into(); - if let Some(node) = self.nodes_by_name.get(&node_name) { - Ok(node) - } else { - Err(anyhow::anyhow!("can't find the node!")) + pub fn get_node(&self, name: impl Into<String>) -> Result<&NetworkNode, anyhow::Error> { + let name = &name.into(); + if let Some(node) = self.nodes_by_name.get(name) { + return Ok(node); } + + let list = self + .nodes_by_name + .keys() + .cloned() + .collect::<Vec<_>>() + .join(", "); + + Err(anyhow::anyhow!( + "can't find node with name: {name:?}, should be one of {list}" + )) } pub fn nodes(&self) -> Vec<&NetworkNode> { diff --git a/crates/provider/src/lib.rs b/crates/provider/src/lib.rs index 4f48f0b..3ecb379 100644 --- a/crates/provider/src/lib.rs +++ b/crates/provider/src/lib.rs @@ -86,7 +86,7 @@ pub trait ProviderNamespace { async fn static_setup(&self) -> Result<(), ProviderError>; } -pub type DynNamespace = Arc<dyn ProviderNamespace>; +pub type DynNamespace = Arc<dyn ProviderNamespace + Send + Sync>; type ExecutionResult = Result<String, (ExitStatus, String)>; diff --git a/crates/sdk/Cargo.toml b/crates/sdk/Cargo.toml new file mode 100644 index 0000000..3983f3b --- /dev/null +++ b/crates/sdk/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "zombienet-sdk" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +configuration = { path = "../configuration" } +orchestrator = { path = "../orchestrator" } +provider = { path = "../provider" } +support = { path = "../support" } +async-trait = { workspace = true } +tokio = { workspace = true } +futures = { workspace = true } +subxt = { workspace = true } diff --git a/crates/sdk/src/lib.rs b/crates/sdk/src/lib.rs new file mode 100644 index 0000000..f113b2a --- /dev/null +++ b/crates/sdk/src/lib.rs @@ -0,0 +1,31 @@ +use async_trait::async_trait; +pub use configuration::{NetworkConfig, NetworkConfigBuilder, RegistrationStrategy}; +pub use orchestrator::{errors::OrchestratorError, network::Network, AddNodeOpts, Orchestrator}; +use provider::NativeProvider; +use support::{fs::local::LocalFileSystem, process::os::OsProcessManager}; + +#[async_trait] +pub trait NetworkConfigExt { + /// Spawns a network using the native provider. + /// + /// # Example: + /// ```rust + /// # use zombienet_sdk::{NetworkConfig, NetworkConfigExt}; + /// # async fn example() -> Result<(), zombienet_sdk::OrchestratorError> { + /// let network = NetworkConfig::load_from_toml("config.toml")? + /// .spawn_native() + /// .await?; + /// # Ok(()) + /// # } + /// ``` + async fn spawn_native(self) -> Result<Network<LocalFileSystem>, OrchestratorError>; +} + +#[async_trait] +impl NetworkConfigExt for NetworkConfig { + async fn spawn_native(self) -> Result<Network<LocalFileSystem>, OrchestratorError> { + let provider = NativeProvider::new(LocalFileSystem {}, OsProcessManager {}); + let orchestrator = Orchestrator::new(LocalFileSystem {}, provider); + orchestrator.spawn(self).await + } +} -- GitLab