]> git.proxmox.com Git - proxmox-backup.git/blame - src/api2/node/disks/mod.rs
update to first proxmox crate split
[proxmox-backup.git] / src / api2 / node / disks / mod.rs
CommitLineData
707974fd
DM
1use anyhow::{bail, Error};
2use serde_json::{json, Value};
553cd12b 3
553cd12b 4use proxmox::{sortable, identity};
6ef1b649
WB
5use proxmox_router::{
6 list_subdirs_api_method, Router, RpcEnvironment, RpcEnvironmentType, SubdirMap, Permission,
7};
8use proxmox_schema::api;
553cd12b 9
8cc3760e 10use pbs_api_types::{
049a22a3 11 UPID_SCHEMA, NODE_SCHEMA, BLOCKDEVICE_NAME_SCHEMA,
8cc3760e
DM
12 PRIV_SYS_AUDIT, PRIV_SYS_MODIFY,
13};
14
7fa27795
DM
15use crate::tools::disks::{
16 DiskUsageInfo, DiskUsageType, DiskManage, SmartData,
707974fd 17 get_disks, get_smart_data, get_disk_usage_info, inititialize_gpt_disk,
7fa27795 18};
b9700a9f 19use proxmox_rest_server::WorkerTask;
1ec0d70d 20use pbs_tools::task_log;
553cd12b 21
d4f2397d 22pub mod directory;
929a13b3 23pub mod zfs;
d4f2397d 24
553cd12b 25#[api(
7fa27795 26 protected: true,
553cd12b
DM
27 input: {
28 properties: {
ce8e3de4
DM
29 node: {
30 schema: NODE_SCHEMA,
31 },
553cd12b 32 skipsmart: {
08cb2038
TL
33 description: "Skip smart checks.",
34 type: bool,
35 optional: true,
36 default: false,
ff30caea
DM
37 },
38 "usage-type": {
39 type: DiskUsageType,
40 optional: true,
41 },
553cd12b
DM
42 },
43 },
44 returns: {
45 description: "Local disk list.",
46 type: Array,
47 items: {
48 type: DiskUsageInfo,
49 },
50 },
51 access: {
52 permission: &Permission::Privilege(&["system", "disks"], PRIV_SYS_AUDIT, false),
53 },
54)]
55/// List local disks
56pub fn list_disks(
57 skipsmart: bool,
ff30caea 58 usage_type: Option<DiskUsageType>,
553cd12b
DM
59) -> Result<Vec<DiskUsageInfo>, Error> {
60
61 let mut list = Vec::new();
62
63 for (_, info) in get_disks(None, skipsmart)? {
ff30caea
DM
64 if let Some(ref usage_type) = usage_type {
65 if info.used == *usage_type {
66 list.push(info);
67 }
68 } else {
69 list.push(info);
70 }
553cd12b
DM
71 }
72
bbff317a
FE
73 list.sort_by(|a, b| a.name.cmp(&b.name));
74
553cd12b
DM
75 Ok(list)
76}
77
7fa27795
DM
78#[api(
79 protected: true,
80 input: {
81 properties: {
ce8e3de4
DM
82 node: {
83 schema: NODE_SCHEMA,
84 },
7fa27795 85 disk: {
9069debc 86 schema: BLOCKDEVICE_NAME_SCHEMA,
7fa27795
DM
87 },
88 healthonly: {
89 description: "If true returns only the health status.",
90 type: bool,
91 optional: true,
92 },
93 },
94 },
95 returns: {
96 type: SmartData,
97 },
98 access: {
99 permission: &Permission::Privilege(&["system", "disks"], PRIV_SYS_AUDIT, false),
100 },
101)]
102/// Get SMART attributes and health of a disk.
103pub fn smart_status(
104 disk: String,
105 healthonly: Option<bool>,
106) -> Result<SmartData, Error> {
107
108 let healthonly = healthonly.unwrap_or(false);
109
110 let manager = DiskManage::new();
111 let disk = manager.disk_by_name(&disk)?;
112 get_smart_data(&disk, healthonly)
113}
114
707974fd
DM
115#[api(
116 protected: true,
117 input: {
118 properties: {
119 node: {
120 schema: NODE_SCHEMA,
121 },
122 disk: {
123 schema: BLOCKDEVICE_NAME_SCHEMA,
124 },
125 uuid: {
126 description: "UUID for the GPT table.",
127 type: String,
128 optional: true,
129 max_length: 36,
130 },
131 },
132 },
133 returns: {
134 schema: UPID_SCHEMA,
135 },
136 access: {
137 permission: &Permission::Privilege(&["system", "disks"], PRIV_SYS_MODIFY, false),
138 },
139)]
140/// Initialize empty Disk with GPT
141pub fn initialize_disk(
142 disk: String,
143 uuid: Option<String>,
144 rpcenv: &mut dyn RpcEnvironment,
145) -> Result<Value, Error> {
146
39735609 147 let to_stdout = rpcenv.env_type() == RpcEnvironmentType::CLI;
707974fd 148
049a22a3 149 let auth_id = rpcenv.get_auth_id().unwrap();
707974fd
DM
150
151 let info = get_disk_usage_info(&disk, true)?;
152
153 if info.used != DiskUsageType::Unused {
154 bail!("disk '{}' is already in use.", disk);
155 }
156
157 let upid_str = WorkerTask::new_thread(
e6dc35ac 158 "diskinit", Some(disk.clone()), auth_id, to_stdout, move |worker|
707974fd 159 {
1ec0d70d 160 task_log!(worker, "initialize disk {}", disk);
707974fd
DM
161
162 let disk_manager = DiskManage::new();
2b388026 163 let disk_info = disk_manager.disk_by_name(&disk)?;
707974fd
DM
164
165 inititialize_gpt_disk(&disk_info, uuid.as_deref())?;
166
167 Ok(())
168 })?;
169
170 Ok(json!(upid_str))
171}
172
553cd12b
DM
173#[sortable]
174const SUBDIRS: SubdirMap = &sorted!([
707974fd 175 // ("lvm", &lvm::ROUTER),
fb5a0665 176 ("directory", &directory::ROUTER),
929a13b3 177 ("zfs", &zfs::ROUTER),
707974fd
DM
178 (
179 "initgpt", &Router::new()
180 .post(&API_METHOD_INITIALIZE_DISK)
181 ),
553cd12b
DM
182 (
183 "list", &Router::new()
184 .get(&API_METHOD_LIST_DISKS)
185 ),
7fa27795
DM
186 (
187 "smart", &Router::new()
188 .get(&API_METHOD_SMART_STATUS)
189 ),
553cd12b
DM
190]);
191
192pub const ROUTER: Router = Router::new()
193 .get(&list_subdirs_api_method!(SUBDIRS))
194 .subdirs(SUBDIRS);