From 0227e9c02dd955e549e77b1078d33291594b8416 Mon Sep 17 00:00:00 2001 From: Alexander Weiss Date: Tue, 8 Aug 2023 22:43:28 +0200 Subject: [PATCH] backup: add --init option --- changelog/new.txt | 3 ++- config/full.toml | 2 ++ src/commands/backup.rs | 37 ++++++++++++++++++++++++++++++++++--- src/commands/init.rs | 12 ++++++------ 4 files changed, 44 insertions(+), 10 deletions(-) diff --git a/changelog/new.txt b/changelog/new.txt index 144065c8d..36a608302 100644 --- a/changelog/new.txt +++ b/changelog/new.txt @@ -20,4 +20,5 @@ New features: - Creation of new keys now enforces confirmation of entered key. This helps to prevent mistype of passwords during the initial entry - Check: Add check if time is set for packs-to-delete - ls: Options --long (-l) and --summary (-s) have been added. -- forget: Option --json has been added. \ No newline at end of file +- forget: Option --json has been added. +- backup: New option --init to initialize repository if it doesn't exist yet. diff --git a/config/full.toml b/config/full.toml index bd787ace5..d8b3504f3 100644 --- a/config/full.toml +++ b/config/full.toml @@ -74,6 +74,7 @@ exclude-if-present = [".nobackup", "CACHEDIR.TAG"] # Default: not set one-file-system = false exclude-larger-than = "100MB" # Default: not set json = false +init = false # Backup options for specific sources - all above options are also available here and replace them for the given source [[backup.sources]] @@ -104,6 +105,7 @@ exclude-if-present = [".nobackup", "CACHEDIR.TAG"] # Default: not set one-file-system = false exclude-larger-than = "100MB" # Default: not set json = false +init = false [[backup.sources]] source = "/path/to/source2 /second/path" # multiple local paths are allowd within one source diff --git a/src/commands/backup.rs b/src/commands/backup.rs index 40348857b..333b9b1a7 100644 --- a/src/commands/backup.rs +++ b/src/commands/backup.rs @@ -17,10 +17,12 @@ use merge::Merge; use serde::Deserialize; use rustic_core::{ - BackupOptions, LocalSourceFilterOptions, LocalSourceSaveOptions, ParentOptions, PathList, - SnapshotOptions, + BackupOptions, ConfigOptions, KeyOptions, LocalSourceFilterOptions, LocalSourceSaveOptions, + ParentOptions, PathList, Repository, SnapshotOptions, }; +use super::init::init; + /// `backup` subcommand #[derive(Clone, Command, Default, Debug, clap::Parser, Deserialize, Merge)] #[serde(default, rename_all = "kebab-case", deny_unknown_fields)] @@ -56,6 +58,11 @@ pub struct BackupCmd { #[merge(strategy = merge::bool::overwrite_false)] json: bool, + /// Initialize repository, if it doesn't exist yet + #[clap(long)] + #[merge(strategy = merge::bool::overwrite_false)] + init: bool, + #[clap(flatten, next_help_heading = "Options for parent processing")] #[serde(flatten)] parent_opts: ParentOptions, @@ -68,6 +75,16 @@ pub struct BackupCmd { #[serde(flatten)] snap_opts: SnapshotOptions, + #[clap(flatten, next_help_heading = "Key options (when using --init)")] + #[serde(skip)] + #[merge(skip)] + key_opts: KeyOptions, + + #[clap(flatten, next_help_heading = "Config options (when using --init)")] + #[serde(skip)] + #[merge(skip)] + config_opts: ConfigOptions, + #[clap(skip)] #[merge(strategy = merge_sources)] sources: Vec, @@ -98,7 +115,21 @@ impl BackupCmd { fn inner_run(&self) -> Result<()> { let config = RUSTIC_APP.config(); - let repo = open_repository(&config)?.to_indexed_ids()?; + let po = config.global.progress_options; + let repo = Repository::new_with_progress(&config.repository, po)?; + // Initialize repository if --init is set and it is not yet initialized + let repo = if self.init && repo.config_id()?.is_none() { + if config.global.dry_run { + bail!( + "cannot initialize repository {} in dry-run mode!", + repo.name + ); + } + init(repo, &self.key_opts, &self.config_opts)? + } else { + open_repository(&config)? + } + .to_indexed_ids()?; // manually check for a "source" field, check is not done by serde, see above. if !config.backup.source.is_empty() { diff --git a/src/commands/init.rs b/src/commands/init.rs index d0f331ed2..6a42b8275 100644 --- a/src/commands/init.rs +++ b/src/commands/init.rs @@ -9,7 +9,7 @@ use crate::{Application, RUSTIC_APP}; use dialoguer::Password; -use rustic_core::{ConfigOptions, KeyOptions, Repository}; +use rustic_core::{ConfigOptions, KeyOptions, OpenStatus, Repository}; /// `init` subcommand #[derive(clap::Parser, Command, Debug)] @@ -42,7 +42,9 @@ impl InitCmd { if repo.config_id()?.is_some() { bail!("Config file already exists. Aborting."); } - init(repo, &self.key_opts, &self.config_opts) + + let _ = init(repo, &self.key_opts, &self.config_opts)?; + Ok(()) } } @@ -50,7 +52,7 @@ pub(crate) fn init( repo: Repository, key_opts: &KeyOptions, config_opts: &ConfigOptions, -) -> Result<()> { +) -> Result> { let pass = repo.password()?.unwrap_or_else(|| { match Password::new() .with_prompt("enter password for new key") @@ -66,7 +68,5 @@ pub(crate) fn init( } }); - let _ = repo.init_with_password(&pass, key_opts, config_opts)?; - - Ok(()) + Ok(repo.init_with_password(&pass, key_opts, config_opts)?) }