5
0
mirror of git://git.proxmox.com/git/proxmox-backup.git synced 2025-01-06 13:18:00 +03:00

pbs-api-types: add mount_status field to DataStoreListItem

Signed-off-by: Hannes Laimer <h.laimer@proxmox.com>
This commit is contained in:
Hannes Laimer 2024-11-25 17:21:55 +01:00 committed by Thomas Lamprecht
parent 40a2b110bf
commit 76609915d6
3 changed files with 66 additions and 21 deletions

View File

@ -178,6 +178,20 @@ pub enum ChunkOrder {
Inode,
}
#[api]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
/// Current mounting status of a datastore, useful for removable datastores.
pub enum DataStoreMountStatus {
/// Removable datastore is currently mounted correctly.
Mounted,
/// Removable datastore is currebtly not mounted.
NotMounted,
/// Datastore is not removable, so there is no mount status.
#[default]
NonRemovable,
}
#[api]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
@ -451,6 +465,7 @@ impl DataStoreConfig {
pub struct DataStoreListItem {
pub store: String,
pub comment: Option<String>,
pub mount_status: DataStoreMountStatus,
/// If the datastore is in maintenance mode, information about it
#[serde(skip_serializing_if = "Option::is_none")]
pub maintenance: Option<String>,
@ -1456,6 +1471,7 @@ pub struct DataStoreStatusListItem {
/// The available bytes of the underlying storage. (-1 on error)
#[serde(skip_serializing_if = "Option::is_none")]
pub avail: Option<u64>,
pub mount_status: DataStoreMountStatus,
/// A list of usages of the past (last Month).
#[serde(skip_serializing_if = "Option::is_none")]
pub history: Option<Vec<Option<f64>>>,
@ -1480,12 +1496,13 @@ pub struct DataStoreStatusListItem {
}
impl DataStoreStatusListItem {
pub fn empty(store: &str, err: Option<String>) -> Self {
pub fn empty(store: &str, err: Option<String>, mount_status: DataStoreMountStatus) -> Self {
DataStoreStatusListItem {
store: store.to_owned(),
total: None,
used: None,
avail: None,
mount_status,
history: None,
history_start: None,
history_delta: None,

View File

@ -38,14 +38,15 @@ use pxar::EntryKind;
use pbs_api_types::{
print_ns_and_snapshot, print_store_and_ns, ArchiveType, Authid, BackupArchiveName,
BackupContent, BackupGroupDeleteStats, BackupNamespace, BackupType, Counts, CryptMode,
DataStoreConfig, DataStoreListItem, DataStoreStatus, GarbageCollectionJobStatus, GroupListItem,
JobScheduleStatus, KeepOptions, MaintenanceMode, MaintenanceType, Operation, PruneJobOptions,
SnapshotListItem, SnapshotVerifyState, BACKUP_ARCHIVE_NAME_SCHEMA, BACKUP_ID_SCHEMA,
BACKUP_NAMESPACE_SCHEMA, BACKUP_TIME_SCHEMA, BACKUP_TYPE_SCHEMA, CATALOG_NAME,
CLIENT_LOG_BLOB_NAME, DATASTORE_SCHEMA, IGNORE_VERIFIED_BACKUPS_SCHEMA, MANIFEST_BLOB_NAME,
MAX_NAMESPACE_DEPTH, NS_MAX_DEPTH_SCHEMA, PRIV_DATASTORE_AUDIT, PRIV_DATASTORE_BACKUP,
PRIV_DATASTORE_MODIFY, PRIV_DATASTORE_PRUNE, PRIV_DATASTORE_READ, PRIV_DATASTORE_VERIFY, UPID,
UPID_SCHEMA, VERIFICATION_OUTDATED_AFTER_SCHEMA,
DataStoreConfig, DataStoreListItem, DataStoreMountStatus, DataStoreStatus,
GarbageCollectionJobStatus, GroupListItem, JobScheduleStatus, KeepOptions, MaintenanceMode,
MaintenanceType, Operation, PruneJobOptions, SnapshotListItem, SnapshotVerifyState,
BACKUP_ARCHIVE_NAME_SCHEMA, BACKUP_ID_SCHEMA, BACKUP_NAMESPACE_SCHEMA, BACKUP_TIME_SCHEMA,
BACKUP_TYPE_SCHEMA, CATALOG_NAME, CLIENT_LOG_BLOB_NAME, DATASTORE_SCHEMA,
IGNORE_VERIFIED_BACKUPS_SCHEMA, MANIFEST_BLOB_NAME, MAX_NAMESPACE_DEPTH, NS_MAX_DEPTH_SCHEMA,
PRIV_DATASTORE_AUDIT, PRIV_DATASTORE_BACKUP, PRIV_DATASTORE_MODIFY, PRIV_DATASTORE_PRUNE,
PRIV_DATASTORE_READ, PRIV_DATASTORE_VERIFY, UPID, UPID_SCHEMA,
VERIFICATION_OUTDATED_AFTER_SCHEMA,
};
use pbs_client::pxar::{create_tar, create_zip};
use pbs_config::CachedUserInfo;
@ -1323,8 +1324,8 @@ pub fn get_datastore_list(
let mut list = Vec::new();
for (store, (_, data)) in &config.sections {
let acl_path = &["datastore", store];
for (store, (_, data)) in config.sections {
let acl_path = &["datastore", &store];
let user_privs = user_info.lookup_privs(&auth_id, acl_path);
let allowed = (user_privs & (PRIV_DATASTORE_AUDIT | PRIV_DATASTORE_BACKUP)) != 0;
@ -1335,15 +1336,20 @@ pub fn get_datastore_list(
}
}
let store_config: DataStoreConfig = serde_json::from_value(data)?;
let mount_status = match pbs_datastore::get_datastore_mount_status(&store_config) {
Some(true) => DataStoreMountStatus::Mounted,
Some(false) => DataStoreMountStatus::NotMounted,
None => DataStoreMountStatus::NonRemovable,
};
if allowed || allow_id {
list.push(DataStoreListItem {
store: store.clone(),
comment: if !allowed {
None
} else {
data["comment"].as_str().map(String::from)
},
maintenance: data["maintenance-mode"].as_str().map(String::from),
comment: store_config.comment.filter(|_| allowed),
mount_status,
maintenance: store_config.maintenance_mode,
});
}
}

View File

@ -10,11 +10,12 @@ use proxmox_schema::api;
use proxmox_sortable_macro::sortable;
use pbs_api_types::{
Authid, DataStoreStatusListItem, Operation, PRIV_DATASTORE_AUDIT, PRIV_DATASTORE_BACKUP,
Authid, DataStoreConfig, DataStoreMountStatus, DataStoreStatusListItem, Operation,
PRIV_DATASTORE_AUDIT, PRIV_DATASTORE_BACKUP,
};
use pbs_config::CachedUserInfo;
use pbs_datastore::DataStore;
use pbs_datastore::{get_datastore_mount_status, DataStore};
use crate::server::metric_collection::rrd::extract_rrd_data;
use crate::tools::statistics::linear_regression;
@ -51,10 +52,26 @@ pub async fn datastore_status(
for (store, (_, _)) in &config.sections {
let user_privs = user_info.lookup_privs(&auth_id, &["datastore", store]);
let allowed = (user_privs & (PRIV_DATASTORE_AUDIT | PRIV_DATASTORE_BACKUP)) != 0;
let store_config = config.lookup::<DataStoreConfig>("datastore", store)?;
let mount_status = match get_datastore_mount_status(&store_config) {
Some(true) => DataStoreMountStatus::Mounted,
Some(false) => {
list.push(DataStoreStatusListItem::empty(
store,
None,
DataStoreMountStatus::NotMounted,
));
continue;
}
None => DataStoreMountStatus::NonRemovable,
};
if !allowed {
if let Ok(datastore) = DataStore::lookup_datastore(store, Some(Operation::Lookup)) {
if can_access_any_namespace(datastore, &auth_id, &user_info) {
list.push(DataStoreStatusListItem::empty(store, None));
list.push(DataStoreStatusListItem::empty(store, None, mount_status));
}
}
continue;
@ -63,7 +80,11 @@ pub async fn datastore_status(
let datastore = match DataStore::lookup_datastore(store, Some(Operation::Read)) {
Ok(datastore) => datastore,
Err(err) => {
list.push(DataStoreStatusListItem::empty(store, Some(err.to_string())));
list.push(DataStoreStatusListItem::empty(
store,
Some(err.to_string()),
mount_status,
));
continue;
}
};
@ -74,6 +95,7 @@ pub async fn datastore_status(
total: Some(status.total),
used: Some(status.used),
avail: Some(status.available),
mount_status,
history: None,
history_start: None,
history_delta: None,