backup-client: allow to specify directories (prepare for catar backup)
This commit is contained in:
parent
b62b6cadf4
commit
bcd879cfb3
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -131,7 +131,7 @@ impl <'a> ImageIndexReader<'a> {
|
|||
}
|
||||
|
||||
pub struct ImageIndexWriter<'a> {
|
||||
store: &'a mut ChunkStore,
|
||||
store: &'a ChunkStore,
|
||||
filename: PathBuf,
|
||||
tmp_filename: PathBuf,
|
||||
chunk_size: usize,
|
||||
|
@ -153,7 +153,7 @@ impl <'a> Drop for 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 mut tmp_path = full_path.clone();
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
||||
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(¶m, "filename");
|
||||
let store = required_string_param(¶m, "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 file = std::fs::File::open(filename)?;
|
||||
let stat = nix::sys::stat::fstat(file.as_raw_fd())?;
|
||||
|
||||
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");
|
||||
}
|
||||
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);
|
||||
|
||||
{
|
||||
let file = std::fs::File::open(filename)?;
|
||||
let stat = nix::sys::stat::fstat(file.as_raw_fd())?;
|
||||
if stat.st_size <= 0 { bail!("got strange file size '{}'", stat.st_size); }
|
||||
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)
|
||||
})?;
|
||||
let idx = datastore.open_image_reader(target)?;
|
||||
idx.print_info();
|
||||
|
||||
index.close()?; // commit changes
|
||||
} else {
|
||||
bail!("unsupported file type (expected a directory, file or block device)");
|
||||
}
|
||||
|
||||
//datastore.garbage_collection()?;
|
||||
|
||||
let idx = datastore.open_image_reader(target)?;
|
||||
idx.print_info();
|
||||
|
||||
Ok(Value::Null)
|
||||
}
|
||||
|
||||
|
@ -77,9 +111,9 @@ fn main() {
|
|||
|
||||
let cmd_def = CliCommand::new(
|
||||
ApiMethod::new(
|
||||
backup_file,
|
||||
ObjectSchema::new("Create backup from file.")
|
||||
.required("filename", StringSchema::new("Source file name."))
|
||||
create_backup,
|
||||
ObjectSchema::new("Create backup.")
|
||||
.required("filename", StringSchema::new("Source name (file or directory name)"))
|
||||
.required("store", StringSchema::new("Datastore name."))
|
||||
.required("target", StringSchema::new("Target name."))
|
||||
.optional(
|
||||
|
|
Loading…
Reference in New Issue