Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: Allow specifying many options in config profile without array #1130

Merged
merged 1 commit into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 17 additions & 17 deletions config/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,15 @@ If you want to contribute your own configuration, please

### Global Options

| 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 |
| no-progress | If true, disables progress indicators. | false | | RUSTIC_NO_PROGRESS |
| progress-interval | The interval at which progress indicators are shown. | "100ms" | "1m" | RUSTIC_PROGRESS_INTERVAL |
| use-profile | An array of profiles to use. Allows to recursely use other profiles. | Empty array | | RUSTIC_USE_PROFILE |
| 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 |
| no-progress | If true, disables progress indicators. | false | | RUSTIC_NO_PROGRESS |
| progress-interval | The interval at which progress indicators are shown. | "100ms" | "1m" | RUSTIC_PROGRESS_INTERVAL |
| use-profile | Profile or array of profiles to use. Allows to recursely use other profiles. | Empty array | "other" , ["2nd", "3rd"] | RUSTIC_USE_PROFILE |

### Global Options - env variables

Expand Down Expand Up @@ -99,13 +99,13 @@ could possibly shadow other values that you have already set.

### Snapshot-Filter Options

| Attribute | Description | Default Value | Example Value |
| ------------ | ------------------------------------- | --------------- | ------------- |
| filter-host | Array of hosts to filter snapshots. | Not set | ["myhost"] |
| filter-label | Array of labels to filter snapshots. | No label filter | |
| filter-paths | Array of paths to filter snapshots. | No paths filter | |
| filter-tags | Array of tags to filter snapshots. | No tags filter | |
| filter-fn | Custom filter function for snapshots. | Not set | |
| Attribute | Description | Default Value | Example Value |
| ------------ | ---------------------------------------------- | ------------- | ---------------------------- |
| filter-host | Array or string of hosts to filter snapshots. | Not set | ["myhost", "host2"] / "host" |
| filter-label | Array or string of labels to filter snapshots. | Not set | |
| filter-paths | Array or string of paths to filter snapshots. | Not set | |
| filter-tags | Array or string of tags to filter snapshots. | Not set | |
| filter-fn | Custom filter function for snapshots. | Not set | |

### Backup Options

Expand All @@ -125,7 +125,7 @@ can be overwritten in the source-specifc configuration, see below.
| force | If true, forces the backup even if no changes are detected. | false | |
| git-ignore | If true, use .gitignore rules to exclude files from the backup in the source directory. | false | |
| glob | Array of globs specifying what to include/exclude in the backup. | Not set | |
| glob-file | Array of glob files specifying what to include/exclude in the backup. | Not set | |
| glob-file | Array or string of glob files specifying what to include/exclude in the backup. | Not set | |
| group-by | Grouping strategy to find parent snapshot. | "host,label,paths" | |
| host | Host name used in the snapshot. | Not set | |
| iglob | Like glob, but apply case-insensitve | Not set | |
Expand Down
172 changes: 172 additions & 0 deletions config/full-one.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
# Full rustic config file containing all options which are available through the config file.
#
# It uses short notations for options which allow multiple entries in an array but are also possible as single line
# For notations using arrays, see full.toml
#
# This file should be placed in the user's local config dir (~/.config/rustic/) or in the global
# config dir (/etc/rustic).
# If you save it under NAME.toml, use "rustic -P NAME" to access this profile.
#
# Note that most options can be overwritten by the corresponding command line option.

# Global options: These options are used for all commands.
[global]
use-profile = []
log-level = "info" # any of "off", "error", "warn", "info", "debug", "trace"; default: "info"
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.
[global.env]
# This is only an example how to set an rclone env variable. Default: No variables are defined.
RCLONE_XXX = "true"

