From bc478d5f2cd116987eddae4b083c028b67c54785 Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Mon, 11 Nov 2024 22:12:47 +0100 Subject: [PATCH 1/9] refactor(mount): rename fields for clarity Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- config/full.toml | 4 ++-- src/commands/mount.rs | 12 ++++++------ src/commands/mount/fusefs.rs | 1 - 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/config/full.toml b/config/full.toml index a23e719cf..b710d5aba 100644 --- a/config/full.toml +++ b/config/full.toml @@ -209,7 +209,7 @@ snapshot-path = "latest:/dir" # Default: not set - if not set, generate a virtua [mount] path-template = "[{hostname}]/[{label}]/{time}" # The path template to use for snapshots. {id}, {id_long}, {time}, {username}, {hostname}, {label}, {tags}, {backup_start}, {backup_end} are replaced. [default: "[{hostname}]/[{label}]/{time}"]. Only relevant if no snapshot-path is given. time-template = "%Y-%m-%d_%H-%M-%S" # only relevant if no snapshot-path is given -no-allow-other = true +exclusive = true # don't allow other users to access the mount point file-access = "read" # Default: "forbidden" for hot/cold repos, else "read" -mountpoint = "~/mnt" +mount-point = "~/mnt" snapshot-path = "latest:/dir" # Default: not set - if not set, generate a virtual tree with all snapshots using path-template diff --git a/src/commands/mount.rs b/src/commands/mount.rs index 8f459198a..33511592d 100644 --- a/src/commands/mount.rs +++ b/src/commands/mount.rs @@ -33,7 +33,7 @@ pub struct MountCmd { /// Don't allow other users to access the mount point #[clap(long)] #[merge(strategy=conflate::bool::overwrite_false)] - no_allow_other: bool, + exclusive: bool, /// How to handle access to files. [default: "forbidden" for hot/cold repositories, else "read"] #[clap(long)] @@ -43,7 +43,7 @@ pub struct MountCmd { /// The mount point to use #[clap(value_name = "PATH")] #[merge(strategy=conflate::option::overwrite_none)] - mountpoint: Option, + mount_point: Option, /// Specify directly which snapshot/path to mount #[clap(value_name = "SNAPSHOT[:PATH]")] @@ -80,9 +80,9 @@ impl Runnable for MountCmd { impl MountCmd { fn inner_run(&self, repo: CliIndexedRepo) -> Result<()> { let config = RUSTIC_APP.config(); - let mountpoint = config + let mount_point = config .mount - .mountpoint + .mount_point .as_ref() .ok_or_else(|| anyhow!("please specify a mountpoint"))?; @@ -120,7 +120,7 @@ impl MountCmd { OsStr::new("kernel_cache"), ]; - if !config.mount.no_allow_other { + if !config.mount.exclusive { options.extend_from_slice(&[ OsStr::new("-o"), OsStr::new("allow_other"), @@ -141,7 +141,7 @@ impl MountCmd { )?; let fs = FuseMT::new(FuseFS::new(repo, vfs, file_access), 1); - mount(fs, mountpoint, &options)?; + mount(fs, mount_point, &options)?; Ok(()) } diff --git a/src/commands/mount/fusefs.rs b/src/commands/mount/fusefs.rs index 3fc143dd3..eb2f4d185 100644 --- a/src/commands/mount/fusefs.rs +++ b/src/commands/mount/fusefs.rs @@ -164,7 +164,6 @@ impl FilesystemMT for FuseFS { fh: u64, offset: u64, size: u32, - callback: impl FnOnce(ResultSlice<'_>) -> CallbackResult, ) -> CallbackResult { if let Some(open_file) = self.open_files.read().unwrap().get(&fh) { From 4eaee909a016f2d35017ebec137f111929b22268 Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Tue, 12 Nov 2024 03:14:51 +0100 Subject: [PATCH 2/9] allow users to define own mount options Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- config/full.toml | 3 +++ src/commands/mount.rs | 44 +++++++++++++++++++++++++++++-------------- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/config/full.toml b/config/full.toml index b710d5aba..1ff6f7d89 100644 --- a/config/full.toml +++ b/config/full.toml @@ -213,3 +213,6 @@ exclusive = true # don't allow other users to access the mount point file-access = "read" # Default: "forbidden" for hot/cold repos, else "read" mount-point = "~/mnt" snapshot-path = "latest:/dir" # Default: not set - if not set, generate a virtual tree with all snapshots using path-template +options = [ + "kernel_cache", # Default: ["kernel_cache] +] diff --git a/src/commands/mount.rs b/src/commands/mount.rs index 33511592d..d0dfb716c 100644 --- a/src/commands/mount.rs +++ b/src/commands/mount.rs @@ -49,6 +49,19 @@ pub struct MountCmd { #[clap(value_name = "SNAPSHOT[:PATH]")] #[merge(strategy=conflate::option::overwrite_none)] snapshot_path: Option, + + /// Other options to use for mount + #[clap(skip)] + options: MountOpts, +} + +#[derive(Clone, Debug, Serialize, Deserialize, Merge)] +pub(crate) struct MountOpts(#[merge(strategy = conflate::vec::ignore)] pub(crate) Vec); + +impl Default for MountOpts { + fn default() -> Self { + Self(vec![String::from("kernel_cache")]) + } } impl Override for MountCmd { @@ -91,6 +104,7 @@ impl MountCmd { .path_template .clone() .unwrap_or_else(|| "[{hostname}]/[{label}]/{time}".to_string()); + let time_template = config .mount .time_template @@ -112,21 +126,13 @@ impl MountCmd { )? }; - let name_opt = format!("fsname=rusticfs:{}", repo.config().id); - let mut options = vec![ - OsStr::new("-o"), - OsStr::new(&name_opt), - OsStr::new("-o"), - OsStr::new("kernel_cache"), - ]; + let mut options = self.options.0; + + options.extend_from_slice(&[format!("fsname=rusticfs:{}", repo.config().id)]); if !config.mount.exclusive { - options.extend_from_slice(&[ - OsStr::new("-o"), - OsStr::new("allow_other"), - OsStr::new("-o"), - OsStr::new("default_permissions"), - ]); + options + .extend_from_slice(&["allow_other".to_string(), "default_permissions".to_string()]); } let file_access = config.mount.file_access.as_ref().map_or_else( @@ -141,7 +147,17 @@ impl MountCmd { )?; let fs = FuseMT::new(FuseFS::new(repo, vfs, file_access), 1); - mount(fs, mount_point, &options)?; + + // Sort and deduplicate options + options.sort_unstable(); + options.dedup(); + + // join options into a single comma-delimited string and prepent "-o " + // this should be parsed just fine by fuser, here + // https://github.com/cberner/fuser/blob/9f6ced73a36f1d99846e28be9c5e4903939ee9d5/src/mnt/mount_options.rs#L157 + let options = OsStr::new(&format!("-o {}", options.join(","))); + + mount(fs, mount_point, &[options.as_ref()])?; Ok(()) } From 225d5f3ddb496bee46fbaa87bc3426137fc05c36 Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Tue, 12 Nov 2024 03:29:58 +0100 Subject: [PATCH 3/9] fix(mount): update MountOpts to use append strategy and clone options Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- src/commands/mount.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/commands/mount.rs b/src/commands/mount.rs index d0dfb716c..5530e5de6 100644 --- a/src/commands/mount.rs +++ b/src/commands/mount.rs @@ -56,7 +56,7 @@ pub struct MountCmd { } #[derive(Clone, Debug, Serialize, Deserialize, Merge)] -pub(crate) struct MountOpts(#[merge(strategy = conflate::vec::ignore)] pub(crate) Vec); +pub(crate) struct MountOpts(#[merge(strategy = conflate::vec::append)] pub(crate) Vec); impl Default for MountOpts { fn default() -> Self { @@ -126,7 +126,7 @@ impl MountCmd { )? }; - let mut options = self.options.0; + let mut options = self.options.0.clone(); options.extend_from_slice(&[format!("fsname=rusticfs:{}", repo.config().id)]); @@ -155,9 +155,10 @@ impl MountCmd { // join options into a single comma-delimited string and prepent "-o " // this should be parsed just fine by fuser, here // https://github.com/cberner/fuser/blob/9f6ced73a36f1d99846e28be9c5e4903939ee9d5/src/mnt/mount_options.rs#L157 - let options = OsStr::new(&format!("-o {}", options.join(","))); + let opt_string = format!("-o {}", options.join(",")); + let options = OsStr::new(&opt_string); - mount(fs, mount_point, &[options.as_ref()])?; + mount(fs, mount_point, &[options])?; Ok(()) } From 2df8c23b3f25db6649acc108c7b9d833b0f27436 Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Tue, 19 Nov 2024 20:37:14 +0100 Subject: [PATCH 4/9] chore: update rustic_core to version 0.6.1 and refactor MountCmd options handling Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- src/commands/mount.rs | 54 +++++++++++++++++++++++++------------------ 3 files changed, 35 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 728c74604..d4fa35559 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4259,9 +4259,9 @@ checksum = "fbcebf2228827bc4b61cb54dfd84cf43aacf06ca2dfe4c014b136a0e32b876e2" [[package]] name = "rustic_core" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced8fa06db8411fa55828c4469f8c43f02fa35ad87ab678531da70fd9dfc8f8c" +checksum = "fc1b5cf696737fe234607d2e0dfb7e04a9eb3ae535b3b8090d77555992d097a7" dependencies = [ "aes256ctr_poly1305aes", "binrw", diff --git a/Cargo.toml b/Cargo.toml index 01cb3c7bd..6e9351aea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,7 +48,7 @@ rustdoc-args = ["--document-private-items", "--generate-link-to-definition"] [dependencies] abscissa_core = { version = "0.8.1", default-features = false, features = ["application"] } rustic_backend = { version = "0.5.0", features = ["cli"] } -rustic_core = { version = "0.6.0", features = ["cli"] } +rustic_core = { version = "0.6.1", features = ["cli"] } # allocators jemallocator-global = { version = "0.3.2", optional = true } diff --git a/src/commands/mount.rs b/src/commands/mount.rs index 5530e5de6..4b4fed524 100644 --- a/src/commands/mount.rs +++ b/src/commands/mount.rs @@ -17,7 +17,7 @@ use fuse_mt::{mount, FuseMT}; use rustic_core::vfs::{FilePolicy, IdenticalSnapshot, Latest, Vfs}; use serde::{Deserialize, Serialize}; -#[derive(Clone, Command, Default, Debug, clap::Parser, Serialize, Deserialize, Merge)] +#[derive(Clone, Command, Debug, clap::Parser, Serialize, Deserialize, Merge)] #[serde(default, rename_all = "kebab-case", deny_unknown_fields)] pub struct MountCmd { /// The path template to use for snapshots. {id}, {id_long}, {time}, {username}, {hostname}, {label}, {tags}, {backup_start}, {backup_end} are replaced. [default: "[{hostname}]/[{label}]/{time}"] @@ -31,14 +31,14 @@ pub struct MountCmd { time_template: Option, /// Don't allow other users to access the mount point - #[clap(long)] + #[clap(short, long)] #[merge(strategy=conflate::bool::overwrite_false)] exclusive: bool, /// How to handle access to files. [default: "forbidden" for hot/cold repositories, else "read"] #[clap(long)] #[merge(strategy=conflate::option::overwrite_none)] - file_access: Option, + file_access: Option, /// The mount point to use #[clap(value_name = "PATH")] @@ -51,16 +51,22 @@ pub struct MountCmd { snapshot_path: Option, /// Other options to use for mount - #[clap(skip)] - options: MountOpts, + #[clap(short, long = "option", value_name = "OPTION")] + #[merge(strategy = conflate::vec::overwrite_empty)] + options: Vec, } -#[derive(Clone, Debug, Serialize, Deserialize, Merge)] -pub(crate) struct MountOpts(#[merge(strategy = conflate::vec::append)] pub(crate) Vec); - -impl Default for MountOpts { +impl Default for MountCmd { fn default() -> Self { - Self(vec![String::from("kernel_cache")]) + Self { + path_template: Some(String::from("[{hostname}]/[{label}]/{time}")), + time_template: Some(String::from("%Y-%m-%d_%H-%M-%S")), + exclusive: false, + file_access: None, + mount_point: None, + snapshot_path: None, + options: vec![String::from("kernel_cache")], + } } } @@ -126,39 +132,43 @@ impl MountCmd { )? }; - let mut options = self.options.0.clone(); + let mut mount_options = if config.mount.options.is_empty() { + vec!["kernel_cache".to_string()] + } else { + config.mount.options.clone() + }; - options.extend_from_slice(&[format!("fsname=rusticfs:{}", repo.config().id)]); + mount_options.push(format!("fsname=rusticfs:{}", repo.config().id)); if !config.mount.exclusive { - options + mount_options .extend_from_slice(&["allow_other".to_string(), "default_permissions".to_string()]); } let file_access = config.mount.file_access.as_ref().map_or_else( || { if repo.config().is_hot == Some(true) { - Ok(FilePolicy::Forbidden) + FilePolicy::Forbidden } else { - Ok(FilePolicy::Read) + FilePolicy::Read } }, - |s| s.parse(), - )?; + |s| *s, + ); let fs = FuseMT::new(FuseFS::new(repo, vfs, file_access), 1); // Sort and deduplicate options - options.sort_unstable(); - options.dedup(); + mount_options.sort_unstable(); + mount_options.dedup(); // join options into a single comma-delimited string and prepent "-o " // this should be parsed just fine by fuser, here // https://github.com/cberner/fuser/blob/9f6ced73a36f1d99846e28be9c5e4903939ee9d5/src/mnt/mount_options.rs#L157 - let opt_string = format!("-o {}", options.join(",")); - let options = OsStr::new(&opt_string); + let opt_string = format!("-o {}", mount_options.join(",")); + let mount_options = OsStr::new(&opt_string); - mount(fs, mount_point, &[options])?; + mount(fs, mount_point, &[mount_options])?; Ok(()) } From 04e6efe34a5c4f30d46190724b7b05e02f1db6ce Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Wed, 20 Nov 2024 03:21:12 +0100 Subject: [PATCH 5/9] chore: update conflate to version 0.3.3 and refactor MountCmd for improved config handling Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- Cargo.lock | 4 +- Cargo.toml | 2 +- src/commands/mount.rs | 97 ++++++++++++++++++++++--------------------- 3 files changed, 53 insertions(+), 50 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d4fa35559..be2d9fdb7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -896,9 +896,9 @@ dependencies = [ [[package]] name = "conflate" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce1803bd64597191f7f4afa2dd0437f76b7b3c065d0e4566380012406c28eaac" +checksum = "0911e70a8cf23eb9cab4282eb9cf050421ee4d8b4464a366b2eb5e8f41c6ddec" dependencies = [ "conflate_derive", "num-traits", diff --git a/Cargo.toml b/Cargo.toml index 6e9351aea..8b70cbb04 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -91,7 +91,7 @@ bytesize = "1" cached = "0.53.1" clap = { version = "4", features = ["derive", "env", "wrap_help"] } clap_complete = "4" -conflate = "0.3.1" +conflate = "0.3.3" convert_case = "0.6.0" dateparser = "0.2.1" derive_more = { version = "1", features = ["debug"] } diff --git a/src/commands/mount.rs b/src/commands/mount.rs index 4b4fed524..97ce8067a 100644 --- a/src/commands/mount.rs +++ b/src/commands/mount.rs @@ -6,18 +6,19 @@ mod fusefs; use fusefs::FuseFS; +use abscissa_core::{ + config::Override, Command, FrameworkError, FrameworkErrorKind::ParseError, Runnable, Shutdown, +}; +use anyhow::{bail, Result}; +use clap::Parser; +use conflate::{Merge, MergePrecedence}; +use fuse_mt::{mount, FuseMT}; +use rustic_core::vfs::{FilePolicy, IdenticalSnapshot, Latest, Vfs}; use std::{ffi::OsStr, path::PathBuf}; use crate::{repository::CliIndexedRepo, status_err, Application, RusticConfig, RUSTIC_APP}; -use abscissa_core::{config::Override, Command, FrameworkError, Runnable, Shutdown}; -use anyhow::{anyhow, Result}; -use conflate::Merge; -use fuse_mt::{mount, FuseMT}; -use rustic_core::vfs::{FilePolicy, IdenticalSnapshot, Latest, Vfs}; -use serde::{Deserialize, Serialize}; - -#[derive(Clone, Command, Debug, clap::Parser, Serialize, Deserialize, Merge)] +#[derive(Clone, Debug, Default, Command, Parser, Merge, serde::Serialize, serde::Deserialize)] #[serde(default, rename_all = "kebab-case", deny_unknown_fields)] pub struct MountCmd { /// The path template to use for snapshots. {id}, {id_long}, {time}, {username}, {hostname}, {label}, {tags}, {backup_start}, {backup_end} are replaced. [default: "[{hostname}]/[{label}]/{time}"] @@ -56,29 +57,28 @@ pub struct MountCmd { options: Vec, } -impl Default for MountCmd { - fn default() -> Self { - Self { - path_template: Some(String::from("[{hostname}]/[{label}]/{time}")), - time_template: Some(String::from("%Y-%m-%d_%H-%M-%S")), - exclusive: false, - file_access: None, - mount_point: None, - snapshot_path: None, - options: vec![String::from("kernel_cache")], - } - } -} - impl Override for MountCmd { // Process the given command line options, overriding settings from // a configuration file using explicit flags taken from command-line // arguments. fn override_config(&self, mut config: RusticConfig) -> Result { - let mut self_config = self.clone(); - // merge "mount" section from config file, if given - self_config.merge(config.mount); + // Merge by precedence, cli <- config <- default + let mut self_config = self.clone().merge_precedence(config.mount, Self::new()); + + // Other values + if self_config.mount_point.is_none() { + return Err(ParseError + .context("Please specify a valid mount point!") + .into()); + } + + if self_config.options.is_empty() { + self_config.options = vec!["kernel_cache".to_string()]; + }; + + // rewrite the "mount" section in the config file config.mount = self_config; + Ok(config) } } @@ -97,25 +97,32 @@ impl Runnable for MountCmd { } impl MountCmd { + fn new() -> Self { + Self { + path_template: Some(String::from("[{hostname}]/[{label}]/{time}")), + time_template: Some(String::from("%Y-%m-%d_%H-%M-%S")), + options: vec![String::from("kernel_cache")], + ..Default::default() + } + } + fn inner_run(&self, repo: CliIndexedRepo) -> Result<()> { let config = RUSTIC_APP.config(); - let mount_point = config - .mount - .mount_point - .as_ref() - .ok_or_else(|| anyhow!("please specify a mountpoint"))?; - - let path_template = config - .mount - .path_template - .clone() - .unwrap_or_else(|| "[{hostname}]/[{label}]/{time}".to_string()); - - let time_template = config - .mount - .time_template - .clone() - .unwrap_or_else(|| "%Y-%m-%d_%H-%M-%S".to_string()); + + // We have merged the config file, the command line options, and the + // default values into a single struct. Now we can use the values. + // If a value is missing, we can return an error. + let Some(path_template) = config.mount.path_template.clone() else { + bail!("please specify a path template"); + }; + + let Some(time_template) = config.mount.time_template.clone() else { + bail!("please specify a time template"); + }; + + let Some(mount_point) = config.mount.mount_point.clone() else { + bail!("please specify a mount point"); + }; let sn_filter = |sn: &_| config.snapshot_filter.matches(sn); let vfs = if let Some(snap_path) = &config.mount.snapshot_path { @@ -132,11 +139,7 @@ impl MountCmd { )? }; - let mut mount_options = if config.mount.options.is_empty() { - vec!["kernel_cache".to_string()] - } else { - config.mount.options.clone() - }; + let mut mount_options = config.mount.options.clone(); mount_options.push(format!("fsname=rusticfs:{}", repo.config().id)); From 54c73e742624707ea322ea298b1a11d866be60cc Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Wed, 20 Nov 2024 03:58:42 +0100 Subject: [PATCH 6/9] fix: improve error messages for missing mount configuration parameters Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- src/commands/mount.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/commands/mount.rs b/src/commands/mount.rs index 97ce8067a..146e0ea41 100644 --- a/src/commands/mount.rs +++ b/src/commands/mount.rs @@ -113,15 +113,15 @@ impl MountCmd { // default values into a single struct. Now we can use the values. // If a value is missing, we can return an error. let Some(path_template) = config.mount.path_template.clone() else { - bail!("please specify a path template"); + bail!("Please specify a path template!"); }; let Some(time_template) = config.mount.time_template.clone() else { - bail!("please specify a time template"); + bail!("Please specify a time template!"); }; let Some(mount_point) = config.mount.mount_point.clone() else { - bail!("please specify a mount point"); + bail!("Please specify a mount point!"); }; let sn_filter = |sn: &_| config.snapshot_filter.matches(sn); @@ -139,6 +139,7 @@ impl MountCmd { )? }; + // Prepare the mount options let mut mount_options = config.mount.options.clone(); mount_options.push(format!("fsname=rusticfs:{}", repo.config().id)); @@ -169,9 +170,8 @@ impl MountCmd { // this should be parsed just fine by fuser, here // https://github.com/cberner/fuser/blob/9f6ced73a36f1d99846e28be9c5e4903939ee9d5/src/mnt/mount_options.rs#L157 let opt_string = format!("-o {}", mount_options.join(",")); - let mount_options = OsStr::new(&opt_string); - mount(fs, mount_point, &[mount_options])?; + mount(fs, mount_point, &[OsStr::new(&opt_string)])?; Ok(()) } From 3b95fcae7befce5fb1b3ef068423aa48e4f4fc63 Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Sun, 24 Nov 2024 10:12:34 +0100 Subject: [PATCH 7/9] apply from review feedback Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- src/commands/mount.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/commands/mount.rs b/src/commands/mount.rs index 146e0ea41..092d3cd48 100644 --- a/src/commands/mount.rs +++ b/src/commands/mount.rs @@ -63,7 +63,10 @@ impl Override for MountCmd { // arguments. fn override_config(&self, mut config: RusticConfig) -> Result { // Merge by precedence, cli <- config <- default - let mut self_config = self.clone().merge_precedence(config.mount, Self::new()); + let mut self_config = self + .clone() + .merge_from(config.mount) + .merge_from(Self::with_default_config()); // Other values if self_config.mount_point.is_none() { @@ -72,10 +75,6 @@ impl Override for MountCmd { .into()); } - if self_config.options.is_empty() { - self_config.options = vec!["kernel_cache".to_string()]; - }; - // rewrite the "mount" section in the config file config.mount = self_config; @@ -97,7 +96,7 @@ impl Runnable for MountCmd { } impl MountCmd { - fn new() -> Self { + fn with_default_config() -> Self { Self { path_template: Some(String::from("[{hostname}]/[{label}]/{time}")), time_template: Some(String::from("%Y-%m-%d_%H-%M-%S")), From da2d33fbdff213b253e1fc7809630162b5cb1725 Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Sun, 24 Nov 2024 11:44:17 +0100 Subject: [PATCH 8/9] use MergeFrom Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- src/commands/mount.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/mount.rs b/src/commands/mount.rs index 092d3cd48..9a8c8b0a0 100644 --- a/src/commands/mount.rs +++ b/src/commands/mount.rs @@ -11,7 +11,7 @@ use abscissa_core::{ }; use anyhow::{bail, Result}; use clap::Parser; -use conflate::{Merge, MergePrecedence}; +use conflate::{Merge, MergeFrom}; use fuse_mt::{mount, FuseMT}; use rustic_core::vfs::{FilePolicy, IdenticalSnapshot, Latest, Vfs}; use std::{ffi::OsStr, path::PathBuf}; From 70ba9aec272f4f477e3fedf41152e9ac106f86aa Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Sun, 24 Nov 2024 20:30:26 +0100 Subject: [PATCH 9/9] remove unneeded mut Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- src/commands/mount.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/mount.rs b/src/commands/mount.rs index 9a8c8b0a0..bfed98501 100644 --- a/src/commands/mount.rs +++ b/src/commands/mount.rs @@ -63,7 +63,7 @@ impl Override for MountCmd { // arguments. fn override_config(&self, mut config: RusticConfig) -> Result { // Merge by precedence, cli <- config <- default - let mut self_config = self + let self_config = self .clone() .merge_from(config.mount) .merge_from(Self::with_default_config());