move some more API types
ArchiveEntry -> pbs-datastore RestoreDaemonStatus -> pbs-api-types Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
40ff84b138
commit
013b1e8bca
|
@ -1,7 +1,8 @@
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use proxmox::api::api;
|
use proxmox::api::api;
|
||||||
|
|
||||||
#[api()]
|
#[api]
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "kebab-case")]
|
#[serde(rename_all = "kebab-case")]
|
||||||
/// General status information about a running VM file-restore daemon
|
/// General status information about a running VM file-restore daemon
|
||||||
|
@ -12,4 +13,3 @@ pub struct RestoreDaemonStatus {
|
||||||
/// not set, as then the status call will have reset the timer before returning the value
|
/// not set, as then the status call will have reset the timer before returning the value
|
||||||
pub timeout: i64,
|
pub timeout: i64,
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,8 @@ pub use upid::UPID;
|
||||||
mod crypto;
|
mod crypto;
|
||||||
pub use crypto::{CryptMode, Fingerprint};
|
pub use crypto::{CryptMode, Fingerprint};
|
||||||
|
|
||||||
|
pub mod file_restore;
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod local_macros {
|
mod local_macros {
|
||||||
|
|
|
@ -5,8 +5,10 @@ use std::io::{Read, Write, Seek, SeekFrom};
|
||||||
use std::os::unix::ffi::OsStrExt;
|
use std::os::unix::ffi::OsStrExt;
|
||||||
|
|
||||||
use anyhow::{bail, format_err, Error};
|
use anyhow::{bail, format_err, Error};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use pathpatterns::{MatchList, MatchType};
|
use pathpatterns::{MatchList, MatchType};
|
||||||
|
use proxmox::api::api;
|
||||||
use proxmox::tools::io::ReadExt;
|
use proxmox::tools::io::ReadExt;
|
||||||
|
|
||||||
use crate::file_formats::PROXMOX_CATALOG_FILE_MAGIC_1_0;
|
use crate::file_formats::PROXMOX_CATALOG_FILE_MAGIC_1_0;
|
||||||
|
@ -808,3 +810,56 @@ fn test_catalog_i64_compatibility() {
|
||||||
test_encode_decode((1<<50)-1);
|
test_encode_decode((1<<50)-1);
|
||||||
test_encode_decode(u64::MAX);
|
test_encode_decode(u64::MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An entry in a hierarchy of files for restore and listing.
|
||||||
|
#[api]
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct ArchiveEntry {
|
||||||
|
/// Base64-encoded full path to the file, including the filename
|
||||||
|
pub filepath: String,
|
||||||
|
/// Displayable filename text for UIs
|
||||||
|
pub text: String,
|
||||||
|
/// File or directory type of this entry
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
pub entry_type: String,
|
||||||
|
/// Is this entry a leaf node, or does it have children (i.e. a directory)?
|
||||||
|
pub leaf: bool,
|
||||||
|
/// The file size, if entry_type is 'f' (file)
|
||||||
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
|
pub size: Option<u64>,
|
||||||
|
/// The file "last modified" time stamp, if entry_type is 'f' (file)
|
||||||
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
|
pub mtime: Option<i64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ArchiveEntry {
|
||||||
|
pub fn new(filepath: &[u8], entry_type: Option<&DirEntryAttribute>) -> Self {
|
||||||
|
let size = match entry_type {
|
||||||
|
Some(DirEntryAttribute::File { size, .. }) => Some(*size),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
Self::new_with_size(filepath, entry_type, size)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_with_size(
|
||||||
|
filepath: &[u8],
|
||||||
|
entry_type: Option<&DirEntryAttribute>,
|
||||||
|
size: Option<u64>,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
filepath: base64::encode(filepath),
|
||||||
|
text: String::from_utf8_lossy(filepath.split(|x| *x == b'/').last().unwrap())
|
||||||
|
.to_string(),
|
||||||
|
entry_type: match entry_type {
|
||||||
|
Some(entry_type) => CatalogEntryType::from(entry_type).to_string(),
|
||||||
|
None => "v".to_owned(),
|
||||||
|
},
|
||||||
|
leaf: !matches!(entry_type, None | Some(DirEntryAttribute::Directory { .. })),
|
||||||
|
size,
|
||||||
|
mtime: match entry_type {
|
||||||
|
Some(DirEntryAttribute::File { mtime, .. }) => Some(*mtime),
|
||||||
|
_ => None,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ use pbs_client::pxar::create_zip;
|
||||||
use pbs_datastore::{BackupDir, BackupGroup, StoreProgress, CATALOG_NAME};
|
use pbs_datastore::{BackupDir, BackupGroup, StoreProgress, CATALOG_NAME};
|
||||||
use pbs_datastore::backup_info::BackupInfo;
|
use pbs_datastore::backup_info::BackupInfo;
|
||||||
use pbs_datastore::cached_chunk_reader::CachedChunkReader;
|
use pbs_datastore::cached_chunk_reader::CachedChunkReader;
|
||||||
use pbs_datastore::catalog::CatalogReader;
|
use pbs_datastore::catalog::{ArchiveEntry, CatalogReader};
|
||||||
use pbs_datastore::data_blob::DataBlob;
|
use pbs_datastore::data_blob::DataBlob;
|
||||||
use pbs_datastore::data_blob_reader::DataBlobReader;
|
use pbs_datastore::data_blob_reader::DataBlobReader;
|
||||||
use pbs_datastore::dynamic_index::{BufferedDynamicReader, DynamicIndexReader, LocalDynamicReadAt};
|
use pbs_datastore::dynamic_index::{BufferedDynamicReader, DynamicIndexReader, LocalDynamicReadAt};
|
||||||
|
@ -48,8 +48,8 @@ use pbs_tools::stream::{AsyncReaderStream, AsyncChannelWriter};
|
||||||
use pbs_tools::json::{required_integer_param, required_string_param};
|
use pbs_tools::json::{required_integer_param, required_string_param};
|
||||||
|
|
||||||
use crate::api2::types::{
|
use crate::api2::types::{
|
||||||
ArchiveEntry, DataStoreStatus, RRDMode, RRDTimeFrameResolution,
|
DataStoreStatus, RRDMode, RRDTimeFrameResolution, IGNORE_VERIFIED_BACKUPS_SCHEMA, UPID_SCHEMA,
|
||||||
IGNORE_VERIFIED_BACKUPS_SCHEMA, UPID_SCHEMA, VERIFICATION_OUTDATED_AFTER_SCHEMA
|
VERIFICATION_OUTDATED_AFTER_SCHEMA
|
||||||
};
|
};
|
||||||
use crate::api2::node::rrd::create_value_from_rrd;
|
use crate::api2::node::rrd::create_value_from_rrd;
|
||||||
use crate::api2::helpers;
|
use crate::api2::helpers;
|
||||||
|
|
|
@ -7,9 +7,7 @@ use hyper::{Body, Response, StatusCode, header};
|
||||||
|
|
||||||
use proxmox::http_bail;
|
use proxmox::http_bail;
|
||||||
|
|
||||||
use pbs_datastore::catalog::{CatalogReader, DirEntryAttribute};
|
use pbs_datastore::catalog::{ArchiveEntry, CatalogReader, DirEntryAttribute};
|
||||||
|
|
||||||
use crate::api2::types::ArchiveEntry;
|
|
||||||
|
|
||||||
pub async fn create_download_response(path: PathBuf) -> Result<Response<Body>, Error> {
|
pub async fn create_download_response(path: PathBuf) -> Result<Response<Body>, Error> {
|
||||||
let file = match tokio::fs::File::open(path.clone()).await {
|
let file = match tokio::fs::File::open(path.clone()).await {
|
||||||
|
|
|
@ -6,16 +6,11 @@ use serde::{Deserialize, Serialize};
|
||||||
use proxmox::api::{api, schema::*};
|
use proxmox::api::{api, schema::*};
|
||||||
use proxmox::const_regex;
|
use proxmox::const_regex;
|
||||||
|
|
||||||
use pbs_datastore::catalog::{CatalogEntryType, DirEntryAttribute};
|
|
||||||
|
|
||||||
use crate::config::acl::Role;
|
use crate::config::acl::Role;
|
||||||
|
|
||||||
mod tape;
|
mod tape;
|
||||||
pub use tape::*;
|
pub use tape::*;
|
||||||
|
|
||||||
mod file_restore;
|
|
||||||
pub use file_restore::*;
|
|
||||||
|
|
||||||
mod acme;
|
mod acme;
|
||||||
pub use acme::*;
|
pub use acme::*;
|
||||||
|
|
||||||
|
@ -818,59 +813,6 @@ pub struct DatastoreNotify {
|
||||||
pub sync: Option<Notify>,
|
pub sync: Option<Notify>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An entry in a hierarchy of files for restore and listing.
|
|
||||||
#[api()]
|
|
||||||
#[derive(Serialize, Deserialize)]
|
|
||||||
pub struct ArchiveEntry {
|
|
||||||
/// Base64-encoded full path to the file, including the filename
|
|
||||||
pub filepath: String,
|
|
||||||
/// Displayable filename text for UIs
|
|
||||||
pub text: String,
|
|
||||||
/// File or directory type of this entry
|
|
||||||
#[serde(rename = "type")]
|
|
||||||
pub entry_type: String,
|
|
||||||
/// Is this entry a leaf node, or does it have children (i.e. a directory)?
|
|
||||||
pub leaf: bool,
|
|
||||||
/// The file size, if entry_type is 'f' (file)
|
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
|
||||||
pub size: Option<u64>,
|
|
||||||
/// The file "last modified" time stamp, if entry_type is 'f' (file)
|
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
|
||||||
pub mtime: Option<i64>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ArchiveEntry {
|
|
||||||
pub fn new(filepath: &[u8], entry_type: Option<&DirEntryAttribute>) -> Self {
|
|
||||||
let size = match entry_type {
|
|
||||||
Some(DirEntryAttribute::File { size, .. }) => Some(*size),
|
|
||||||
_ => None,
|
|
||||||
};
|
|
||||||
Self::new_with_size(filepath, entry_type, size)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_with_size(
|
|
||||||
filepath: &[u8],
|
|
||||||
entry_type: Option<&DirEntryAttribute>,
|
|
||||||
size: Option<u64>,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
|
||||||
filepath: base64::encode(filepath),
|
|
||||||
text: String::from_utf8_lossy(filepath.split(|x| *x == b'/').last().unwrap())
|
|
||||||
.to_string(),
|
|
||||||
entry_type: match entry_type {
|
|
||||||
Some(entry_type) => CatalogEntryType::from(entry_type).to_string(),
|
|
||||||
None => "v".to_owned(),
|
|
||||||
},
|
|
||||||
leaf: !matches!(entry_type, None | Some(DirEntryAttribute::Directory { .. })),
|
|
||||||
size,
|
|
||||||
mtime: match entry_type {
|
|
||||||
Some(DirEntryAttribute::File { mtime, .. }) => Some(*mtime),
|
|
||||||
_ => None,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const DATASTORE_NOTIFY_STRING_SCHEMA: Schema = StringSchema::new(
|
pub const DATASTORE_NOTIFY_STRING_SCHEMA: Schema = StringSchema::new(
|
||||||
"Datastore notification setting")
|
"Datastore notification setting")
|
||||||
.format(&ApiStringFormat::PropertyString(&DatastoreNotify::API_SCHEMA))
|
.format(&ApiStringFormat::PropertyString(&DatastoreNotify::API_SCHEMA))
|
||||||
|
|
|
@ -19,7 +19,7 @@ use pxar::decoder::aio::Decoder;
|
||||||
use pbs_api_types::CryptMode;
|
use pbs_api_types::CryptMode;
|
||||||
use pbs_datastore::{CryptConfig, CATALOG_NAME};
|
use pbs_datastore::{CryptConfig, CATALOG_NAME};
|
||||||
use pbs_datastore::backup_info::BackupDir;
|
use pbs_datastore::backup_info::BackupDir;
|
||||||
use pbs_datastore::catalog::{CatalogReader, DirEntryAttribute};
|
use pbs_datastore::catalog::{ArchiveEntry, CatalogReader, DirEntryAttribute};
|
||||||
use pbs_datastore::dynamic_index::{BufferedDynamicReader, LocalDynamicReadAt};
|
use pbs_datastore::dynamic_index::{BufferedDynamicReader, LocalDynamicReadAt};
|
||||||
use pbs_datastore::index::IndexFile;
|
use pbs_datastore::index::IndexFile;
|
||||||
use pbs_datastore::key_derivation::decrypt_key;
|
use pbs_datastore::key_derivation::decrypt_key;
|
||||||
|
@ -34,7 +34,7 @@ use pbs_client::tools::{
|
||||||
REPO_URL_SCHEMA,
|
REPO_URL_SCHEMA,
|
||||||
};
|
};
|
||||||
|
|
||||||
use proxmox_backup::api2::{helpers, types::ArchiveEntry};
|
use proxmox_backup::api2::helpers;
|
||||||
use proxmox_backup::tools;
|
use proxmox_backup::tools;
|
||||||
|
|
||||||
mod proxmox_file_restore;
|
mod proxmox_file_restore;
|
||||||
|
|
|
@ -12,10 +12,9 @@ use proxmox::api::{api, cli::*};
|
||||||
|
|
||||||
use pbs_client::BackupRepository;
|
use pbs_client::BackupRepository;
|
||||||
use pbs_datastore::backup_info::BackupDir;
|
use pbs_datastore::backup_info::BackupDir;
|
||||||
|
use pbs_datastore::catalog::ArchiveEntry;
|
||||||
use pbs_datastore::manifest::BackupManifest;
|
use pbs_datastore::manifest::BackupManifest;
|
||||||
|
|
||||||
use proxmox_backup::api2::types::ArchiveEntry;
|
|
||||||
|
|
||||||
use super::block_driver_qemu::QemuBlockDriver;
|
use super::block_driver_qemu::QemuBlockDriver;
|
||||||
|
|
||||||
/// Contains details about a snapshot that is to be accessed by block file restore
|
/// Contains details about a snapshot that is to be accessed by block file restore
|
||||||
|
|
|
@ -12,8 +12,8 @@ use proxmox::tools::fs::lock_file;
|
||||||
|
|
||||||
use pbs_client::{DEFAULT_VSOCK_PORT, BackupRepository, VsockClient};
|
use pbs_client::{DEFAULT_VSOCK_PORT, BackupRepository, VsockClient};
|
||||||
use pbs_datastore::backup_info::BackupDir;
|
use pbs_datastore::backup_info::BackupDir;
|
||||||
|
use pbs_datastore::catalog::ArchiveEntry;
|
||||||
|
|
||||||
use proxmox_backup::api2::types::ArchiveEntry;
|
|
||||||
use proxmox_backup::tools;
|
use proxmox_backup::tools;
|
||||||
|
|
||||||
use super::block_driver::*;
|
use super::block_driver::*;
|
||||||
|
|
|
@ -19,14 +19,13 @@ use proxmox::api::{
|
||||||
};
|
};
|
||||||
use proxmox::{identity, list_subdirs_api_method, sortable};
|
use proxmox::{identity, list_subdirs_api_method, sortable};
|
||||||
|
|
||||||
|
use pbs_api_types::file_restore::RestoreDaemonStatus;
|
||||||
use pbs_client::pxar::{create_archive, Flags, PxarCreateOptions, ENCODER_MAX_ENTRIES};
|
use pbs_client::pxar::{create_archive, Flags, PxarCreateOptions, ENCODER_MAX_ENTRIES};
|
||||||
use pbs_datastore::catalog::DirEntryAttribute;
|
use pbs_datastore::catalog::{ArchiveEntry, DirEntryAttribute};
|
||||||
use pbs_tools::fs::read_subdir;
|
use pbs_tools::fs::read_subdir;
|
||||||
use pbs_tools::json::required_string_param;
|
use pbs_tools::json::required_string_param;
|
||||||
use pbs_tools::zip::zip_directory;
|
use pbs_tools::zip::zip_directory;
|
||||||
|
|
||||||
use proxmox_backup::api2::types::*;
|
|
||||||
|
|
||||||
use pxar::encoder::aio::TokioWriter;
|
use pxar::encoder::aio::TokioWriter;
|
||||||
|
|
||||||
use super::{disk::ResolveResult, watchdog_remaining, watchdog_inhibit, watchdog_ping};
|
use super::{disk::ResolveResult, watchdog_remaining, watchdog_inhibit, watchdog_ping};
|
||||||
|
|
Loading…
Reference in New Issue