# Repository options: These options define which backend to use and which password to use.
[repository]
repository = "/repo/rustic" # Must be set
repo-hot = "/my/hot/repo" # Default: not set
# one of the three password options must be set
password = "mySecretPassword"
password-file = "/my/password.txt"
password-command = "my_command.sh"
no-cache = false
cache-dir = "/my/rustic/cachedir" # Default: Applications default cache dir, e.g. ~/.cache/rustic
# use either warm-up (warm-up by file access) or warm-up-command to specify warming up
warm-up = false
warm-up-command = "warmup.sh" # Default: not set
warm-up-wait = "10min" # Default: not set

# Additional repository options - depending on backend. These can be only set in the config file or using env variables.
# For env variables use upper snake case and prefix with "RUSTIC_REPO_OPT_", e.g. `use-passwort = "true"` becomes
# `RUSTIC_REPO_OPT_USE_PASSWORT=true`
[repository.options]
post-create-command = "par2create -qq -n1 -r5 %file" # Only local backend; Default: not set
post-delete-command = "sh -c \"rm -f %file*.par2\"" # Only local backend; Default: not set
retry = "default" # Only rest/rclone/all opendal backends; Allowed values: "false"/"off", "default" or number of retries
timeout = "10min" # Only rest/rclone backend
rclone-command = "rclone serve restic --addr localhost:0" # Only rclone; Default: not set
use-password = "true" # Only rclone
rest-url = "http://localhost:8000" # Only rclone; Default: determine REST URL from rclone output
# Note that opendal backends use several service-dependent options which may be specified here, see
# https://opendal.apache.org/docs/rust/opendal/services/index.html

# Additional repository options for the hot part - depending on backend. These can be only set in the config file or
# using env variables.
# For env variables use upper snake case and prefix with "RUSTIC_REPO_OPTHOT_"
[repository.options-hot]
# see [repository.options]

# Additional repository options for the cold part - depending on backend. These can be only set in the config file or
# using env variables.
# For env variables use upper snake case and prefix with "RUSTIC_REPO_OPTCOLD_"
[repository.options-cold]
# see [repository.options]

# Snapshot-filter options: These options apply to all commands that use snapshot filters
[snapshot-filter]
filter-host = "host2" # Default: no host filter
filter-label = "label1" # Default: no label filter
filter-tags = "tag1,tag2" # Default: no tags filger
filter-paths = "path1" # Default: no paths filter
filter-fn = '|sn| {sn.host == "host1" || sn.description.contains("test")}' # Default: no filter function

# Backup options: These options are used for all sources when calling the backup command.
# They can be overwritten by source-specific options (see below) or command line options.
[backup]
label = "label" # Default: not set
tag = "tag1" # Default: not set
description = "my description" # Default: not set
description-from = "/path/to/description.txt" # Default: not set
delete-never = false
delete-after = "5d" # Default: not set
host = "manually_set_host" # Default: host name
group-by = "host,label,paths" # Can be any combination of host,label,paths,tags
parent = "123abc" # Default: not set
force = false
ignore-ctime = false
ignore-inode = false
stdin-filename = "stdin" # Only for stdin source
as-path = "/my/path" # Default: not set; Note: This only works if source contains of a single path.
with-atime = false
ignore-devid = false
glob = "*.txt" # Default: not set
iglob = "*.txt" # Default: not set
glob-file = "glob-file.txt" # Default: not set
iglob-file = "glob-file.txt" # Default: not set
git-ignore = false
no-require-git = false
exclude-if-present = ".nobackup" # Default: not set
custom-ignorefile = ".rusticignore" # Default: not set
one-file-system = false
exclude-larger-than = "100MB" # Default: not set
json = false
init = false
no-scan = false
quiet = false
skip-identical-parent = false

# Backup options for specific sources - all above options are also available here and replace them for the given source
[[backup.sources]]
source = "/path/to/source1"
label = "label" # Default: not set
# .. and so on. see [backup]

