[pbs-devel] [RFC PATCH proxmox-backup 1/5] api2/admin/datastore: refactor list_dir_content in catalog_reader
Dietmar Maurer
dietmar at proxmox.com
Tue Dec 22 06:49:02 CET 2020
comments inline
> On 12/21/2020 12:25 PM Dominik Csapak <d.csapak at proxmox.com> wrote:
>
>
> 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)
> + }
> +
This is OK for me
> /// 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);
> + }
But this is API code, so we should find another place for this.
> +
> + Ok(res)
> + }
> +
> /// Finds all entries matching the given match patterns and calls the
> /// provided callback on them.
> pub fn find(
> --
> 2.20.1
>
>
>
> _______________________________________________
> pbs-devel mailing list
> pbs-devel at lists.proxmox.com
> https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel
More information about the pbs-devel
mailing list