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
130
131
132
133
134
135
136
use serde_json;
use std::collections::BTreeMap;
use std::io;
use super::{lxc_output, Location};
#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)]
pub struct Snapshot {
pub architecture: String,
pub config: BTreeMap<String, String>,
pub created_at: String,
pub ephemeral: bool,
pub expanded_config: BTreeMap<String, String>,
pub expanded_devices: BTreeMap<String, BTreeMap<String, String>>,
pub last_used_at: String,
pub name: String,
pub profiles: Vec<String>,
pub stateful: bool,
}
#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)]
pub struct State {
pub status: String,
pub status_code: usize,
pub memory: BTreeMap<String, usize>,
pub pid: usize,
pub processes: usize,
pub cpu: BTreeMap<String, usize>,
}
#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)]
pub struct Info {
pub architecture: String,
pub config: BTreeMap<String, String>,
pub devices: BTreeMap<String, BTreeMap<String, String>>,
pub ephemeral: bool,
pub profiles: Vec<String>,
pub created_at: String,
pub expanded_config: BTreeMap<String, String>,
pub expanded_devices: BTreeMap<String, BTreeMap<String, String>>,
pub name: String,
pub stateful: bool,
pub status: String,
pub status_code: usize,
pub last_used_at: String,
pub state: Option<State>,
pub snapshots: Option<Vec<Snapshot>>,
}
impl Info {
pub fn all(location: Location) -> io::Result<Vec<Self>> {
let json = match location {
Location::Local => lxc_output(&["list", "--format", "json"])?,
Location::Remote(remote) => lxc_output(&["list", &format!("{}:", remote), "--format", "json"])?
};
serde_json::from_slice::<Vec<Self>>(&json).map_err(|err| {
io::Error::new(
io::ErrorKind::Other,
format!("LXD info: failed to parse json: {}", err)
)
})
}
pub fn new(location: Location, name: &str) -> io::Result<Self> {
let json = match location {
Location::Local => lxc_output(&["list", &format!("{}$", name), "--format", "json"])?,
Location::Remote(remote) => lxc_output(&["list", &format!("{}:", remote), &format!("{}$", name), "--fast", "--format", "json"])?
};
match serde_json::from_slice::<Vec<Self>>(&json) {
Ok(mut list) => if list.len() == 1 {
Ok(list.remove(0))
} else {
Err(io::Error::new(
io::ErrorKind::NotFound,
format!("LXD info: {} not found", name)
))
},
Err(err) => {
Err(io::Error::new(
io::ErrorKind::Other,
format!("LXD info: failed to parse json: {}", err)
))
}
}
}
}