xnode_deployer/
lib.rs

1use serde::{Deserialize, Serialize};
2
3mod utils;
4pub use utils::{Error, XnodeDeployerError};
5
6#[cfg(feature = "hivelocity")]
7pub mod hivelocity;
8
9#[derive(Serialize, Deserialize, Debug)]
10pub struct DeployInput {
11    pub xnode_owner: Option<String>,
12    pub domain: Option<String>,
13    pub acme_email: Option<String>,
14    pub user_passwd: Option<String>,
15    pub encrypted: Option<String>,
16    pub initial_config: Option<String>,
17}
18#[derive(Serialize, Deserialize, Debug)]
19pub struct DeployOutput<ProviderOutput> {
20    pub ip: String,
21    pub provider: ProviderOutput,
22}
23
24pub trait XnodeDeployer: Send + Sync {
25    type ProviderOutput;
26
27    /// Provision new hardware with XnodeOS
28    fn deploy(
29        &self,
30        input: DeployInput,
31    ) -> impl Future<Output = Result<DeployOutput<Self::ProviderOutput>, Error>> + Send;
32
33    /// Cancel renting of hardware
34    fn undeploy(
35        &self,
36        xnode: DeployOutput<Self::ProviderOutput>,
37    ) -> impl Future<Output = Option<Error>> + Send;
38}
39
40impl DeployInput {
41    pub fn cloud_init(&self) -> String {
42        let mut env = vec![];
43        for (name, content) in [
44            ("XNODE_OWNER", &self.xnode_owner),
45            ("DOMAIN", &self.domain),
46            ("ACME_EMAIL", &self.acme_email),
47            ("USER_PASSWD", &self.user_passwd),
48            ("ENCRYPTED", &self.encrypted),
49            ("INITIAL_CONFIG", &self.initial_config),
50        ] {
51            if let Some(content) = content {
52                env.push(format!("export {name}=\"{content}\" && "));
53            }
54        }
55
56        let env = env.join("");
57        format!(
58            "#cloud-config\nruncmd:\n - {env} curl https://raw.githubusercontent.com/Openmesh-Network/xnode-manager/main/os/install.sh | bash 2>&1 | tee /tmp/xnodeos.log"
59        )
60    }
61}