diff --git a/Cargo.toml b/Cargo.toml index 83512b9eecde558a80f20ca6b88b0d05d7058964..90b06f55d82a8ba84088a54267d0bf5d2a8bae08 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 a39fd0e23c7a9fa00f7bc41cca2fce6557d4ebda..ca65ee13c0e7f78b08b22caf9391454464cb23b9 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 a8731cc2d3666ee310213d62becffff19dd9f624..5464c990d3ee86bfcd20751da31a50094adf5ae8 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 bb44ece6e7b024e663387d196237b1dd9d3bc597..6cef33dbcaab3defb73c9df399ddee6116cae8dd 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 663eb6c15c25810719b67f763e7f3f64288ba66d..5a32d764f1074b3ffcde43c9dc330fd13c6eb239 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 81ac29cac9c895bd5f8fd86d9a8a20d6b42f8599..d11b8a36cb2eeff85f364146c4e851ea25a54af4 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 df24292bdebe574c80342c07966ff7c19cd1c067..a705b7260489a0562ce9f29cb894003b001b7b82 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 27ddc232a17bac8de310e2043472aeee9d677f3e..20edbd8315f88d6740838e8124b9f0b66cd88c07 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 4f48f0b0c7741de0d9fdbf1afd055cf70dd241f0..3ecb3796705efae791012068bd441d484b0d619b 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 0000000000000000000000000000000000000000..3983f3b92a6947a6be180fdbf935091c540b6511 --- /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 0000000000000000000000000000000000000000..f113b2a15e47acd991b115116dd16c06b2a7c5e5 --- /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 + } +}