zombienet_provider/native/
provider.rs1use std::{
2 collections::HashMap,
3 path::{Path, PathBuf},
4 sync::{Arc, Weak},
5};
6
7use async_trait::async_trait;
8use support::fs::FileSystem;
9use tokio::sync::RwLock;
10
11use super::namespace::NativeNamespace;
12use crate::{
13 types::ProviderCapabilities, DynNamespace, Provider, ProviderError, ProviderNamespace,
14};
15
16const PROVIDER_NAME: &str = "native";
17
18pub struct NativeProvider<FS>
19where
20 FS: FileSystem + Send + Sync + Clone,
21{
22 weak: Weak<NativeProvider<FS>>,
23 capabilities: ProviderCapabilities,
24 tmp_dir: PathBuf,
25 filesystem: FS,
26 pub(super) namespaces: RwLock<HashMap<String, Arc<NativeNamespace<FS>>>>,
27}
28
29impl<FS> NativeProvider<FS>
30where
31 FS: FileSystem + Send + Sync + Clone,
32{
33 pub fn new(filesystem: FS) -> Arc<Self> {
34 Arc::new_cyclic(|weak| NativeProvider {
35 weak: weak.clone(),
36 capabilities: ProviderCapabilities {
37 has_resources: false,
38 requires_image: false,
39 prefix_with_full_path: true,
40 use_default_ports_in_cmd: false,
41 },
42 tmp_dir: std::env::temp_dir(),
47 filesystem,
48 namespaces: RwLock::new(HashMap::new()),
49 })
50 }
51
52 pub fn tmp_dir(mut self, tmp_dir: impl Into<PathBuf>) -> Self {
53 self.tmp_dir = tmp_dir.into();
54 self
55 }
56}
57
58#[async_trait]
59impl<FS> Provider for NativeProvider<FS>
60where
61 FS: FileSystem + Send + Sync + Clone + 'static,
62{
63 fn name(&self) -> &str {
64 PROVIDER_NAME
65 }
66
67 fn capabilities(&self) -> &ProviderCapabilities {
68 &self.capabilities
69 }
70
71 async fn namespaces(&self) -> HashMap<String, DynNamespace> {
72 self.namespaces
73 .read()
74 .await
75 .iter()
76 .map(|(name, namespace)| (name.clone(), namespace.clone() as DynNamespace))
77 .collect()
78 }
79
80 async fn create_namespace(&self) -> Result<DynNamespace, ProviderError> {
81 let namespace = NativeNamespace::new(
82 &self.weak,
83 &self.tmp_dir,
84 &self.capabilities,
85 &self.filesystem,
86 None,
87 )
88 .await?;
89
90 self.namespaces
91 .write()
92 .await
93 .insert(namespace.name().to_string(), namespace.clone());
94
95 Ok(namespace)
96 }
97
98 async fn create_namespace_with_base_dir(
99 &self,
100 base_dir: &Path,
101 ) -> Result<DynNamespace, ProviderError> {
102 let namespace = NativeNamespace::new(
103 &self.weak,
104 &self.tmp_dir,
105 &self.capabilities,
106 &self.filesystem,
107 Some(base_dir),
108 )
109 .await?;
110
111 self.namespaces
112 .write()
113 .await
114 .insert(namespace.name().to_string(), namespace.clone());
115
116 Ok(namespace)
117 }
118}