summaryrefslogtreecommitdiff
path: root/src/cmd
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2020-11-23 07:57:57 +0200
committerLars Wirzenius <liw@liw.fi>2020-11-23 09:32:50 +0200
commiteeabe321112af8fcef1b4c1be7728684f9a7a9aa (patch)
tree0722e5c3aeaac36987227bf5ee99c6a1e288cdeb /src/cmd
parent7194cdfb105b1b835dc2a4ff3bbfc1823f170243 (diff)
downloadobnam2-eeabe321112af8fcef1b4c1be7728684f9a7a9aa.tar.gz
feat: progress reporting to backups and restores
Diffstat (limited to 'src/cmd')
-rw-r--r--src/cmd/backup.rs33
-rw-r--r--src/cmd/restore.rs23
2 files changed, 51 insertions, 5 deletions
diff --git a/src/cmd/backup.rs b/src/cmd/backup.rs
index 926b2b1..8f195eb 100644
--- a/src/cmd/backup.rs
+++ b/src/cmd/backup.rs
@@ -1,9 +1,12 @@
use crate::client::{BackupClient, ClientConfig};
use crate::fsiter::FsIterator;
use crate::generation::Generation;
+use indicatif::{ProgressBar, ProgressStyle};
use std::path::Path;
use tempfile::NamedTempFile;
+const GUESS_FILE_COUNT: u64 = 0;
+
pub fn backup(config: &Path, buffer_size: usize) -> anyhow::Result<()> {
let config = ClientConfig::read_config(config)?;
let client = BackupClient::new(&config.server_url)?;
@@ -21,10 +24,21 @@ pub fn backup(config: &Path, buffer_size: usize) -> anyhow::Result<()> {
// The fetching is in its own block so that the file handles
// get closed and data flushed to disk.
let mut gen = Generation::create(&dbname)?;
- gen.insert_iter(FsIterator::new(&config.root).map(|entry| match entry {
- Err(err) => Err(err),
- Ok(entry) => client.upload_filesystem_entry(entry, buffer_size),
+ let progress = create_progress_bar(GUESS_FILE_COUNT);
+ progress.enable_steady_tick(100);
+ gen.insert_iter(FsIterator::new(&config.root).map(|entry| {
+ progress.inc(1);
+ match entry {
+ Err(err) => Err(err),
+ Ok(entry) => {
+ progress.set_message(&format!("{}", entry.path().display()));
+ client.upload_filesystem_entry(entry, buffer_size)
+ }
+ }
}))?;
+ progress.set_length(gen.file_count());
+ progress.finish();
+ println!("file count: {}", gen.file_count());
}
// Upload the SQLite file, i.e., the named temporary file, which
@@ -37,3 +51,16 @@ pub fn backup(config: &Path, buffer_size: usize) -> anyhow::Result<()> {
Ok(())
}
+
+fn create_progress_bar(file_count: u64) -> ProgressBar {
+ let progress = ProgressBar::new(file_count);
+ let parts = vec![
+ "{wide_bar}",
+ "elapsed: {elapsed}",
+ "files: {pos}/{len}",
+ "current: {wide_msg}",
+ "{spinner}",
+ ];
+ progress.set_style(ProgressStyle::default_bar().template(&parts.join("\n")));
+ progress
+}
diff --git a/src/cmd/restore.rs b/src/cmd/restore.rs
index 0051d20..f2724c9 100644
--- a/src/cmd/restore.rs
+++ b/src/cmd/restore.rs
@@ -2,6 +2,7 @@ use crate::client::BackupClient;
use crate::client::ClientConfig;
use crate::fsentry::{FilesystemEntry, FilesystemKind};
use crate::generation::Generation;
+use indicatif::{ProgressBar, ProgressStyle};
use log::{debug, info};
use std::fs::File;
use std::io::prelude::*;
@@ -35,9 +36,12 @@ pub fn restore(config: &Path, gen_id: &str, to: &Path) -> anyhow::Result<()> {
info!("downloaded generation to {}", dbname.display());
let gen = Generation::open(&dbname)?;
+ println!("file count: {}", gen.file_count());
+ let progress = create_progress_bar(gen.file_count());
for (fileid, entry) in gen.files()? {
- restore_generation(&client, &gen, fileid, entry, &to)?;
+ restore_generation(&client, &gen, fileid, entry, &to, &progress)?;
}
+ progress.finish();
// Delete the temporary file.
std::fs::remove_file(&dbname)?;
@@ -67,8 +71,10 @@ fn restore_generation(
fileid: u64,
entry: FilesystemEntry,
to: &Path,
+ progress: &ProgressBar,
) -> anyhow::Result<()> {
- println!("restoring {}:{}", fileid, entry.path().display());
+ progress.set_message(&format!("{}", entry.path().display()));
+ progress.inc(1);
let path = if entry.path().is_absolute() {
entry.path().strip_prefix("/")?
@@ -112,3 +118,16 @@ fn restore_regular(
debug!("restored regular {}", path.display());
Ok(())
}
+
+fn create_progress_bar(file_count: u64) -> ProgressBar {
+ let progress = ProgressBar::new(file_count);
+ let parts = vec![
+ "{wide_bar}",
+ "elapsed: {elapsed}",
+ "files: {pos}/{len}",
+ "current: {wide_msg}",
+ "{spinner}",
+ ];
+ progress.set_style(ProgressStyle::default_bar().template(&parts.join("\n")));
+ progress
+}