# forget options
[forget]
prune = false
group-by = "host,label,paths" # Can be any combination of host,label,paths,tags
# The following filter options can be also defined here and then overwrite the options for the forget command
filter-host = "host2" # Default: no host filter
filter-label = "label1" # Default: no label filter
filter-tags = "tag1,tag2" # Default: no tags filger
filter-paths = "path1" # Default: no paths filter
filter-fn = '|sn| {sn.host == "host1" || sn.description.contains("test")}' # Default: no filter function
# The retention options follow. All of these are not set by default.
keep-tags = "tag1" # Default: not set
keep-ids = "123abc" # Keep all snapshots whose ID starts with any of these strings, default: not set
keep-last = 0
keep-daily = 3
keep-weekly = 0
keep-monthly = 0
keep-quarter-yearly = 0
keep-half-yearly = 0
keep-yearly = 10
keep-within = "0s"
keep-within-daily = "0 seconds"
keep-within-weekly = "2 months"
keep-withing-monthly = "1 year"
keep-withing-quarter-yearly = "0 year"
keep-withing-half-yearly = "1 year"
keep-within-yearly = "10 years"

# Multiple targets are available for the copy command. Each specify a repository with exactly identical options as in
# the [repository] section.
[[copy.targets]]
repository = "/repo/rustic" # Must be set
repo-hot = "/my/hot/repo" # Default: not set
# one of the three password options must be set
password = "mySecretPassword"
password-file = "/my/password.txt"
password-command = "my_command.sh"
no-cache = false
cache-dir = "/my/rustic/cachedir" # Default: Applications default cache dir, e.g. ~/.cache/rustic
# use either warm-up (warm-up by file access) or warm-up-command to specify warming up
warm-up = false
warm-up-command = "warmup.sh %id" # Default: not set
warm-up-wait = "10min" # Default: not set

[[copy.targets]]
repository = "/repo/rustic2" # Must be set
# ...

[webdav]
address = "localhost:8000"
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
symlinks = false
file-access = "read" # Default: "forbidden" for hot/cold repos, else "read"
snapshot-path = "latest:/dir" # Default: not set - if not set, generate a virtual tree with all snapshots using path-template
8 changes: 4 additions & 4 deletions config/full.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ repo-hot = "/my/hot/repo" # Default: not set
# one of the three password options must be set
password = "mySecretPassword"
password-file = "/my/password.txt"
password-command = "my_command.sh"
password-command = ["my_command.sh"]
no-cache = false
cache-dir = "/my/rustic/cachedir" # Default: Applications default cache dir, e.g. ~/.cache/rustic
# use either warm-up (warm-up by file access) or warm-up-command to specify warming up
warm-up = false
warm-up-command = "warmup.sh %id" # Default: not set
warm-up-command = ["warmup.sh", "%id"] # Default: not set
warm-up-wait = "10min" # Default: not set

# Additional repository options - depending on backend. These can be only set in the config file or using env variables.
Expand Down Expand Up @@ -130,11 +130,11 @@ filter-tags = ["tag1,tag2", "tag3"] # Default: no tags filger
filter-paths = ["path1", "path2,path3"] # Default: no paths filter
filter-fn = '|sn| {sn.host == "host1" || sn.description.contains("test")}' # Default: no filter function
# The retention options follow. All of these are not set by default.
keep-tags = ["tag1", "tag2,tag3"]
keep-tags = ["tag1", "tag2,tag3"] # Default: not set
keep-ids = [
"123abc",
"11122233",
] # Keep all snapshots whose ID starts with any of these strings
] # Keep all snapshots whose ID starts with any of these strings, default: not set
keep-last = 0
keep-daily = 3
keep-weekly = 0
Expand Down
2 changes: 1 addition & 1 deletion src/commands/backup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ pub struct BackupCmd {
/// Backup source, used within config file
#[clap(skip)]
#[merge(skip)]
#[serde_as(deserialize_as = "OneOrMany<_>")]
#[serde_as(as = "OneOrMany<_>")]
source: Vec<String>,
}

