]> git.proxmox.com Git - proxmox-backup.git/commitdiff
backup/datastore.rs: implement list_backups
authorDietmar Maurer <dietmar@proxmox.com>
Sun, 20 Jan 2019 17:02:06 +0000 (18:02 +0100)
committerDietmar Maurer <dietmar@proxmox.com>
Sun, 20 Jan 2019 17:02:27 +0000 (18:02 +0100)
src/backup/datastore.rs

index 43fb2750fd391a97c96718b5052405fac9574ad0..c4339f07824245d77ee178123c585a573e84da62 100644 (file)
@@ -1,10 +1,15 @@
 use failure::*;
 
+use chrono::prelude::*;
+
 use std::path::{PathBuf, Path};
 use std::collections::HashMap;
 use lazy_static::lazy_static;
 use std::sync::{Mutex, Arc};
 
+use std::os::unix::io::AsRawFd;
+
+use crate::tools;
 use crate::config::datastore;
 use super::chunk_store::*;
 use super::image_index::*;
@@ -17,6 +22,13 @@ pub struct DataStore {
     gc_mutex: Mutex<bool>,
 }
 
+#[derive(Debug)]
+pub struct BackupInfo {
+    pub backup_type: String,
+    pub backup_id: String,
+    pub backup_time: i64,
+}
+
 lazy_static!{
     static ref datastore_map: Mutex<HashMap<String, Arc<DataStore>>> =  Mutex::new(HashMap::new());
 }
@@ -150,6 +162,45 @@ impl DataStore {
         Ok(relative_path)
     }
 
+    pub fn list_backups(&self) -> Result<Vec<BackupInfo>, Error> {
+        let path = self.base_path();
+
+        let mut list = vec![];
+
+        lazy_static! {
+            static ref BACKUP_TYPE_REGEX: regex::Regex = regex::Regex::new("^(host|vm|ct)$").unwrap();
+        }
+        lazy_static! {
+            static ref BACKUP_ID_REGEX: regex::Regex = regex::Regex::new("^[A-Za-z][A-Za-z0-9_-]+$").unwrap();
+        }
+        lazy_static! {
+             static ref BACKUP_DATE_REGEX: regex::Regex = regex::Regex::new(
+                 "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}$").unwrap();
+        }
+
+        tools::scandir(libc::AT_FDCWD, &path, &BACKUP_TYPE_REGEX, |l0_fd, backup_type, file_type| {
+            if file_type != nix::dir::Type::Directory { return Ok(()); }
+            tools::scandir(l0_fd, backup_type, &BACKUP_ID_REGEX, |l1_fd, backup_id, file_type| {
+                if file_type != nix::dir::Type::Directory { return Ok(()); }
+                tools::scandir(l1_fd, backup_id, &BACKUP_DATE_REGEX, |_, backup_time, file_type| {
+                    if file_type != nix::dir::Type::Directory { return Ok(()); }
+
+                    let dt = Utc.datetime_from_str(backup_time, "%Y-%m-%dT%H:%M:%S")?;
+
+                    list.push(BackupInfo {
+                        backup_type: backup_type.to_owned(),
+                        backup_id: backup_id.to_owned(),
+                        backup_time: dt.timestamp(),
+                    });
+
+                    Ok(())
+                })
+            })
+        })?;
+
+        Ok(list)
+    }
+
     pub fn list_images(&self) -> Result<Vec<PathBuf>, Error> {
         let base = self.base_path();