summaryrefslogtreecommitdiff
path: root/src/cmd/backup.rs
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2021-02-06 19:22:10 +0200
committerLars Wirzenius <liw@liw.fi>2021-02-06 20:00:04 +0200
commit7cfa4142bc1859f9084a35e7e7fd5f67d3a655a3 (patch)
tree1eabf91078c2be52b719b78110af1630a3fbf375 /src/cmd/backup.rs
parentaa75f0d5709fb4062900db5ab5b6e2598b6af667 (diff)
downloadobnam2-7cfa4142bc1859f9084a35e7e7fd5f67d3a655a3.tar.gz
feat! back up multiple roots
This changes the client configuration file "root" field (with a single string) to "roots" (a list of strings).
Diffstat (limited to 'src/cmd/backup.rs')
-rw-r--r--src/cmd/backup.rs70
1 files changed, 47 insertions, 23 deletions
diff --git a/src/cmd/backup.rs b/src/cmd/backup.rs
index fd1d876..cb2e9af 100644
--- a/src/cmd/backup.rs
+++ b/src/cmd/backup.rs
@@ -1,9 +1,11 @@
use crate::backup_run::BackupRun;
+use crate::chunkid::ChunkId;
use crate::client::ClientConfig;
use crate::error::ObnamError;
use crate::fsiter::FsIterator;
use crate::generation::NascentGeneration;
use log::info;
+use std::path::{Path, PathBuf};
use std::time::SystemTime;
use tempfile::NamedTempFile;
@@ -31,40 +33,62 @@ pub fn backup(config: &ClientConfig) -> Result<(), ObnamError> {
};
let genlist = run.client().list_generations()?;
- let file_count = {
- let iter = FsIterator::new(&config.root);
- let mut new = NascentGeneration::create(&newname)?;
-
- match genlist.resolve("latest") {
- Err(_) => {
- info!("fresh backup without a previous generation");
- new.insert_iter(iter.map(|entry| run.backup_file_initially(entry)))?;
- }
- Ok(old) => {
- info!("incremental backup based on {}", old);
- let old = run.client().fetch_generation(&old, &oldname)?;
- run.progress()
- .files_in_previous_generation(old.file_count()? as u64);
- new.insert_iter(iter.map(|entry| run.backup_file_incrementally(entry, &old)))?;
- }
- }
- run.progress().finish();
- new.file_count()
+ let file_count = match genlist.resolve("latest") {
+ Err(_) => initial_backup(&config.roots, &newname, &run)?,
+ Ok(old) => incremental_backup(&old, &config.roots, &newname, &oldname, &run)?,
};
+ run.progress().finish();
// Upload the SQLite file, i.e., the named temporary file, which
// still exists, since we persisted it above.
let gen_id = run
.client()
.upload_generation(&newname, SQLITE_CHUNK_SIZE)?;
- println!("status: OK");
- println!("duration: {}", runtime.elapsed()?.as_secs());
- println!("file-count: {}", file_count);
- println!("generation-id: {}", gen_id);
// Delete the temporary file.q
std::fs::remove_file(&newname)?;
std::fs::remove_file(&oldname)?;
+ report_stats(&runtime, file_count, &gen_id)?;
+
Ok(())
}
+
+fn report_stats(runtime: &SystemTime, file_count: i64, gen_id: &ChunkId) -> Result<(), ObnamError> {
+ println!("status: OK");
+ println!("duration: {}", runtime.elapsed()?.as_secs());
+ println!("file-count: {}", file_count);
+ println!("generation-id: {}", gen_id);
+ Ok(())
+}
+
+fn initial_backup(roots: &[PathBuf], newname: &Path, run: &BackupRun) -> Result<i64, ObnamError> {
+ info!("fresh backup without a previous generation");
+
+ let mut new = NascentGeneration::create(&newname)?;
+ for root in roots {
+ let iter = FsIterator::new(root);
+ new.insert_iter(iter.map(|entry| run.backup_file_initially(entry)))?;
+ }
+ Ok(new.file_count())
+}
+
+fn incremental_backup(
+ old: &str,
+ roots: &[PathBuf],
+ newname: &Path,
+ oldname: &Path,
+ run: &BackupRun,
+) -> Result<i64, ObnamError> {
+ info!("incremental backup based on {}", old);
+
+ let old = run.client().fetch_generation(&old, &oldname)?;
+ let mut new = NascentGeneration::create(&newname)?;
+ for root in roots {
+ let iter = FsIterator::new(root);
+ run.progress()
+ .files_in_previous_generation(old.file_count()? as u64);
+ new.insert_iter(iter.map(|entry| run.backup_file_incrementally(entry, &old)))?;
+ }
+ Ok(new.file_count())
+}