backup-client: allow to specify directories (prepare for catar backup)
This commit is contained in:
		@ -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(
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user