backup-client: allow to specify directories (prepare for catar backup)

This commit is contained in:
Dietmar Maurer 2018-12-27 10:11:11 +01:00
parent b62b6cadf4
commit bcd879cfb3
3 changed files with 64 additions and 30 deletions

View File

@ -62,9 +62,9 @@ impl DataStore {
}) })
} }
pub fn create_image_writer<P: AsRef<Path>>(&mut self, filename: P, size: usize, chunk_size: usize) -> Result<ImageIndexWriter, Error> { pub fn create_image_writer<P: AsRef<Path>>(&self, filename: P, size: usize, chunk_size: usize) -> Result<ImageIndexWriter, Error> {
let index = ImageIndexWriter::create(&mut self.chunk_store, filename.as_ref(), size, chunk_size)?; let index = ImageIndexWriter::create(&self.chunk_store, filename.as_ref(), size, chunk_size)?;
Ok(index) Ok(index)
} }

View File

@ -131,7 +131,7 @@ impl <'a> ImageIndexReader<'a> {
} }
pub struct ImageIndexWriter<'a> { pub struct ImageIndexWriter<'a> {
store: &'a mut ChunkStore, store: &'a ChunkStore,
filename: PathBuf, filename: PathBuf,
tmp_filename: PathBuf, tmp_filename: PathBuf,
chunk_size: usize, chunk_size: usize,
@ -153,7 +153,7 @@ impl <'a> Drop for ImageIndexWriter<'a> {
impl <'a> ImageIndexWriter<'a> { impl <'a> ImageIndexWriter<'a> {
pub fn create(store: &'a mut ChunkStore, path: &Path, size: usize, chunk_size: usize) -> Result<Self, Error> { pub fn create(store: &'a ChunkStore, path: &Path, size: usize, chunk_size: usize) -> Result<Self, Error> {
let full_path = store.relative_path(path); let full_path = store.relative_path(path);
let mut tmp_path = full_path.clone(); let mut tmp_path = full_path.clone();

View File

@ -17,7 +17,48 @@ fn required_string_param<'a>(param: &'a Value, name: &str) -> &'a str {
param[name].as_str().expect(&format!("missing parameter '{}'", name)) param[name].as_str().expect(&format!("missing parameter '{}'", name))
} }
fn backup_file(param: Value, _info: &ApiMethod) -> Result<Value, Error> { fn backup_dir(datastore: &DataStore, file: &std::fs::File, target: &str, chunk_size: usize) -> Result<(), Error> {
let mut target = std::path::PathBuf::from(target);
if let Some(ext) = target.extension() {
if ext != "aidx" {
bail!("got wrong file extension - expected '.aidx'");
}
} else {
target.set_extension("aidx");
}
bail!("not implemented");
Ok(())
}
fn backup_image(datastore: &DataStore, file: &std::fs::File, size: usize, target: &str, chunk_size: usize) -> Result<(), Error> {
let mut target = std::path::PathBuf::from(target);
if let Some(ext) = target.extension() {
if ext != "iidx" {
bail!("got wrong file extension - expected '.iidx'");
}
} else {
target.set_extension("iidx");
}
let mut index = datastore.create_image_writer(&target, size, chunk_size)?;
tools::file_chunker(file, chunk_size, |pos, chunk| {
index.add_chunk(pos, chunk)?;
Ok(true)
})?;
index.close()?; // commit changes
Ok(())
}
fn create_backup(param: Value, _info: &ApiMethod) -> Result<Value, Error> {
let filename = required_string_param(&param, "filename"); let filename = required_string_param(&param, "filename");
let store = required_string_param(&param, "store"); let store = required_string_param(&param, "store");
@ -35,40 +76,33 @@ fn backup_file(param: Value, _info: &ApiMethod) -> Result<Value, Error> {
} }
} }
let mut datastore = DataStore::open(store)?; let datastore = DataStore::open(store)?;
println!("Backup file '{}' to '{}'", filename, store);
let mut target = std::path::PathBuf::from(target);
if let Some(ext) = target.extension() {
if ext != "iidx" {
bail!("got wrong file extension - expected '.iidx'");
}
} else {
target.set_extension("iidx");
}
{
let file = std::fs::File::open(filename)?; let file = std::fs::File::open(filename)?;
let stat = nix::sys::stat::fstat(file.as_raw_fd())?; let stat = nix::sys::stat::fstat(file.as_raw_fd())?;
if (stat.st_mode & libc::S_IFDIR) != 0 {
println!("Backup directory '{}' to '{}'", filename, store);
backup_dir(&datastore, &file, &target, chunk_size)?;
} else if (stat.st_mode & (libc::S_IFREG|libc::S_IFBLK)) != 0 {
println!("Backup file '{}' to '{}'", filename, store);
if stat.st_size <= 0 { bail!("got strange file size '{}'", stat.st_size); } if stat.st_size <= 0 { bail!("got strange file size '{}'", stat.st_size); }
let size = stat.st_size as usize; let size = stat.st_size as usize;
let mut index = datastore.create_image_writer(&target, size, chunk_size)?; backup_image(&datastore, &file, size, &target, chunk_size)?;
tools::file_chunker(file, chunk_size, |pos, chunk| {
index.add_chunk(pos, chunk)?;
Ok(true)
})?;
index.close()?; // commit changes
}
//datastore.garbage_collection()?;
let idx = datastore.open_image_reader(target)?; let idx = datastore.open_image_reader(target)?;
idx.print_info(); idx.print_info();
} else {
bail!("unsupported file type (expected a directory, file or block device)");
}
//datastore.garbage_collection()?;
Ok(Value::Null) Ok(Value::Null)
} }
@ -77,9 +111,9 @@ fn main() {
let cmd_def = CliCommand::new( let cmd_def = CliCommand::new(
ApiMethod::new( ApiMethod::new(
backup_file, create_backup,
ObjectSchema::new("Create backup from file.") ObjectSchema::new("Create backup.")
.required("filename", StringSchema::new("Source file name.")) .required("filename", StringSchema::new("Source name (file or directory name)"))
.required("store", StringSchema::new("Datastore name.")) .required("store", StringSchema::new("Datastore name."))
.required("target", StringSchema::new("Target name.")) .required("target", StringSchema::new("Target name."))
.optional( .optional(