1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#[cfg(test)]
mod tests;
mod types;
pub use types::{OtherInfo, PowerState, Snapshot, SnapshotId, Vm, VmId, VmOrSnapshotId};
use jsonrpsee_types::{traits::Client as _, v2::params::ParamsSer};
use jsonrpsee_ws_client::WsClient;
use std::sync::Arc;
use crate::{procedure_args, RpcError};
pub struct VmProcedures {
pub(crate) inner: Arc<WsClient>,
}
impl VmProcedures {
pub async fn restart_nonblocking(&self, vm_id: VmId) -> Result<(), RestartError> {
#[derive(serde::Deserialize, Debug)]
#[serde(transparent)]
struct RestartResult(bool);
let params = procedure_args! { "id" => vm_id };
let restart_suceeded: RestartResult = self
.inner
.request("vm.restart", Some(ParamsSer::Map(params)))
.await
.map_err(RestartError::Rpc)?;
if let RestartResult(false) = restart_suceeded {
return Err(RestartError::ReportedFail);
}
Ok(())
}
pub async fn snapshot(
&self,
vm_id: VmId,
name: String,
description: String,
save_memory: bool,
) -> Result<SnapshotId, RpcError> {
let params = procedure_args! {
"id" => vm_id,
"name" => name,
"description" => description,
"saveMemory"=> save_memory,
};
self.inner
.request("vm.snapshot", Some(ParamsSer::Map(params)))
.await
.map_err(Into::into)
}
pub async fn revert(&self, snapshot_id: SnapshotId) -> Result<(), RevertSnapshotError> {
#[derive(serde::Deserialize, Debug)]
#[serde(transparent)]
struct RevertResult(bool);
let params = procedure_args! { "snapshot" => snapshot_id.clone() };
let revert_result = self
.inner
.request::<RevertResult>("vm.revert", Some(ParamsSer::Map(params)))
.await
.map_err(RevertSnapshotError::Rpc)?;
if let RevertResult(false) = revert_result {
log::warn!("revert_snapshot: {:?} false", snapshot_id);
return Err(RevertSnapshotError::ReportedFail);
}
Ok(())
}
pub async fn delete(
&self,
vm_or_snapshot_id: impl Into<VmOrSnapshotId>,
) -> Result<(), RpcError> {
#[derive(serde::Deserialize)]
#[serde(transparent)]
struct DeleteResult(([(); 0], [(); 1]));
let vm_or_snapshot_id = vm_or_snapshot_id.into();
let params = procedure_args! { "id" => vm_or_snapshot_id };
self.inner
.request::<DeleteResult>("vm.delete", Some(ParamsSer::Map(params)))
.await?;
Ok(())
}
}
#[derive(Debug)]
pub enum RestartError {
ReportedFail,
Rpc(RpcError),
}
#[derive(Debug)]
pub enum RevertSnapshotError {
ReportedFail,
Rpc(RpcError),
}