xo_api_client/api/vm/
mod.rs

1#[cfg(test)]
2mod tests;
3
4mod types;
5pub use types::{OtherInfo, PowerState, Snapshot, SnapshotId, Vm, VmId, VmOrSnapshotId};
6
7use jsonrpsee_types::{traits::Client as _, v2::params::ParamsSer};
8use jsonrpsee_ws_client::WsClient;
9use std::sync::Arc;
10
11use crate::{procedure_args, RpcError};
12
13pub struct VmProcedures {
14    pub(crate) inner: Arc<WsClient>,
15}
16
17impl VmProcedures {
18    /// This function will try to initiate a soft restart of the VM
19    /// The there is no guarantee that the VM has started once the returned
20    /// future resolves
21    ///
22    /// xo-cli: vm.restart id=<string> [force=<boolean>]
23    pub async fn restart_nonblocking(&self, vm_id: VmId) -> Result<(), RestartError> {
24        #[derive(serde::Deserialize, Debug)]
25        #[serde(transparent)]
26        struct RestartResult(bool);
27
28        let params = procedure_args! { "id" => vm_id };
29
30        let restart_suceeded: RestartResult = self
31            .inner
32            .request("vm.restart", Some(ParamsSer::Map(params)))
33            .await
34            .map_err(RestartError::Rpc)?;
35
36        if let RestartResult(false) = restart_suceeded {
37            return Err(RestartError::ReportedFail);
38        }
39
40        Ok(())
41    }
42
43    /// Create snapshot of the specified VM
44    ///
45    /// `save_memory`: Should the RAM memory of the VM be saved? Setting this to true does make the
46    /// snapshot take a lot more time, may even freeze the VM for some time. If you are unsure,
47    /// set this to `false`
48    ///
49    /// xo-cli: vm.snapshot [description=<string>] id=<string> [name=<string>] [saveMemory=<boolean>]
50    pub async fn snapshot(
51        &self,
52        vm_id: VmId,
53        name: String,
54        description: String,
55        save_memory: bool,
56    ) -> Result<SnapshotId, RpcError> {
57        let params = procedure_args! {
58            "id" => vm_id,
59            "name" => name,
60            "description" => description,
61            "saveMemory"=> save_memory,
62        };
63
64        self.inner
65            .request("vm.snapshot", Some(ParamsSer::Map(params)))
66            .await
67            .map_err(Into::into)
68    }
69
70    /// Roll back Vm to an earlier snapshot
71    ///
72    /// xo-cli: vm.revert snapshot=<string>
73    pub async fn revert(&self, snapshot_id: SnapshotId) -> Result<(), RevertSnapshotError> {
74        #[derive(serde::Deserialize, Debug)]
75        #[serde(transparent)]
76        struct RevertResult(bool);
77
78        let params = procedure_args! { "snapshot" => snapshot_id.clone() };
79
80        let revert_result = self
81            .inner
82            .request::<RevertResult>("vm.revert", Some(ParamsSer::Map(params)))
83            .await
84            .map_err(RevertSnapshotError::Rpc)?;
85
86        if let RevertResult(false) = revert_result {
87            log::warn!("revert_snapshot: {:?} false", snapshot_id);
88            return Err(RevertSnapshotError::ReportedFail);
89        }
90
91        Ok(())
92    }
93
94    /// This may be used for deleting snapshots as well as entire VMs, so be careful!
95    ///
96    /// xo-cli: vm.delete id=<string>
97    pub async fn delete(
98        &self,
99        vm_or_snapshot_id: impl Into<VmOrSnapshotId>,
100    ) -> Result<(), RpcError> {
101        #[derive(serde::Deserialize)]
102        #[serde(transparent)]
103        struct DeleteResult(([(); 0], [(); 1]));
104
105        let vm_or_snapshot_id = vm_or_snapshot_id.into();
106
107        let params = procedure_args! { "id" => vm_or_snapshot_id };
108
109        self.inner
110            .request::<DeleteResult>("vm.delete", Some(ParamsSer::Map(params)))
111            .await?;
112
113        Ok(())
114    }
115}
116
117/// Error during restart of VM
118#[derive(Debug)]
119pub enum RestartError {
120    ReportedFail,
121    Rpc(RpcError),
122}
123
124/// Error during revert of VM snapshot
125#[derive(Debug)]
126pub enum RevertSnapshotError {
127    ReportedFail,
128    Rpc(RpcError),
129}