summaryrefslogtreecommitdiff
path: root/src/backup_run.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/backup_run.rs')
-rw-r--r--src/backup_run.rs92
1 files changed, 92 insertions, 0 deletions
diff --git a/src/backup_run.rs b/src/backup_run.rs
new file mode 100644
index 0000000..e3bfc5a
--- /dev/null
+++ b/src/backup_run.rs
@@ -0,0 +1,92 @@
+use crate::backup_progress::BackupProgress;
+use crate::backup_reason::Reason;
+use crate::chunkid::ChunkId;
+use crate::client::{BackupClient, ClientConfig};
+use crate::fsentry::FilesystemEntry;
+use crate::generation::LocalGeneration;
+use crate::policy::BackupPolicy;
+use log::{info, warn};
+
+pub struct BackupRun {
+ client: BackupClient,
+ policy: BackupPolicy,
+ buffer_size: usize,
+ progress: BackupProgress,
+}
+
+impl BackupRun {
+ pub fn new(config: &ClientConfig, buffer_size: usize) -> anyhow::Result<Self> {
+ let client = BackupClient::new(&config.server_url)?;
+ let policy = BackupPolicy::new();
+ let progress = BackupProgress::new();
+ Ok(Self {
+ client,
+ policy,
+ buffer_size,
+ progress,
+ })
+ }
+
+ pub fn client(&self) -> &BackupClient {
+ &self.client
+ }
+
+ pub fn progress(&self) -> &BackupProgress {
+ &self.progress
+ }
+
+ pub fn backup_file_initially(
+ &self,
+ entry: anyhow::Result<FilesystemEntry>,
+ ) -> anyhow::Result<(FilesystemEntry, Vec<ChunkId>, Reason)> {
+ match entry {
+ Err(err) => Err(err.into()),
+ Ok(entry) => {
+ let path = &entry.pathbuf();
+ info!("backup: {}", path.display());
+ self.progress.found_live_file(path);
+ let ids = self
+ .client
+ .upload_filesystem_entry(&entry, self.buffer_size)?;
+ Ok((entry.clone(), ids, Reason::IsNew))
+ }
+ }
+ }
+
+ pub fn backup_file_incrementally(
+ &self,
+ entry: anyhow::Result<FilesystemEntry>,
+ old: &LocalGeneration,
+ ) -> anyhow::Result<(FilesystemEntry, Vec<ChunkId>, Reason)> {
+ match entry {
+ Err(err) => {
+ warn!("backup: {}", err);
+ self.progress.found_problem();
+ Err(err)
+ }
+ Ok(entry) => {
+ let path = &entry.pathbuf();
+ info!("backup: {}", path.display());
+ self.progress.found_live_file(path);
+ let reason = self.policy.needs_backup(&old, &entry);
+ match reason {
+ Reason::IsNew | Reason::Changed | Reason::Error => {
+ let ids = self
+ .client
+ .upload_filesystem_entry(&entry, self.buffer_size)?;
+ Ok((entry.clone(), ids, reason))
+ }
+ Reason::Unchanged | Reason::Skipped => {
+ let fileno = old.get_fileno(&entry.pathbuf())?;
+ let ids = if let Some(fileno) = fileno {
+ old.chunkids(fileno)?
+ } else {
+ vec![]
+ };
+ Ok((entry.clone(), ids, reason))
+ }
+ }
+ }
+ }
+ }
+}