[pbs-devel] [RFC PATCH proxmox-backup 1/5] api2/admin/datastore: refactor list_dir_content in catalog_reader
Dominik Csapak
d.csapak at proxmox.com
Mon Dec 21 12:25:03 CET 2020
we will reuse that later in the client, so we need it somewhere
we can use from there
Signed-off-by: Dominik Csapak <d.csapak at proxmox.com>
---
src/api2/admin/datastore.rs | 52 ++++-------------------------
src/backup/catalog.rs | 65 +++++++++++++++++++++++++++++++++++++
2 files changed, 72 insertions(+), 45 deletions(-)
diff --git a/src/api2/admin/datastore.rs b/src/api2/admin/datastore.rs
index 16fee943..5f06a2bf 100644
--- a/src/api2/admin/datastore.rs
+++ b/src/api2/admin/datastore.rs
@@ -1302,7 +1302,7 @@ fn catalog(
_param: Value,
_info: &ApiMethod,
rpcenv: &mut dyn RpcEnvironment,
-) -> Result<Value, Error> {
+) -> Result<Vec<Value>, Error> {
let datastore = DataStore::lookup_datastore(&store)?;
let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
@@ -1334,52 +1334,14 @@ fn catalog(
let reader = BufferedDynamicReader::new(index, chunk_reader);
let mut catalog_reader = CatalogReader::new(reader);
- let mut current = catalog_reader.root()?;
- let mut components = vec![];
-
- if filepath != "root" {
- components = base64::decode(filepath)?;
- if components.len() > 0 && components[0] == '/' as u8 {
- components.remove(0);
- }
- for component in components.split(|c| *c == '/' as u8) {
- if let Some(entry) = catalog_reader.lookup(¤t, component)? {
- current = entry;
- } else {
- bail!("path {:?} not found in catalog", &String::from_utf8_lossy(&components));
- }
- }
- }
-
- let mut res = Vec::new();
-
- for direntry in catalog_reader.read_dir(¤t)? {
- let mut components = components.clone();
- components.push('/' as u8);
- components.extend(&direntry.name);
- let path = base64::encode(components);
- let text = String::from_utf8_lossy(&direntry.name);
- let mut entry = json!({
- "filepath": path,
- "text": text,
- "type": CatalogEntryType::from(&direntry.attr).to_string(),
- "leaf": true,
- });
- match direntry.attr {
- DirEntryAttribute::Directory { start: _ } => {
- entry["leaf"] = false.into();
- },
- DirEntryAttribute::File { size, mtime } => {
- entry["size"] = size.into();
- entry["mtime"] = mtime.into();
- },
- _ => {},
- }
- res.push(entry);
- }
+ let path = if filepath != "root" {
+ base64::decode(filepath)?
+ } else {
+ vec![b'/']
+ };
- Ok(res.into())
+ catalog_reader.list_dir_content(&path)
}
fn recurse_files<'a, T, W>(
diff --git a/src/backup/catalog.rs b/src/backup/catalog.rs
index b500fb93..5f8e85a6 100644
--- a/src/backup/catalog.rs
+++ b/src/backup/catalog.rs
@@ -5,6 +5,7 @@ use std::io::{Read, Write, Seek, SeekFrom};
use std::os::unix::ffi::OsStrExt;
use anyhow::{bail, format_err, Error};
+use serde_json::{json, Value};
use pathpatterns::{MatchList, MatchType};
use proxmox::tools::io::ReadExt;
@@ -474,6 +475,32 @@ impl <R: Read + Seek> CatalogReader<R> {
Ok(entry_list)
}
+ /// Lookup a DirEntry from an absolute path
+ pub fn lookup_recursive(
+ &mut self,
+ path: &[u8],
+ ) -> Result<DirEntry, Error> {
+ let mut current = self.root()?;
+ if path == b"/" {
+ return Ok(current);
+ }
+
+ let components = if path.len() > 0 && path[0] == b'/' {
+ &path[1..]
+ } else {
+ path
+ }.split(|c| *c == b'/');
+
+ for comp in components {
+ if let Some(entry) = self.lookup(¤t, comp)? {
+ current = entry;
+ } else {
+ bail!("path {:?} not found in catalog", String::from_utf8_lossy(&path));
+ }
+ }
+ Ok(current)
+ }
+
/// Lockup a DirEntry inside a parent directory
pub fn lookup(
&mut self,
@@ -554,6 +581,44 @@ impl <R: Read + Seek> CatalogReader<R> {
})
}
+ /// Returns the list of content of the given path as json
+ pub fn list_dir_content(&mut self, path: &[u8]) -> Result<Vec<Value>, Error> {
+ let dir = self.lookup_recursive(path)?;
+ let mut res = vec![];
+ let mut path = path.to_vec();
+ if path.len() > 0 && path[0] == b'/' {
+ path.remove(0);
+ }
+
+ for direntry in self.read_dir(&dir)? {
+ let mut components = path.clone();
+ components.push(b'/');
+ components.extend(&direntry.name);
+ let path = base64::encode(&components);
+ let text = String::from_utf8_lossy(&direntry.name);
+ let mut entry = json!({
+ "filepath": path,
+ "text": text,
+ "name": direntry.name.clone(),
+ "type": CatalogEntryType::from(&direntry.attr).to_string(),
+ "leaf": true,
+ });
+ match direntry.attr {
+ DirEntryAttribute::Directory { start: _ } => {
+ entry["leaf"] = false.into();
+ },
+ DirEntryAttribute::File { size, mtime } => {
+ entry["size"] = size.into();
+ entry["mtime"] = mtime.into();
+ },
+ _ => {},
+ }
+ res.push(entry);
+ }
+
+ Ok(res)
+ }
+
/// Finds all entries matching the given match patterns and calls the
/// provided callback on them.
pub fn find(
--
2.20.1
More information about the pbs-devel
mailing list