summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2021-03-12 12:31:49 +0200
committerLars Wirzenius <liw@liw.fi>2021-03-12 12:32:47 +0200
commit989b50a633ad285b86c3549ea9ac6f62c0a13273 (patch)
treefdc9a7ebf3c689ec4377f4dc237dbea8a46a3355
parent0fcb8f314a054e4c92e49461f1ae2d9392756638 (diff)
downloadobnam2-989b50a633ad285b86c3549ea9ac6f62c0a13273.tar.gz
feat: handle files in directories that can be read but not executed
-rw-r--r--obnam.md19
-rw-r--r--src/error.rs3
-rw-r--r--src/fsiter.rs12
3 files changed, 26 insertions, 8 deletions
diff --git a/obnam.md b/obnam.md
index cffd83a..15cddb2 100644
--- a/obnam.md
+++ b/obnam.md
@@ -1449,6 +1449,25 @@ then file live/unreadable is restored to rest
then file live/unreadable/data.dat is not restored to rest
~~~
+## Unexecutable directory
+
+This scenario verifies that Obnam will skip a file in a directory it
+can't read. Obnam should warn about that, but not give an error.
+
+~~~scenario
+given an installed obnam
+and a running chunk server
+and a client config based on smoke.yaml
+and a file live/dir/data.dat containing some random data
+and file live/dir has mode 600
+when I run obnam --config smoke.yaml backup
+then stdout contains "live/dir"
+then backup generation is GEN
+when I invoke obnam --config smoke.yaml restore <GEN> rest
+then file live/dir is restored to rest
+then file live/dir/data.dat is not restored to rest
+~~~
+
## Restore latest generation
This scenario verifies that the latest backup generation can be
diff --git a/src/error.rs b/src/error.rs
index 73d4a66..a905458 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -5,11 +5,10 @@ use crate::generation::{LocalGenerationError, NascentError};
use crate::genlist::GenerationListError;
use std::time::SystemTimeError;
use tempfile::PersistError;
-use thiserror::Error;
/// Define all the kinds of errors that functions corresponding to
/// subcommands of the main program can return.
-#[derive(Debug, Error)]
+#[derive(Debug, thiserror::Error)]
pub enum ObnamError {
#[error(transparent)]
GenerationListError(#[from] GenerationListError),
diff --git a/src/fsiter.rs b/src/fsiter.rs
index 57b6fd5..b778cf3 100644
--- a/src/fsiter.rs
+++ b/src/fsiter.rs
@@ -1,6 +1,6 @@
use crate::fsentry::{FilesystemEntry, FsEntryError};
-use log::{debug, error};
-use std::path::Path;
+use log::{debug, warn};
+use std::path::{Path, PathBuf};
use walkdir::{DirEntry, IntoIter, WalkDir};
/// Iterator over file system entries in a directory tree.
@@ -13,8 +13,8 @@ pub enum FsIterError {
#[error(transparent)]
WalkError(#[from] walkdir::Error),
- #[error(transparent)]
- IoError(#[from] std::io::Error),
+ #[error("I/O error on {0}: {1}")]
+ IoError(PathBuf, #[source] std::io::Error),
#[error(transparent)]
FsEntryError(#[from] FsEntryError),
@@ -50,8 +50,8 @@ fn new_entry(e: &DirEntry) -> FsIterResult<FilesystemEntry> {
let meta = match meta {
Ok(meta) => meta,
Err(err) => {
- error!("failed to get metadata: {}", err);
- return Err(err.into());
+ warn!("failed to get metadata for {}: {}", path.display(), err);
+ return Err(FsIterError::IoError(path.to_path_buf(), err));
}
};
let entry = FilesystemEntry::from_metadata(path, &meta)?;