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)
|
Ok(index)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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(¶m, "filename");
|
let filename = required_string_param(¶m, "filename");
|
||||||
let store = required_string_param(¶m, "store");
|
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 (stat.st_mode & libc::S_IFDIR) != 0 {
|
||||||
if let Some(ext) = target.extension() {
|
println!("Backup directory '{}' to '{}'", filename, store);
|
||||||
if ext != "iidx" {
|
|
||||||
bail!("got wrong file extension - expected '.iidx'");
|
backup_dir(&datastore, &file, &target, chunk_size)?;
|
||||||
}
|
|
||||||
} else {
|
} else if (stat.st_mode & (libc::S_IFREG|libc::S_IFBLK)) != 0 {
|
||||||
target.set_extension("iidx");
|
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); }
|
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| {
|
let idx = datastore.open_image_reader(target)?;
|
||||||
index.add_chunk(pos, chunk)?;
|
idx.print_info();
|
||||||
Ok(true)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
index.close()?; // commit changes
|
} else {
|
||||||
|
bail!("unsupported file type (expected a directory, file or block device)");
|
||||||
}
|
}
|
||||||
|
|
||||||
//datastore.garbage_collection()?;
|
//datastore.garbage_collection()?;
|
||||||
|
|
||||||
let idx = datastore.open_image_reader(target)?;
|
|
||||||
idx.print_info();
|
|
||||||
|
|
||||||
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(
|
||||||
|
|
Loading…
Reference in New Issue