src/api2/admin/datastore.rs: impl list_backup_groups

This commit is contained in:
Dietmar Maurer 2019-03-02 11:29:05 +01:00
parent 3147e56a74
commit 812c6f8716
2 changed files with 89 additions and 4 deletions

View File

@ -7,6 +7,7 @@ use serde_json::{json, Value};
use std::collections::{HashSet, HashMap}; use std::collections::{HashSet, HashMap};
use chrono::{DateTime, Datelike, Local}; use chrono::{DateTime, Datelike, Local};
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::Arc;
//use hyper::StatusCode; //use hyper::StatusCode;
//use hyper::rt::{Future, Stream}; //use hyper::rt::{Future, Stream};
@ -50,6 +51,39 @@ fn mark_selections<F: Fn(DateTime<Local>, &BackupInfo) -> String> (
} }
} }
fn get_group_list(
param: Value,
_info: &ApiMethod,
_rpcenv: &mut RpcEnvironment,
) -> Result<Value, Error> {
let store = param["store"].as_str().unwrap();
let datastore = DataStore::lookup_datastore(store)?;
let backup_list = datastore.list_backups()?;
let group_hash = group_backups(backup_list);
let mut groups = vec![];
for (_group_id, mut list) in group_hash {
list.sort_unstable_by(|a, b| b.backup_dir.backup_time.cmp(&a.backup_dir.backup_time)); // new backups first
let info = &list[0];
let group = &info.backup_dir.group;
groups.push(json!({
"backup_type": group.backup_type,
"backup_id": group.backup_id,
"last_backup": info.backup_dir.backup_time.timestamp(),
"num_backups": list.len() as u64,
}));
}
Ok(json!(groups))
}
fn prune( fn prune(
param: Value, param: Value,
@ -249,17 +283,22 @@ fn get_datastore_list(
pub fn router() -> Router { pub fn router() -> Router {
let store_schema: Arc<Schema> = Arc::new(
StringSchema::new("Datastore name.").into()
);
let datastore_info = Router::new() let datastore_info = Router::new()
.get(ApiMethod::new( .get(ApiMethod::new(
|_,_,_| Ok(json!([ |_,_,_| Ok(json!([
{"subdir": "backups" }, {"subdir": "backups" },
{"subdir": "catar" }, {"subdir": "catar" },
{"subdir": "gc" }, {"subdir": "gc" },
{"subdir": "groups" },
{"subdir": "status" }, {"subdir": "status" },
{"subdir": "prune" }, {"subdir": "prune" },
])), ])),
ObjectSchema::new("Directory index.") ObjectSchema::new("Directory index.")
.required("store", StringSchema::new("Datastore name."))) .required("store", store_schema.clone()))
) )
.subdir( .subdir(
"backups", "backups",
@ -267,7 +306,7 @@ pub fn router() -> Router {
.get(ApiMethod::new( .get(ApiMethod::new(
get_backup_list, get_backup_list,
ObjectSchema::new("List backups.") ObjectSchema::new("List backups.")
.required("store", StringSchema::new("Datastore name."))))) .required("store", store_schema.clone()))))
.subdir( .subdir(
"catar", "catar",
Router::new() Router::new()
@ -278,6 +317,13 @@ pub fn router() -> Router {
Router::new() Router::new()
.get(api_method_garbage_collection_status()) .get(api_method_garbage_collection_status())
.post(api_method_start_garbage_collection())) .post(api_method_start_garbage_collection()))
.subdir(
"groups",
Router::new()
.get(ApiMethod::new(
get_group_list,
ObjectSchema::new("List backup groups.")
.required("store", store_schema.clone()))))
.subdir( .subdir(
"prune", "prune",
Router::new() Router::new()

View File

@ -135,6 +135,45 @@ fn list_backups(
Ok(Value::Null) Ok(Value::Null)
} }
fn list_backup_groups(
param: Value,
_info: &ApiMethod,
_rpcenv: &mut RpcEnvironment,
) -> Result<Value, Error> {
let repo_url = tools::required_string_param(&param, "repository")?;
let repo = BackupRepository::parse(repo_url)?;
let mut client = HttpClient::new(&repo.host, &repo.user);
let path = format!("api2/json/admin/datastore/{}/groups", repo.store);
let result = client.get(&path)?;
// fixme: implement and use output formatter instead ..
let list = result["data"].as_array().unwrap();
for item in list {
let id = item["backup_id"].as_str().unwrap();
let btype = item["backup_type"].as_str().unwrap();
let epoch = item["last_backup"].as_i64().unwrap();
let last_backup = Local.timestamp(epoch, 0);
let num_backups = item["num_backups"].as_u64().unwrap();
let group = BackupGroup {
backup_type: btype.to_string(),
backup_id: id.to_string(),
};
let path = group.group_path().to_str().unwrap().to_owned();
println!("{} | {} | {}", path, last_backup.format("%c"), num_backups);
}
//Ok(result)
Ok(Value::Null)
}
fn start_garbage_collection( fn start_garbage_collection(
param: Value, param: Value,
_info: &ApiMethod, _info: &ApiMethod,
@ -318,8 +357,8 @@ fn main() {
let list_cmd_def = CliCommand::new( let list_cmd_def = CliCommand::new(
ApiMethod::new( ApiMethod::new(
list_backups, list_backup_groups,
ObjectSchema::new("List backups.") ObjectSchema::new("List backup groups.")
.required("repository", repo_url_schema.clone()) .required("repository", repo_url_schema.clone())
)) ))
.arg_param(vec!["repository"]); .arg_param(vec!["repository"]);