summaryrefslogtreecommitdiff
path: root/src/cmd
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2020-12-12 10:44:50 +0200
committerLars Wirzenius <liw@liw.fi>2020-12-12 11:58:12 +0200
commit146a5fe13cba442afca954733bafd854f4448928 (patch)
tree1ae24923cc950aedb77772f167045656c2f9249a /src/cmd
parent57b85f1d11c8972cd056a339c29e28ab3b91137c (diff)
downloadobnam2-146a5fe13cba442afca954733bafd854f4448928.tar.gz
feat: back up and restore symlinks
Diffstat (limited to 'src/cmd')
-rw-r--r--src/cmd/backup.rs12
-rw-r--r--src/cmd/restore.rs17
2 files changed, 26 insertions, 3 deletions
diff --git a/src/cmd/backup.rs b/src/cmd/backup.rs
index 8f195eb..86f1b96 100644
--- a/src/cmd/backup.rs
+++ b/src/cmd/backup.rs
@@ -2,6 +2,7 @@ use crate::client::{BackupClient, ClientConfig};
use crate::fsiter::FsIterator;
use crate::generation::Generation;
use indicatif::{ProgressBar, ProgressStyle};
+use log::info;
use std::path::Path;
use tempfile::NamedTempFile;
@@ -24,13 +25,14 @@ 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)?;
- let progress = create_progress_bar(GUESS_FILE_COUNT);
+ let progress = create_progress_bar(GUESS_FILE_COUNT, false);
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) => {
+ info!("backup: {}", entry.path().display());
progress.set_message(&format!("{}", entry.path().display()));
client.upload_filesystem_entry(entry, buffer_size)
}
@@ -52,8 +54,12 @@ 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);
+fn create_progress_bar(file_count: u64, verbose: bool) -> ProgressBar {
+ let progress = if verbose {
+ ProgressBar::new(file_count)
+ } else {
+ ProgressBar::hidden()
+ };
let parts = vec![
"{wide_bar}",
"elapsed: {elapsed}",
diff --git a/src/cmd/restore.rs b/src/cmd/restore.rs
index 2b62ef5..27f0ce3 100644
--- a/src/cmd/restore.rs
+++ b/src/cmd/restore.rs
@@ -8,6 +8,7 @@ use log::{debug, error, info};
use std::fs::File;
use std::io::prelude::*;
use std::io::Error;
+use std::os::unix::fs::symlink;
use std::os::unix::io::AsRawFd;
use std::path::{Path, PathBuf};
use structopt::StructOpt;
@@ -81,6 +82,7 @@ fn restore_generation(
to: &Path,
progress: &ProgressBar,
) -> anyhow::Result<()> {
+ debug!("restoring {:?}", entry);
progress.set_message(&format!("{}", entry.path().display()));
progress.inc(1);
@@ -88,6 +90,7 @@ fn restore_generation(
match entry.kind() {
FilesystemKind::Regular => restore_regular(client, &gen, &to, fileid, &entry)?,
FilesystemKind::Directory => restore_directory(&to)?,
+ FilesystemKind::Symlink => restore_symlink(&to, &entry)?,
}
Ok(())
}
@@ -142,6 +145,20 @@ fn restore_regular(
Ok(())
}
+fn restore_symlink(path: &Path, entry: &FilesystemEntry) -> anyhow::Result<()> {
+ debug!("restoring symlink {}", path.display());
+ let parent = path.parent().unwrap();
+ debug!(" mkdir {}", parent.display());
+ if !parent.exists() {
+ std::fs::create_dir_all(parent)?;
+ {
+ symlink(path, entry.symlink_target().unwrap())?;
+ }
+ }
+ debug!("restored regular {}", path.display());
+ Ok(())
+}
+
fn restore_metadata(path: &Path, entry: &FilesystemEntry) -> anyhow::Result<()> {
debug!("restoring metadata for {}", entry.path().display());