1 use proxmox
::list_subdirs_api_method
;
4 use serde_json
::{json, Value}
;
15 use crate::api2
::types
::{
18 RRDTimeFrameResolution
,
24 use crate::backup
::{DataStore}
;
25 use crate::config
::datastore
;
26 use crate::tools
::statistics
::{linear_regression}
;
27 use crate::config
::cached_user_info
::CachedUserInfo
;
28 use crate::config
::acl
::{
31 PRIV_DATASTORE_BACKUP
,
36 description
: "Lists the Status of the Datastores.",
39 description
: "Status of a Datastore",
43 schema
: DATASTORE_SCHEMA
,
47 description
: "The Size of the underlying storage in bytes",
51 description
: "The used bytes of the underlying storage",
55 description
: "The available bytes of the underlying storage",
59 description
: "A list of usages of the past (last Month).",
62 description
: "The usage of a time in the past. Either null or between 0.0 and 1.0.",
65 "estimated-full-date": {
68 description
: "Estimation of the UNIX epoch when the storage will be full.\
69 This is calculated via a simple Linear Regression (Least Squares)\
70 of RRD data of the last Month. Missing if there are not enough data points yet.\
71 If the estimate lies in the past, the usage is decreasing.",
77 permission
: &Permission
::Anybody
,
80 /// List Datastore usages and estimates
84 rpcenv
: &mut dyn RpcEnvironment
,
85 ) -> Result
<Value
, Error
> {
87 let (config
, _digest
) = datastore
::config()?
;
89 let userid
: Userid
= rpcenv
.get_user().unwrap().parse()?
;
90 let user_info
= CachedUserInfo
::new()?
;
92 let mut list
= Vec
::new();
94 for (store
, (_
, _
)) in &config
.sections
{
95 let user_privs
= user_info
.lookup_privs(&userid
, &["datastore", &store
]);
96 let allowed
= (user_privs
& (PRIV_DATASTORE_AUDIT
| PRIV_DATASTORE_BACKUP
)) != 0;
101 let datastore
= DataStore
::lookup_datastore(&store
)?
;
102 let status
= crate::tools
::disks
::disk_usage(&datastore
.base_path())?
;
104 let mut entry
= json
!({
106 "total": status
.total
,
108 "avail": status
.avail
,
111 let rrd_dir
= format
!("datastore/{}", store
);
112 let now
= proxmox
::tools
::time
::epoch_f64();
113 let rrd_resolution
= RRDTimeFrameResolution
::Month
;
114 let rrd_mode
= RRDMode
::Average
;
116 let total_res
= crate::rrd
::extract_cached_data(
124 let used_res
= crate::rrd
::extract_cached_data(
132 match (total_res
, used_res
) {
133 (Some((start
, reso
, total_list
)), Some((_
, _
, used_list
))) => {
134 let mut usage_list
: Vec
<f64> = Vec
::new();
135 let mut time_list
: Vec
<u64> = Vec
::new();
136 let mut history
= Vec
::new();
138 for (idx
, used
) in used_list
.iter().enumerate() {
139 let total
= if idx
< total_list
.len() {
145 match (total
, used
) {
146 (Some(total
), Some(used
)) if total
!= 0.0 => {
147 time_list
.push(start
+ (idx
as u64)*reso
);
148 let usage
= used
/total
;
149 usage_list
.push(usage
);
150 history
.push(json
!(usage
));
153 history
.push(json
!(null
))
158 entry
["history"] = history
.into();
160 // we skip the calculation for datastores with not enough data
161 if usage_list
.len() >= 7 {
162 if let Some((a
,b
)) = linear_regression(&time_list
, &usage_list
) {
164 let estimate
= (1.0 - a
) / b
;
165 entry
["estimated-full-date"] = Value
::from(estimate
.floor() as u64);
167 entry
["estimated-full-date"] = Value
::from(0);
186 description
: "Only list tasks since this UNIX epoch.",
192 description
: "A list of tasks.",
194 items
: { type: TaskListItem }
,
197 description
: "Users can only see there own tasks, unless the have Sys.Audit on /system/tasks.",
198 permission
: &Permission
::Anybody
,
205 rpcenv
: &mut dyn RpcEnvironment
,
206 ) -> Result
<Vec
<TaskListItem
>, Error
> {
208 let userid
: Userid
= rpcenv
.get_user().unwrap().parse()?
;
209 let user_info
= CachedUserInfo
::new()?
;
210 let user_privs
= user_info
.lookup_privs(&userid
, &["system", "tasks"]);
212 let list_all
= (user_privs
& PRIV_SYS_AUDIT
) != 0;
213 let since
= since
.unwrap_or_else(|| 0);
215 let list
: Vec
<TaskListItem
> = server
::TaskListInfoIterator
::new(false)?
218 Ok(info
) => info
.upid
.starttime
> since
,
225 if list_all
|| info
.upid
.userid
== userid
{
226 Some(Ok(TaskListItem
::from(info
)))
231 Err(err
) => Some(Err(err
))
234 .collect
::<Result
<Vec
<TaskListItem
>, Error
>>()?
;
239 const SUBDIRS
: SubdirMap
= &[
240 ("datastore-usage", &Router
::new().get(&API_METHOD_DATASTORE_STATUS
)),
241 ("tasks", &Router
::new().get(&API_METHOD_LIST_TASKS
)),
244 pub const ROUTER
: Router
= Router
::new()
245 .get(&list_subdirs_api_method
!(SUBDIRS
))