src/backup/manifest.rs: new class to generate/parse index.json
This commit is contained in:
parent
ad6e5a6f51
commit
59e9ba01c6
@ -103,7 +103,6 @@
|
|||||||
//!
|
//!
|
||||||
//! Not sure if this is better. TODO
|
//! Not sure if this is better. TODO
|
||||||
|
|
||||||
pub const MANIFEST_BLOB_NAME: &str = "index.json.blob";
|
|
||||||
pub const CATALOG_BLOB_NAME: &str = "catalog.blob";
|
pub const CATALOG_BLOB_NAME: &str = "catalog.blob";
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
@ -119,6 +118,9 @@ macro_rules! PROXMOX_BACKUP_READER_PROTOCOL_ID_V1 {
|
|||||||
mod file_formats;
|
mod file_formats;
|
||||||
pub use file_formats::*;
|
pub use file_formats::*;
|
||||||
|
|
||||||
|
mod manifest;
|
||||||
|
pub use manifest::*;
|
||||||
|
|
||||||
mod crypt_config;
|
mod crypt_config;
|
||||||
pub use crypt_config::*;
|
pub use crypt_config::*;
|
||||||
|
|
||||||
|
65
src/backup/manifest.rs
Normal file
65
src/backup/manifest.rs
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
use failure::*;
|
||||||
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
|
use serde_json::{json, Value};
|
||||||
|
|
||||||
|
use crate::backup::BackupDir;
|
||||||
|
|
||||||
|
pub const MANIFEST_BLOB_NAME: &str = "index.json.blob";
|
||||||
|
|
||||||
|
struct FileInfo {
|
||||||
|
filename: String,
|
||||||
|
size: u64,
|
||||||
|
csum: [u8; 32],
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct BackupManifest {
|
||||||
|
snapshot: BackupDir,
|
||||||
|
files: Vec<FileInfo>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BackupManifest {
|
||||||
|
|
||||||
|
pub fn new(snapshot: BackupDir) -> Self {
|
||||||
|
Self { files: Vec::new(), snapshot }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_file(&mut self, filename: String, size: u64, csum: [u8; 32]) {
|
||||||
|
self.files.push(FileInfo { filename, size, csum });
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_json(self) -> Value {
|
||||||
|
json!({
|
||||||
|
"backup-type": self.snapshot.group().backup_type(),
|
||||||
|
"backup-id": self.snapshot.group().backup_id(),
|
||||||
|
"backup-time": self.snapshot.backup_time().timestamp(),
|
||||||
|
"files": self.files.iter()
|
||||||
|
.fold(Vec::new(), |mut acc, info| {
|
||||||
|
acc.push(json!({
|
||||||
|
"filename": info.filename,
|
||||||
|
"size": info.size,
|
||||||
|
"csum": proxmox::tools::digest_to_hex(&info.csum),
|
||||||
|
}));
|
||||||
|
acc
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<Value> for BackupManifest {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn try_from(data: Value) -> Result<Self, Error> {
|
||||||
|
|
||||||
|
let backup_type = data["backup_type"].as_str().unwrap();
|
||||||
|
let backup_id = data["backup_id"].as_str().unwrap();
|
||||||
|
let backup_time = data["backup_time"].as_i64().unwrap();
|
||||||
|
|
||||||
|
let snapshot = BackupDir::new(backup_type, backup_id, backup_time);
|
||||||
|
|
||||||
|
let files = Vec::new();
|
||||||
|
|
||||||
|
Ok(Self { files, snapshot })
|
||||||
|
}
|
||||||
|
}
|
@ -732,7 +732,8 @@ fn create_backup(
|
|||||||
verbose,
|
verbose,
|
||||||
).await?;
|
).await?;
|
||||||
|
|
||||||
let mut file_list = vec![];
|
let snapshot = BackupDir::new(backup_type, backup_id, backup_time.timestamp());
|
||||||
|
let mut manifest = BackupManifest::new(snapshot);
|
||||||
|
|
||||||
// fixme: encrypt/sign catalog?
|
// fixme: encrypt/sign catalog?
|
||||||
let catalog_file = std::fs::OpenOptions::new()
|
let catalog_file = std::fs::OpenOptions::new()
|
||||||
@ -751,14 +752,14 @@ fn create_backup(
|
|||||||
let stats = client
|
let stats = client
|
||||||
.upload_blob_from_file(&filename, &target, crypt_config.clone(), true)
|
.upload_blob_from_file(&filename, &target, crypt_config.clone(), true)
|
||||||
.await?;
|
.await?;
|
||||||
file_list.push((target, stats));
|
manifest.add_file(target, stats.size, stats.csum);
|
||||||
}
|
}
|
||||||
BackupType::LOGFILE => { // fixme: remove - not needed anymore ?
|
BackupType::LOGFILE => { // fixme: remove - not needed anymore ?
|
||||||
println!("Upload log file '{}' to '{:?}' as {}", filename, repo, target);
|
println!("Upload log file '{}' to '{:?}' as {}", filename, repo, target);
|
||||||
let stats = client
|
let stats = client
|
||||||
.upload_blob_from_file(&filename, &target, crypt_config.clone(), true)
|
.upload_blob_from_file(&filename, &target, crypt_config.clone(), true)
|
||||||
.await?;
|
.await?;
|
||||||
file_list.push((target, stats));
|
manifest.add_file(target, stats.size, stats.csum);
|
||||||
}
|
}
|
||||||
BackupType::PXAR => {
|
BackupType::PXAR => {
|
||||||
upload_catalog = true;
|
upload_catalog = true;
|
||||||
@ -775,7 +776,7 @@ fn create_backup(
|
|||||||
crypt_config.clone(),
|
crypt_config.clone(),
|
||||||
catalog.clone(),
|
catalog.clone(),
|
||||||
).await?;
|
).await?;
|
||||||
file_list.push((target, stats));
|
manifest.add_file(target, stats.size, stats.csum);
|
||||||
catalog.lock().unwrap().end_directory()?;
|
catalog.lock().unwrap().end_directory()?;
|
||||||
}
|
}
|
||||||
BackupType::IMAGE => {
|
BackupType::IMAGE => {
|
||||||
@ -789,7 +790,7 @@ fn create_backup(
|
|||||||
verbose,
|
verbose,
|
||||||
crypt_config.clone(),
|
crypt_config.clone(),
|
||||||
).await?;
|
).await?;
|
||||||
file_list.push((target, stats));
|
manifest.add_file(target, stats.size, stats.csum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -805,7 +806,7 @@ fn create_backup(
|
|||||||
catalog_file.seek(SeekFrom::Start(0))?;
|
catalog_file.seek(SeekFrom::Start(0))?;
|
||||||
|
|
||||||
let stats = client.upload_blob(catalog_file, target).await?;
|
let stats = client.upload_blob(catalog_file, target).await?;
|
||||||
file_list.push((target.to_owned(), stats));
|
manifest.add_file(target.to_owned(), stats.size, stats.csum);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(rsa_encrypted_key) = rsa_encrypted_key {
|
if let Some(rsa_encrypted_key) = rsa_encrypted_key {
|
||||||
@ -814,7 +815,7 @@ fn create_backup(
|
|||||||
let stats = client
|
let stats = client
|
||||||
.upload_blob_from_data(rsa_encrypted_key, target, None, false, false)
|
.upload_blob_from_data(rsa_encrypted_key, target, None, false, false)
|
||||||
.await?;
|
.await?;
|
||||||
file_list.push((format!("{}.blob", target), stats));
|
manifest.add_file(format!("{}.blob", target), stats.size, stats.csum);
|
||||||
|
|
||||||
// openssl rsautl -decrypt -inkey master-private.pem -in rsa-encrypted.key -out t
|
// openssl rsautl -decrypt -inkey master-private.pem -in rsa-encrypted.key -out t
|
||||||
/*
|
/*
|
||||||
@ -826,28 +827,13 @@ fn create_backup(
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// create index.json
|
// create manifest (index.json)
|
||||||
let file_list = file_list.iter()
|
let manifest = manifest.into_json();
|
||||||
.fold(vec![], |mut acc, (filename, stats)| {
|
|
||||||
acc.push(json!({
|
|
||||||
"filename": filename,
|
|
||||||
"size": stats.size,
|
|
||||||
"csum": proxmox::tools::digest_to_hex(&stats.csum),
|
|
||||||
}));
|
|
||||||
acc
|
|
||||||
});
|
|
||||||
|
|
||||||
let index = json!({
|
|
||||||
"backup-type": backup_type,
|
|
||||||
"backup-id": backup_id,
|
|
||||||
"backup-time": backup_time.timestamp(),
|
|
||||||
"files": file_list,
|
|
||||||
});
|
|
||||||
|
|
||||||
println!("Upload index.json to '{:?}'", repo);
|
println!("Upload index.json to '{:?}'", repo);
|
||||||
let index_data = serde_json::to_string_pretty(&index)?.into();
|
let manifest = serde_json::to_string_pretty(&manifest)?.into();
|
||||||
client
|
client
|
||||||
.upload_blob_from_data(index_data, "index.json.blob", crypt_config.clone(), true, true)
|
.upload_blob_from_data(manifest, MANIFEST_BLOB_NAME, crypt_config.clone(), true, true)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
client.finish().await?;
|
client.finish().await?;
|
||||||
|
Loading…
Reference in New Issue
Block a user