From b68a29f24c7bea2b2e11d17dbd150342bad04d9c Mon Sep 17 00:00:00 2001 From: Alexander Weiss Date: Sun, 25 Feb 2024 11:18:46 +0100 Subject: [PATCH 1/2] feat(commands): Add --check-index option --- config/README.md | 1 + config/full.toml | 1 + src/commands.rs | 22 ++++++++++++++++++++-- src/commands/cat.rs | 37 ++++++++++++++++++++++--------------- src/commands/copy.rs | 4 ++-- src/commands/diff.rs | 4 ++-- src/commands/dump.rs | 5 +++-- src/commands/ls.rs | 4 ++-- src/commands/restore.rs | 5 +++-- src/commands/webdav.rs | 4 ++-- src/config.rs | 5 +++++ 11 files changed, 63 insertions(+), 29 deletions(-) diff --git a/config/README.md b/config/README.md index d5a797e69..87358cb26 100644 --- a/config/README.md +++ b/config/README.md @@ -57,6 +57,7 @@ If you want to contribute your own configuration, please | Attribute | Description | Default Value | Example Value | Environment Variable | | ----------------- | --------------------------------------------------------------------------------- | ------------- | ----------------- | ------------------------ | +| check-index | If true, check the index and read pack headers if index information is missing. | false | | RUSTIC_CHECK_INDEX | | dry-run | If true, performs a dry run without making any changes. | false | | RUSTIC_DRY_RUN | | log-level | Logging level. Possible values: "off", "error", "warn", "info", "debug", "trace". | "info" | | RUSTIC_LOG_LEVEL | | log-file | Path to the log file. | No log file | "/log/rustic.log" | RUSTIC_LOG_FILE | diff --git a/config/full.toml b/config/full.toml index cc84108e3..910ae8fa6 100644 --- a/config/full.toml +++ b/config/full.toml @@ -14,6 +14,7 @@ log-file = "/path/to/rustic.log" # Default: not set no-progress = false progress-interval = "100ms" dry-run = false +check-index = false # Global env variables: These are set by rustic before calling a subcommand, e.g. rclone or commands # defined in the repository options. diff --git a/src/commands.rs b/src/commands.rs index 2672f7a51..6e6bab96e 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -25,6 +25,7 @@ pub(crate) mod tag; #[cfg(feature = "webdav")] pub(crate) mod webdav; +use std::fmt::Debug; use std::fs::File; use std::path::PathBuf; use std::str::FromStr; @@ -55,8 +56,8 @@ use clap::builder::{ use convert_case::{Case, Casing}; use dialoguer::Password; use human_panic::setup_panic; -use log::{log, Level}; -use rustic_core::{OpenStatus, Repository}; +use log::{log, warn, Level}; +use rustic_core::{IndexedFull, OpenStatus, Repository}; use simplelog::{CombinedLogger, LevelFilter, TermLogger, TerminalMode, WriteLogger}; pub(super) mod constants { @@ -301,6 +302,9 @@ fn get_repository(repo_opts: &AllRepositoryOptions) -> Result Result> { + if RUSTIC_APP.config().global.check_index { + warn!("Option check-index is not supported and will be ignored!"); + } let repo = get_repository(repo_opts)?; match repo.password()? { // if password is given, directly return the result of find_key_in_backend and don't retry @@ -324,6 +328,20 @@ fn open_repository( Err(anyhow!("incorrect password")) } +/// helper function to get an opened and inedexed repo +fn open_repository_indexed( + repo_opts: &AllRepositoryOptions, +) -> Result> { + let open = open_repository(repo_opts)?; + let check_index = RUSTIC_APP.config().global.check_index; + let repo = if check_index { + open.to_indexed_checked() + } else { + open.to_indexed() + }?; + Ok(repo) +} + #[cfg(test)] mod tests { use crate::commands::EntryPoint; diff --git a/src/commands/cat.rs b/src/commands/cat.rs index c7176cae4..46de46a8e 100644 --- a/src/commands/cat.rs +++ b/src/commands/cat.rs @@ -1,6 +1,9 @@ //! `cat` subcommand -use crate::{commands::open_repository, status_err, Application, RUSTIC_APP}; +use crate::{ + commands::{open_repository, open_repository_indexed}, + status_err, Application, RUSTIC_APP, +}; use abscissa_core::{Command, Runnable, Shutdown}; @@ -59,20 +62,24 @@ impl Runnable for CatCmd { impl CatCmd { fn inner_run(&self) -> Result<()> { let config = RUSTIC_APP.config(); - let repo = open_repository(&config.repository)?; - - let data = match &self.cmd { - CatSubCmd::Config => repo.cat_file(FileType::Config, "")?, - CatSubCmd::Index(opt) => repo.cat_file(FileType::Index, &opt.id)?, - CatSubCmd::Snapshot(opt) => repo.cat_file(FileType::Snapshot, &opt.id)?, - // special treatment for 'cat'ing blobs: read the index and use it to locate the blob - CatSubCmd::TreeBlob(opt) => repo.to_indexed()?.cat_blob(BlobType::Tree, &opt.id)?, - CatSubCmd::DataBlob(opt) => repo.to_indexed()?.cat_blob(BlobType::Data, &opt.id)?, - // special treatment for 'cat'ing a tree within a snapshot - CatSubCmd::Tree(opt) => repo - .to_indexed()? - .cat_tree(&opt.snap, |sn| config.snapshot_filter.matches(sn))?, - }; + let data = + match &self.cmd { + CatSubCmd::Config => { + open_repository(&config.repository)?.cat_file(FileType::Config, "")? + } + CatSubCmd::Index(opt) => { + open_repository(&config.repository)?.cat_file(FileType::Index, &opt.id)? + } + CatSubCmd::Snapshot(opt) => { + open_repository(&config.repository)?.cat_file(FileType::Snapshot, &opt.id)? + } + CatSubCmd::TreeBlob(opt) => open_repository_indexed(&config.repository)? + .cat_blob(BlobType::Tree, &opt.id)?, + CatSubCmd::DataBlob(opt) => open_repository_indexed(&config.repository)? + .cat_blob(BlobType::Data, &opt.id)?, + CatSubCmd::Tree(opt) => open_repository_indexed(&config.repository)? + .cat_tree(&opt.snap, |sn| config.snapshot_filter.matches(sn))?, + }; println!("{}", String::from_utf8(data.to_vec())?); Ok(()) diff --git a/src/commands/copy.rs b/src/commands/copy.rs index 5306a0027..d94c4ce57 100644 --- a/src/commands/copy.rs +++ b/src/commands/copy.rs @@ -1,7 +1,7 @@ //! `copy` subcommand use crate::{ - commands::{get_repository, init::init_password, open_repository}, + commands::{get_repository, init::init_password, open_repository, open_repository_indexed}, config::AllRepositoryOptions, helpers::table_with_titles, status_err, Application, RUSTIC_APP, @@ -56,7 +56,7 @@ impl CopyCmd { RUSTIC_APP.shutdown(Shutdown::Crash); } - let repo = open_repository(&config.repository)?.to_indexed()?; + let repo = open_repository_indexed(&config.repository)?; let mut snapshots = if self.ids.is_empty() { repo.get_matching_snapshots(|sn| config.snapshot_filter.matches(sn))? } else { diff --git a/src/commands/diff.rs b/src/commands/diff.rs index f839fbd3e..4451f2ca8 100644 --- a/src/commands/diff.rs +++ b/src/commands/diff.rs @@ -1,6 +1,6 @@ //! `diff` subcommand -use crate::{commands::open_repository, status_err, Application, RUSTIC_APP}; +use crate::{commands::open_repository_indexed, status_err, Application, RUSTIC_APP}; use abscissa_core::{Command, Runnable, Shutdown}; @@ -50,7 +50,7 @@ impl Runnable for DiffCmd { impl DiffCmd { fn inner_run(&self) -> Result<()> { let config = RUSTIC_APP.config(); - let repo = open_repository(&config.repository)?.to_indexed()?; + let repo = open_repository_indexed(&config.repository)?; let (id1, path1) = arg_to_snap_path(&self.snap1, ""); let (id2, path2) = arg_to_snap_path(&self.snap2, path1); diff --git a/src/commands/dump.rs b/src/commands/dump.rs index ea546d2f1..af204dcb9 100644 --- a/src/commands/dump.rs +++ b/src/commands/dump.rs @@ -1,6 +1,6 @@ //! `dump` subcommand -use crate::{commands::open_repository, status_err, Application, RUSTIC_APP}; +use crate::{commands::open_repository_indexed, status_err, Application, RUSTIC_APP}; use abscissa_core::{Command, Runnable, Shutdown}; use anyhow::Result; @@ -25,7 +25,8 @@ impl Runnable for DumpCmd { impl DumpCmd { fn inner_run(&self) -> Result<()> { let config = RUSTIC_APP.config(); - let repo = open_repository(&config.repository)?.to_indexed()?; + let repo = open_repository_indexed(&config.repository)?; + let node = repo.node_from_snapshot_path(&self.snap, |sn| config.snapshot_filter.matches(sn))?; diff --git a/src/commands/ls.rs b/src/commands/ls.rs index 37eb4bbfa..ff8d7e30c 100644 --- a/src/commands/ls.rs +++ b/src/commands/ls.rs @@ -2,7 +2,7 @@ use std::path::Path; -use crate::{commands::open_repository, status_err, Application, RUSTIC_APP}; +use crate::{commands::open_repository_indexed, status_err, Application, RUSTIC_APP}; use abscissa_core::{Command, Runnable, Shutdown}; use anyhow::Result; @@ -91,7 +91,7 @@ impl Summary { impl LsCmd { fn inner_run(&self) -> Result<()> { let config = RUSTIC_APP.config(); - let repo = open_repository(&config.repository)?.to_indexed()?; + let repo = open_repository_indexed(&config.repository)?; let node = repo.node_from_snapshot_path(&self.snap, |sn| config.snapshot_filter.matches(sn))?; diff --git a/src/commands/restore.rs b/src/commands/restore.rs index 56959d914..395117b9d 100644 --- a/src/commands/restore.rs +++ b/src/commands/restore.rs @@ -1,7 +1,8 @@ //! `restore` subcommand use crate::{ - commands::open_repository, helpers::bytes_size_to_string, status_err, Application, RUSTIC_APP, + commands::open_repository_indexed, helpers::bytes_size_to_string, status_err, Application, + RUSTIC_APP, }; use abscissa_core::{Command, Runnable, Shutdown}; @@ -52,7 +53,7 @@ impl RestoreCmd { fn inner_run(&self) -> Result<()> { let config = RUSTIC_APP.config(); let dry_run = config.global.dry_run; - let repo = open_repository(&config.repository)?.to_indexed()?; + let repo = open_repository_indexed(&config.repository)?; let node = repo.node_from_snapshot_path(&self.snap, |sn| config.snapshot_filter.matches(sn))?; diff --git a/src/commands/webdav.rs b/src/commands/webdav.rs index 4e3f548a0..b00f5c274 100644 --- a/src/commands/webdav.rs +++ b/src/commands/webdav.rs @@ -1,7 +1,7 @@ //! `webdav` subcommand use std::{net::ToSocketAddrs, str::FromStr}; -use crate::{commands::open_repository, status_err, Application, RusticConfig, RUSTIC_APP}; +use crate::{commands::open_repository_indexed, status_err, Application, RusticConfig, RUSTIC_APP}; use abscissa_core::{config::Override, Command, FrameworkError, Runnable, Shutdown}; use anyhow::{anyhow, Result}; use dav_server::{warp::dav_handler, DavHandler}; @@ -64,7 +64,7 @@ impl Runnable for WebDavCmd { impl WebDavCmd { fn inner_run(&self) -> Result<()> { let config = RUSTIC_APP.config(); - let repo = open_repository(&config.repository)?.to_indexed()?; + let repo = open_repository_indexed(&config.repository)?; let path_template = self .path_template diff --git a/src/config.rs b/src/config.rs index 3a6d3757c..d8c8decc1 100644 --- a/src/config.rs +++ b/src/config.rs @@ -146,6 +146,11 @@ pub struct GlobalOptions { #[merge(strategy = merge::bool::overwrite_false)] pub dry_run: bool, + /// Check if index matches pack files and read pack headers if neccessary + #[clap(long, global = true, env = "RUSTIC_CHECK_INDEX")] + #[merge(strategy = merge::bool::overwrite_false)] + pub check_index: bool, + /// Use this log level [default: info] #[clap(long, global = true, env = "RUSTIC_LOG_LEVEL")] pub log_level: Option, From 02bcbb4e53bae926f483c7394a9ba4c053cf8729 Mon Sep 17 00:00:00 2001 From: Alexander Weiss Date: Mon, 15 Apr 2024 10:26:45 +0200 Subject: [PATCH 2/2] test fixture --- tests/show-config-fixtures/empty.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/show-config-fixtures/empty.txt b/tests/show-config-fixtures/empty.txt index 460575cbc..57a5f1921 100644 --- a/tests/show-config-fixtures/empty.txt +++ b/tests/show-config-fixtures/empty.txt @@ -1,6 +1,7 @@ [global] use-profile = [] dry-run = false +check-index = false no-progress = false [global.env]