Expand Down
2 changes: 1 addition & 1 deletion src/commands/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ pub(crate) struct AddCmd {

/// Command to get the new password from
#[clap(long)]
pub(crate) new_password_command: Option<String>,
pub(crate) new_password_command: Vec<String>,

/// Key options
#[clap(flatten)]
Expand Down
9 changes: 5 additions & 4 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,18 @@ pub(crate) mod progress_options;

use std::{collections::HashMap, path::PathBuf};

use directories::ProjectDirs;

use merge::Merge;

use abscissa_core::config::Config;
use abscissa_core::path::AbsPathBuf;
use abscissa_core::FrameworkError;
use clap::Parser;
use directories::ProjectDirs;
use itertools::Itertools;
use log::Level;
use merge::Merge;
use rustic_backend::BackendOptions;
use rustic_core::RepositoryOptions;
use serde::{Deserialize, Serialize};
use serde_with::{serde_as, OneOrMany};

#[cfg(feature = "webdav")]
use crate::commands::webdav::WebDavCmd;
Expand Down Expand Up @@ -126,6 +125,7 @@ impl RusticConfig {
/// Global options
///
/// These options are available for all commands.
#[serde_as]
#[derive(Default, Debug, Parser, Clone, Deserialize, Serialize, Merge)]
#[serde(default, rename_all = "kebab-case", deny_unknown_fields)]
pub struct GlobalOptions {
Expand All @@ -139,6 +139,7 @@ pub struct GlobalOptions {
env = "RUSTIC_USE_PROFILE"
)]
#[merge(strategy = merge::vec::append)]
#[serde_as(as = "OneOrMany<_>")]
pub use_profile: Vec<String>,

/// Only show what would be done without modifying anything. Does not affect read-only commands.
Expand Down
8 changes: 5 additions & 3 deletions src/filtering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::{error::Error, str::FromStr};
use cached::proc_macro::cached;
use rhai::{serde::to_dynamic, Dynamic, Engine, FnPtr, AST};
use serde::{Deserialize, Serialize};
use serde_with::{serde_as, DisplayFromStr};
use serde_with::{serde_as, DisplayFromStr, OneOrMany};

/// A function to filter snapshots
///
Expand Down Expand Up @@ -61,22 +61,24 @@ pub struct SnapshotFilter {
/// Hostname to filter (can be specified multiple times)
#[clap(long, global = true, value_name = "HOSTNAME")]
#[merge(strategy=merge::vec::overwrite_empty)]
#[serde_as(as = "OneOrMany<_>")]
filter_host: Vec<String>,

/// Label to filter (can be specified multiple times)
#[clap(long, global = true, value_name = "LABEL")]
#[merge(strategy=merge::vec::overwrite_empty)]
#[serde_as(as = "OneOrMany<_>")]
filter_label: Vec<String>,

/// Path list to filter (can be specified multiple times)
#[clap(long, global = true, value_name = "PATH[,PATH,..]")]
#[serde_as(as = "Vec<DisplayFromStr>")]
#[serde_as(as = "OneOrMany<DisplayFromStr>")]
#[merge(strategy=merge::vec::overwrite_empty)]
filter_paths: Vec<StringList>,

/// Tag list to filter (can be specified multiple times)
#[clap(long, global = true, value_name = "TAG[,TAG,..]")]
#[serde_as(as = "Vec<DisplayFromStr>")]
#[serde_as(as = "OneOrMany<DisplayFromStr>")]
#[merge(strategy=merge::vec::overwrite_empty)]
filter_tags: Vec<StringList>,

Expand Down
2 changes: 2 additions & 0 deletions tests/show-config-fixtures/empty.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ no-progress = false
[global.env]

[repository]
password-command = []
no-cache = false
warm-up = false
warm-up-command = []

[repository.options]

Expand Down
Loading