diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 77df51d..b2c1cca 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -9,10 +9,12 @@ repos: - --config-file - .yamllint.yaml id: yamllint + exclude: "borgmatic-template.yaml" - repo: https://github.com/pre-commit/pre-commit-hooks rev: v5.0.0 hooks: - id: trailing-whitespace + exclude: "borgmatic-template.yaml" - id: end-of-file-fixer - id: fix-byte-order-marker - id: mixed-line-ending diff --git a/nixos/hosts/shadowfax/config/borgmatic/borgmatic-template.yaml b/nixos/hosts/shadowfax/config/borgmatic/borgmatic-template.yaml new file mode 100644 index 0000000..5baa54c --- /dev/null +++ b/nixos/hosts/shadowfax/config/borgmatic/borgmatic-template.yaml @@ -0,0 +1,1456 @@ +# Constants to use in the configuration file. Within option values, +# all occurrences of the constant name in curly braces will be +# replaced with the constant value. For example, if you have a +# constant named "app_name" with the value "myapp", then the string +# "{app_name}" will be replaced with "myapp" in the configuration +# file. +# constants: + # app_name: myapp + # user: myuser + +# List of source directories and files to back up. Globs and tildes +# are expanded. Do not backslash spaces in path names. +source_directories: + - /nahar/containers/volumes/plex + +# A required list of local or remote repositories with paths and +# optional labels (which can be used with the --repository flag to +# select a repository). Tildes are expanded. Multiple repositories are +# backed up to in sequence. Borg placeholders can be used. See the +# output of "borg help placeholders" for details. See ssh_command for +# SSH options like identity file or port. If systemd service is used, +# then add local repository paths in the systemd service file to the +# ReadWritePaths list. Prior to borgmatic 1.7.10, repositories was a +# list of plain path strings. +repositories: + - path: /eru/borg/plex + label: local + +# Working directory to use when running actions, useful for backing up +# using relative source directory paths. Does not currently apply to +# borgmatic configuration file paths or includes. Tildes are expanded. +# See http://borgbackup.readthedocs.io/en/stable/usage/create.html for +# details. Defaults to not set. +# working_directory: /path/to/working/directory + +# Stay in same file system; do not cross mount points beyond the given +# source directories. Defaults to false. +# one_file_system: true + +# Only store/extract numeric user and group identifiers. Defaults to +# false. +# numeric_ids: true + +# Store atime into archive. Defaults to true in Borg < 1.2, false in +# Borg 1.2+. +# atime: false + +# Store ctime into archive. Defaults to true. +# ctime: false + +# Store birthtime (creation date) into archive. Defaults to true. +# birthtime: false + +# Use Borg's --read-special flag to allow backup of block and other +# special devices. Use with caution, as it will lead to problems if +# used when backing up special devices such as /dev/zero. Defaults to +# false. But when a database hook is used, the setting here is ignored +# and read_special is considered true. +# read_special: false + +# Record filesystem flags (e.g. NODUMP, IMMUTABLE) in archive. +# Defaults to true. +# flags: true + +# Mode in which to operate the files cache. See +# http://borgbackup.readthedocs.io/en/stable/usage/create.html for +# details. Defaults to "ctime,size,inode". +# files_cache: ctime,size,inode + +# Alternate Borg local executable. Defaults to "borg". +# local_path: borg1 + +# Alternate Borg remote executable. Defaults to "borg". +# remote_path: borg1 + +# Any paths matching these patterns are included/excluded from +# backups. Globs are expanded. (Tildes are not.) See the output of +# "borg help patterns" for more details. Quote any value if it +# contains leading punctuation, so it parses correctly. +# patterns: + # - R / + # - '- /home/*/.cache' + # - + /home/susan + # - '- /home/*' + +# Read include/exclude patterns from one or more separate named files, +# one pattern per line. See the output of "borg help patterns" for +# more details. +# patterns_from: + # - /etc/borgmatic/patterns + +# Any paths matching these patterns are excluded from backups. Globs +# and tildes are expanded. Note that a glob pattern must either start +# with a glob or be an absolute path. Do not backslash spaces in path +# names. See the output of "borg help patterns" for more details. +# exclude_patterns: + # - '*.pyc' + # - /home/*/.cache + # - '*/.vim*.tmp' + # - /etc/ssl + # - /home/user/path with spaces + +# Read exclude patterns from one or more separate named files, one +# pattern per line. See the output of "borg help patterns" for more +# details. +# exclude_from: + # - /etc/borgmatic/excludes + +# Exclude directories that contain a CACHEDIR.TAG file. See +# http://www.brynosaurus.com/cachedir/spec.html for details. Defaults +# to false. +# exclude_caches: true + +# Exclude directories that contain a file with the given filenames. +# Defaults to not set. +# exclude_if_present: + # - .nobackup + +# If true, the exclude_if_present filename is included in backups. +# Defaults to false, meaning that the exclude_if_present filename is +# omitted from backups. +# keep_exclude_tags: true + +# Exclude files with the NODUMP flag. Defaults to false. +# exclude_nodump: true + +# Deprecated. Only used for locating database dumps and bootstrap +# metadata within backup archives created prior to deprecation. +# Replaced by user_runtime_directory and user_state_directory. +# Defaults to ~/.borgmatic +# borgmatic_source_directory: /tmp/borgmatic + +# Path for storing temporary runtime data like streaming database +# dumps and bootstrap metadata. borgmatic automatically creates and +# uses a "borgmatic" subdirectory here. Defaults to $XDG_RUNTIME_DIR +# or or $TMPDIR or $TEMP or /run/user/$UID. +# user_runtime_directory: /run/user/1001 + +# Path for storing borgmatic state files like records of when checks +# last ran. borgmatic automatically creates and uses a "borgmatic" +# subdirectory here. If you change this option, borgmatic must +# create the check records again (and therefore re-run checks). +# Defaults to $XDG_STATE_HOME or ~/.local/state. +# user_state_directory: /var/lib/borgmatic + +# If true, then source directories (and root pattern paths) must +# exist. If they don't, an error is raised. Defaults to false. +# source_directories_must_exist: true + +# The standard output of this command is used to unlock the encryption +# key. Only use on repositories that were initialized with +# passcommand/repokey/keyfile encryption. Note that if both +# encryption_passcommand and encryption_passphrase are set, then +# encryption_passphrase takes precedence. This can also be used to +# access encrypted systemd service credentials. Defaults to not set. +# For more details, see: +# https://torsion.org/borgmatic/docs/how-to/provide-your-passwords/ +# encryption_passcommand: secret-tool lookup borg-repository repo-name + +# Passphrase to unlock the encryption key with. Only use on +# repositories that were initialized with passphrase/repokey/keyfile +# encryption. Quote the value if it contains punctuation, so it parses +# correctly. And backslash any quote or backslash literals as well. +# Defaults to not set. Supports the "{credential ...}" syntax. +# encryption_passphrase: "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~" + +# Number of seconds between each checkpoint during a long-running +# backup. See https://borgbackup.readthedocs.io/en/stable/faq.html for +# details. Defaults to checkpoints every 1800 seconds (30 minutes). +# checkpoint_interval: 1800 + +# Number of backed up bytes between each checkpoint during a +# long-running backup. Only supported with Borg 2+. See +# https://borgbackup.readthedocs.io/en/stable/faq.html for details. +# Defaults to only time-based checkpointing (see +# "checkpoint_interval") instead of volume-based checkpointing. +# checkpoint_volume: 1048576 + +# Specify the parameters passed to the chunker (CHUNK_MIN_EXP, +# CHUNK_MAX_EXP, HASH_MASK_BITS, HASH_WINDOW_SIZE). See +# https://borgbackup.readthedocs.io/en/stable/internals.html for +# details. Defaults to "19,23,21,4095". +# chunker_params: 19,23,21,4095 + +# Type of compression to use when creating archives. (Compression +# level can be added separated with a comma, like "zstd,7".) See +# http://borgbackup.readthedocs.io/en/stable/usage/create.html for +# details. Defaults to "lz4". +# compression: lz4 + +# Remote network upload rate limit in kiBytes/second. Defaults to +# unlimited. +# upload_rate_limit: 100 + +# Size of network upload buffer in MiB. Defaults to no buffer. +# upload_buffer_size: 160 + +# Number of times to retry a failing backup before giving up. Defaults +# to 0 (i.e., does not attempt retry). +# retries: 3 + +# Wait time between retries (in seconds) to allow transient issues +# to pass. Increases after each retry by that same wait time as a +# form of backoff. Defaults to 0 (no wait). +# retry_wait: 10 + +# Directory where temporary Borg files are stored. Defaults to +# $TMPDIR. See "Resource Usage" at +# https://borgbackup.readthedocs.io/en/stable/usage/general.html for +# details. +# temporary_directory: /path/to/tmpdir + +# Command to use instead of "ssh". This can be used to specify ssh +# options. Defaults to not set. +# ssh_command: ssh -i /path/to/private/key + +# Base path used for various Borg directories. Defaults to $HOME, +# ~$USER, or ~. +# borg_base_directory: /path/to/base + +# Path for Borg configuration files. Defaults to +# $borg_base_directory/.config/borg +# borg_config_directory: /path/to/base/config + +# Path for Borg cache files. Defaults to +# $borg_base_directory/.cache/borg +# borg_cache_directory: /path/to/base/cache + +# Maximum time to live (ttl) for entries in the Borg files cache. +# borg_files_cache_ttl: 20 + +# Path for Borg security and encryption nonce files. Defaults to +# $borg_base_directory/.config/borg/security +# borg_security_directory: /path/to/base/config/security + +# Path for Borg encryption key files. Defaults to +# $borg_base_directory/.config/borg/keys +# borg_keys_directory: /path/to/base/config/keys + +# A list of Borg exit codes that should be elevated to errors or +# squashed to warnings as indicated. By default, Borg error exit codes +# (2 to 99) are treated as errors while warning exit codes (1 and +# 100+) are treated as warnings. Exit codes other than 1 and 2 are +# only present in Borg 1.4.0+. +# borg_exit_codes: + # - code: 13 + # treat_as: warning + # - code: 100 + # treat_as: error + +# Umask used for when executing Borg or calling hooks. Defaults to +# 0077 for Borg or the umask that borgmatic is run with for hooks. +# umask: 77 + +# Maximum seconds to wait for acquiring a repository/cache lock. +# Defaults to 1. +# lock_wait: 5 + +# Name of the archive to create. Borg placeholders can be used. See +# the output of "borg help placeholders" for details. Defaults to +# "{hostname}-{now:%Y-%m-%dT%H:%M:%S.%f}" with Borg 1 and +# "{hostname}" with Borg 2, as Borg 2 does not require unique +# archive names; identical archive names form a common "series" that +# can be targeted together. When running actions like repo-list, +# info, or check, borgmatic automatically tries to match only +# archives created with this name format. +# archive_name_format: '{hostname}-documents-{now}' + +# A Borg pattern for filtering down the archives used by borgmatic +# actions that operate on multiple archives. For Borg 1.x, use a shell +# pattern here and see the output of "borg help placeholders" for +# details. For Borg 2.x, see the output of "borg help match-archives". +# If match_archives is not specified, borgmatic defaults to deriving +# the match_archives value from archive_name_format. +# match_archives: sh:{hostname}-* + +# Bypass Borg error about a repository that has been moved. Defaults +# to not bypassing. +# relocated_repo_access_is_ok: true + +# Bypass Borg error about a previously unknown unencrypted repository. +# Defaults to not bypassing. +# unknown_unencrypted_repo_access_is_ok: true + +# Bypass Borg confirmation about check with repair option. Defaults to +# an interactive prompt from Borg. +# check_i_know_what_i_am_doing: true + +# Additional options to pass directly to particular Borg commands, +# handy for Borg options that borgmatic does not yet support natively. +# Note that borgmatic does not perform any validation on these +# options. Running borgmatic with "--verbosity 2" shows the exact Borg +# command-line invocation. +# extra_borg_options: + # Extra command-line options to pass to "borg init". + # init: --extra-option + + # Extra command-line options to pass to "borg create". + # create: --extra-option + + # Extra command-line options to pass to "borg prune". + # prune: --extra-option + + # Extra command-line options to pass to "borg compact". + # compact: --extra-option + + # Extra command-line options to pass to "borg check". + # check: --extra-option + +# Keep all archives within this time interval. See "skip_actions" for +# disabling pruning altogether. +# keep_within: 3H + +# Number of secondly archives to keep. +# keep_secondly: 60 + +# Number of minutely archives to keep. +# keep_minutely: 60 + +# Number of hourly archives to keep. +# keep_hourly: 24 + +# Number of daily archives to keep. +keep_daily: 7 + +# Number of weekly archives to keep. +# keep_weekly: 4 + +# Number of monthly archives to keep. +# keep_monthly: 6 + +# Number of yearly archives to keep. +# keep_yearly: 1 + +# Deprecated. When pruning or checking archives, only consider archive +# names starting with this prefix. Borg placeholders can be used. See +# the output of "borg help placeholders" for details. If a prefix is +# not specified, borgmatic defaults to matching archives based on the +# archive_name_format (see above). +# prefix: sourcehostname + +# List of one or more consistency checks to run on a periodic basis +# (if "frequency" is set) or every time borgmatic runs checks (if +# "frequency" is omitted). +# checks: + # Name of the consistency check to run: + # * "repository" checks the consistency of the + # repository. + # * "archives" checks all of the archives. + # * "data" verifies the integrity of the data + # within the archives and implies the "archives" + # check as well. + # * "spot" checks that some percentage of source + # files are found in the most recent archive (with + # identical contents). + # * "extract" does an extraction dry-run of the + # most recent archive. + # * See "skip_actions" for disabling checks + # altogether. + # - name: spot + + # How frequently to run this type of consistency + # check (as a best effort). The value is a number + # followed by a unit of time. E.g., "2 weeks" to + # run this consistency check no more than every + # two weeks for a given repository or "1 month" to + # run it no more than monthly. Defaults to + # "always": running this check every time checks + # are run. + # frequency: 2 weeks + + # After the "frequency" duration has elapsed, only + # run this check if the current day of the week + # matches one of these values (the name of a day of + # the week in the current locale). "weekday" and + # "weekend" are also accepted. Defaults to running + # the check on any day of the week. + # only_run_on: + # - Saturday + # - Sunday + + # The percentage delta between the source + # directories file count and the most recent backup + # archive file count that is allowed before the + # entire consistency check fails. This can catch + # problems like incorrect excludes, inadvertent + # deletes, etc. Required (and only valid) for the + # "spot" check. + # count_tolerance_percentage: 10 + + # The percentage of total files in the source + # directories to randomly sample and compare to + # their corresponding files in the most recent + # backup archive. Required (and only valid) for the + # "spot" check. + # data_sample_percentage: 1 + + # The percentage of total files in the source + # directories that can fail a spot check comparison + # without failing the entire consistency check. This + # can catch problems like source files that have + # been bulk-changed by malware, backups that have + # been tampered with, etc. The value must be lower + # than or equal to the "contents_sample_percentage". + # Required (and only valid) for the "spot" check. + # data_tolerance_percentage: 0.5 + + # Command to use instead of "xxh64sum" to hash + # source files, usually found in an OS package named + # "xxhash". Do not substitute with a different hash + # type (SHA, MD5, etc.) or the check will never + # succeed. Only valid for the "spot" check. + # xxh64sum_command: /usr/local/bin/xxh64sum + + # How many seconds to check the repository before + # interrupting the check. Useful for splitting a + # long-running repository check into multiple + # partial checks. Defaults to no interruption. Only + # applies to the "repository" check, does not check + # the repository index and is not compatible with + # the "--repair" flag. + # max_duration: 3600 + +# Paths or labels for a subset of the configured "repositories" (see +# above) on which to run consistency checks. Handy in case some of +# your repositories are very large, and so running consistency checks +# on them would take too long. Defaults to running consistency checks +# on all configured repositories. +# check_repositories: + # - user@backupserver:sourcehostname.borg + +# Restrict the number of checked archives to the last n. Applies only +# to the "archives" check. Defaults to checking all archives. +# check_last: 3 + +# Apply color to console output. Can be overridden with --no-color +# command-line flag. Defaults to true. +# color: false + +# List of one or more actions to skip running for this configuration +# file, even if specified on the command-line (explicitly or +# implicitly). This is handy for append-only configurations where you +# never want to run "compact" or checkless configuration where you +# want to skip "check". Defaults to not skipping any actions. +# skip_actions: + # - compact + +# List of one or more shell commands or scripts to execute before all +# the actions for each repository. +# before_actions: + # - echo Starting actions. + +# List of one or more shell commands or scripts to execute before +# creating a backup, run once per repository. +# before_backup: + # - echo Starting a backup. + +# List of one or more shell commands or scripts to execute before +# pruning, run once per repository. +# before_prune: + # - echo Starting pruning. + +# List of one or more shell commands or scripts to execute before +# compaction, run once per repository. +# before_compact: + # - echo Starting compaction. + +# List of one or more shell commands or scripts to execute before +# consistency checks, run once per repository. +# before_check: + # - echo Starting checks. + +# List of one or more shell commands or scripts to execute before +# extracting a backup, run once per repository. +# before_extract: + # - echo Starting extracting. + +# List of one or more shell commands or scripts to execute after +# creating a backup, run once per repository. +# after_backup: + # - echo Finished a backup. + +# List of one or more shell commands or scripts to execute after +# compaction, run once per repository. +# after_compact: + # - echo Finished compaction. + +# List of one or more shell commands or scripts to execute after +# pruning, run once per repository. +# after_prune: + # - echo Finished pruning. + +# List of one or more shell commands or scripts to execute after +# consistency checks, run once per repository. +# after_check: + # - echo Finished checks. + +# List of one or more shell commands or scripts to execute after +# extracting a backup, run once per repository. +# after_extract: + # - echo Finished extracting. + +# List of one or more shell commands or scripts to execute after all +# actions for each repository. +# after_actions: + # - echo Finished actions. + +# List of one or more shell commands or scripts to execute when an +# exception occurs during a "create", "prune", "compact", or "check" +# action or an associated before/after hook. +# on_error: + # - echo Error during create/prune/compact/check. + +# List of one or more shell commands or scripts to execute before +# running all actions (if one of them is "create"). These are +# collected from all configuration files and then run once before all +# of them (prior to all actions). +# before_everything: + # - echo Starting actions. + +# List of one or more shell commands or scripts to execute after +# running all actions (if one of them is "create"). These are +# collected from all configuration files and then run once after all +# of them (after any action). +# after_everything: + # - echo Completed actions. + +# Support for the "borgmatic bootstrap" action, used to extract +# borgmatic configuration files from a backup archive. +# bootstrap: + # Store configuration files used to create a backup inside the + # backup itself. Defaults to true. Changing this to false + # prevents "borgmatic bootstrap" from extracting configuration + # files from the backup. + # store_config_files: false + +# List of one or more PostgreSQL databases to dump before creating a +# backup, run once per configuration file. The database dumps are +# added to your source directories at runtime and streamed directly +# to Borg. Requires pg_dump/pg_dumpall/pg_restore commands. See +# https://www.postgresql.org/docs/current/app-pgdump.html and +# https://www.postgresql.org/docs/current/libpq-ssl.html for +# details. +# postgresql_databases: + # Database name (required if using this hook). Or "all" to + # dump all databases on the host. (Also set the "format" + # to dump each database to a separate file instead of one + # combined file.) Note that using this database hook + # implicitly enables read_special (see above) to support + # dump and restore streaming. + # - name: users + + # Database hostname to connect to. Defaults to connecting + # via local Unix socket. + # hostname: database.example.org + + # Database hostname to restore to. Defaults to the + # "hostname" option. + # restore_hostname: database.example.org + + # Port to connect to. Defaults to 5432. + # port: 5433 + + # Port to restore to. Defaults to the "port" option. + # restore_port: 5433 + + # Username with which to connect to the database. Defaults + # to the username of the current user. You probably want + # to specify the "postgres" superuser here when the + # database name is "all". Supports the "{credential ...}" + # syntax. + # username: dbuser + + # Username with which to restore the database. Defaults to + # the "username" option. Supports the "{credential ...}" + # syntax. + # restore_username: dbuser + + # Password with which to connect to the database. Omitting + # a password will only work if PostgreSQL is configured to + # trust the configured username without a password or you + # create a ~/.pgpass file. Supports the "{credential ...}" + # syntax. + # password: trustsome1 + + # Password with which to connect to the restore database. + # Defaults to the "password" option. Supports the + # "{credential ...}" syntax. + # restore_password: trustsome1 + + # Do not output commands to set ownership of objects to + # match the original database. By default, pg_dump and + # pg_restore issue ALTER OWNER or SET SESSION + # AUTHORIZATION statements to set ownership of created + # schema elements. These statements will fail unless the + # initial connection to the database is made by a + # superuser. + # no_owner: true + + # Database dump output format. One of "plain", "custom", + # "directory", or "tar". Defaults to "custom" (unlike raw + # pg_dump) for a single database. Or, when database name + # is "all" and format is blank, dumps all databases to a + # single file. But if a format is specified with an "all" + # database name, dumps each database to a separate file of + # that format, allowing more convenient restores of + # individual databases. See the pg_dump documentation for + # more about formats. + # format: directory + + # SSL mode to use to connect to the database server. One + # of "disable", "allow", "prefer", "require", "verify-ca" + # or "verify-full". Defaults to "disable". + # ssl_mode: require + + # Path to a client certificate. + # ssl_cert: /root/.postgresql/postgresql.crt + + # Path to a private client key. + # ssl_key: /root/.postgresql/postgresql.key + + # Path to a root certificate containing a list of trusted + # certificate authorities. + # ssl_root_cert: /root/.postgresql/root.crt + + # Path to a certificate revocation list. + # ssl_crl: /root/.postgresql/root.crl + + # Command to use instead of "pg_dump" or "pg_dumpall". + # This can be used to run a specific pg_dump version + # (e.g., one inside a running container). If you run it + # from within a container, make sure to mount your + # host's ".borgmatic" folder into the container using + # the same directory structure. Defaults to "pg_dump" + # for single database dump or "pg_dumpall" to dump all + # databases. + # pg_dump_command: docker exec my_pg_container pg_dump + + # Command to use instead of "pg_restore". This can be used + # to run a specific pg_restore version (e.g., one inside a + # running container). Defaults to "pg_restore". + # pg_restore_command: docker exec my_pg_container pg_restore + + # Command to use instead of "psql". This can be used to + # run a specific psql version (e.g., one inside a running + # container). Defaults to "psql". + # psql_command: docker exec my_pg_container psql + + # Additional pg_dump/pg_dumpall options to pass directly + # to the dump command, without performing any validation + # on them. See pg_dump documentation for details. + # options: --role=someone + + # Additional psql options to pass directly to the psql + # command that lists available databases, without + # performing any validation on them. See psql + # documentation for details. + # list_options: --role=someone + + # Additional pg_restore/psql options to pass directly to + # the restore command, without performing any validation + # on them. See pg_restore/psql documentation for details. + # restore_options: --role=someone + + # Additional psql options to pass directly to the analyze + # command run after a restore, without performing any + # validation on them. See psql documentation for details. + # analyze_options: --role=someone + +# List of one or more MariaDB databases to dump before creating a +# backup, run once per configuration file. The database dumps are +# added to your source directories at runtime and streamed directly +# to Borg. Requires mariadb-dump/mariadb commands. See +# https://mariadb.com/kb/en/library/mysqldump/ for details. +# mariadb_databases: + # Database name (required if using this hook). Or "all" to + # dump all databases on the host. Note that using this + # database hook implicitly enables read_special (see + # above) to support dump and restore streaming. + # - name: users + + # Database hostname to connect to. Defaults to connecting + # via local Unix socket. + # hostname: database.example.org + + # Database hostname to restore to. Defaults to the + # "hostname" option. + # restore_hostname: database.example.org + + # Port to connect to. Defaults to 3306. + # port: 3307 + + # Port to restore to. Defaults to the "port" option. + # restore_port: 5433 + + # Username with which to connect to the database. Defaults + # to the username of the current user. Supports the + # "{credential ...}" syntax. + # username: dbuser + + # Username with which to restore the database. Defaults to + # the "username" option. Supports the "{credential ...}" + # syntax. + # restore_username: dbuser + + # Password with which to connect to the database. Omitting + # a password will only work if MariaDB is configured to + # trust the configured username without a password. + # Supports the "{credential ...}" syntax. + # password: trustsome1 + + # Password with which to connect to the restore database. + # Defaults to the "password" option. Supports the + # "{credential ...}" syntax. + # restore_password: trustsome1 + + # Command to use instead of "mariadb-dump". This can be + # used to run a specific mariadb_dump version (e.g., one + # inside a running container). If you run it from within + # a container, make sure to mount your host's + # ".borgmatic" folder into the container using the same + # directory structure. Defaults to "mariadb-dump". + # mariadb_dump_command: docker exec mariadb_container mariadb-dump + + # Command to run instead of "mariadb". This can be used to + # run a specific mariadb version (e.g., one inside a + # running container). Defaults to "mariadb". + # mariadb_command: docker exec mariadb_container mariadb + + # Database dump output format. Currently only "sql" is + # supported. Defaults to "sql" for a single database. Or, + # when database name is "all" and format is blank, dumps + # all databases to a single file. But if a format is + # specified with an "all" database name, dumps each + # database to a separate file of that format, allowing + # more convenient restores of individual databases. + # format: directory + + # Use the "--add-drop-database" flag with mariadb-dump, + # causing the database to be dropped right before restore. + # Defaults to true. + # add_drop_database: false + + # Additional mariadb-dump options to pass directly to the + # dump command, without performing any validation on them. + # See mariadb-dump documentation for details. + # options: --skip-comments + + # Additional options to pass directly to the mariadb + # command that lists available databases, without + # performing any validation on them. See mariadb command + # documentation for details. + # list_options: --defaults-extra-file=mariadb.cnf + + # Additional options to pass directly to the mariadb + # command that restores database dumps, without + # performing any validation on them. See mariadb command + # documentation for details. + # restore_options: --defaults-extra-file=mariadb.cnf + +# List of one or more MySQL databases to dump before creating a +# backup, run once per configuration file. The database dumps are +# added to your source directories at runtime and streamed directly +# to Borg. Requires mysqldump/mysql commands. See +# https://dev.mysql.com/doc/refman/8.0/en/mysqldump.html for +# details. +# mysql_databases: + # Database name (required if using this hook). Or "all" to + # dump all databases on the host. Note that using this + # database hook implicitly enables read_special (see + # above) to support dump and restore streaming. + # - name: users + + # Database hostname to connect to. Defaults to connecting + # via local Unix socket. + # hostname: database.example.org + + # Database hostname to restore to. Defaults to the + # "hostname" option. + # restore_hostname: database.example.org + + # Port to connect to. Defaults to 3306. + # port: 3307 + + # Port to restore to. Defaults to the "port" option. + # restore_port: 5433 + + # Username with which to connect to the database. Defaults + # to the username of the current user. Supports the + # "{credential ...}" syntax. + # username: dbuser + + # Username with which to restore the database. Defaults to + # the "username" option. Supports the "{credential ...}" + # syntax. + # restore_username: dbuser + + # Password with which to connect to the database. Omitting + # a password will only work if MySQL is configured to + # trust the configured username without a password. + # Supports the "{credential ...}" syntax. + # password: trustsome1 + + # Password with which to connect to the restore database. + # Defaults to the "password" option. Supports the + # "{credential ...}" syntax. + # restore_password: trustsome1 + + # Command to use instead of "mysqldump". This can be + # used to run a specific mysql_dump version (e.g., one + # inside a running container). If you run it from within + # a container, make sure to mount your host's + # ".borgmatic" folder into the container using the same + # directory structure. Defaults to "mysqldump". + # mysql_dump_command: docker exec mysql_container mysqldump + + # Command to run instead of "mysql". This can be used to + # run a specific mysql version (e.g., one inside a running + # container). Defaults to "mysql". + # mysql_command: docker exec mysql_container mysql + + # Database dump output format. Currently only "sql" is + # supported. Defaults to "sql" for a single database. Or, + # when database name is "all" and format is blank, dumps + # all databases to a single file. But if a format is + # specified with an "all" database name, dumps each + # database to a separate file of that format, allowing + # more convenient restores of individual databases. + # format: directory + + # Use the "--add-drop-database" flag with mysqldump, + # causing the database to be dropped right before restore. + # Defaults to true. + # add_drop_database: false + + # Additional mysqldump options to pass directly to the + # dump command, without performing any validation on them. + # See mysqldump documentation for details. + # options: --skip-comments + + # Additional options to pass directly to the mysql + # command that lists available databases, without + # performing any validation on them. See mysql command + # documentation for details. + # list_options: --defaults-extra-file=my.cnf + + # Additional options to pass directly to the mysql + # command that restores database dumps, without + # performing any validation on them. See mysql command + # documentation for details. + # restore_options: --defaults-extra-file=my.cnf + +# sqlite_databases: + # This is used to tag the database dump file with a name. + # It is not the path to the database file itself. The name + # "all" has no special meaning for SQLite databases. + # - name: users + + # Path to the SQLite database file to dump. If relative, + # it is relative to the current working directory. Note + # that using this database hook implicitly enables + # read_special (see above) to support dump and restore + # streaming. + # path: /var/lib/sqlite/users.db + + # Path to the SQLite database file to restore to. Defaults + # to the "path" option. + # restore_path: /var/lib/sqlite/users.db + +# List of one or more MongoDB databases to dump before creating a +# backup, run once per configuration file. The database dumps are +# added to your source directories at runtime and streamed directly +# to Borg. Requires mongodump/mongorestore commands. See +# https://docs.mongodb.com/database-tools/mongodump/ and +# https://docs.mongodb.com/database-tools/mongorestore/ for details. +# mongodb_databases: + # Database name (required if using this hook). Or "all" to + # dump all databases on the host. Note that using this + # database hook implicitly enables read_special (see + # above) to support dump and restore streaming. + # - name: users + + # Database hostname to connect to. Defaults to connecting + # to localhost. + # hostname: database.example.org + + # Database hostname to restore to. Defaults to the + # "hostname" option. + # restore_hostname: database.example.org + + # Port to connect to. Defaults to 27017. + # port: 27018 + + # Port to restore to. Defaults to the "port" option. + # restore_port: 5433 + + # Username with which to connect to the database. Skip it + # if no authentication is needed. Supports the + # "{credential ...}" syntax. + # username: dbuser + + # Username with which to restore the database. Defaults to + # the "username" option. Supports the "{credential ...}" + # syntax. + # restore_username: dbuser + + # Password with which to connect to the database. Skip it + # if no authentication is needed. Supports the + # "{credential ...}" syntax. + # password: trustsome1 + + # Password with which to connect to the restore database. + # Defaults to the "password" option. Supports the + # "{credential ...}" syntax. + # restore_password: trustsome1 + + # Authentication database where the specified username + # exists. If no authentication database is specified, the + # database provided in "name" is used. If "name" is "all", + # the "admin" database is used. + # authentication_database: admin + + # Database dump output format. One of "archive", or + # "directory". Defaults to "archive". See mongodump + # documentation for details. Note that format is ignored + # when the database name is "all". + # format: directory + + # Additional mongodump options to pass directly to the + # dump command, without performing any validation on them. + # See mongodump documentation for details. + # options: --dumpDbUsersAndRoles + + # Additional mongorestore options to pass directly to the + # dump command, without performing any validation on them. + # See mongorestore documentation for details. + # restore_options: --restoreDbUsersAndRoles + +# ntfy: + # The topic to publish to. See https://ntfy.sh/docs/publish/ + # for details. + # topic: topic + + # The address of your self-hosted ntfy.sh instance. + # server: https://ntfy.your-domain.com + + # The username used for authentication. Supports the + # "{credential ...}" syntax. + # username: testuser + + # The password used for authentication. Supports the + # "{credential ...}" syntax. + # password: fakepassword + + # An ntfy access token to authenticate with instead of + # username/password. Supports the "{credential ...}" syntax. + # access_token: tk_AgQdq7mVBoFD37zQVN29RhuMzNIz2 + + # start: + # The title of the message. + # title: Ping! + + # The message body to publish. + # message: Your backups have failed. + + # The priority to set. + # priority: urgent + + # Tags to attach to the message. + # tags: incoming_envelope + + # finish: + # The title of the message. + # title: Ping! + + # The message body to publish. + # message: Your backups have failed. + + # The priority to set. + # priority: urgent + + # Tags to attach to the message. + # tags: incoming_envelope + + # fail: + # The title of the message. + # title: Ping! + + # The message body to publish. + # message: Your backups have failed. + + # The priority to set. + # priority: urgent + + # Tags to attach to the message. + # tags: incoming_envelope + + # List of one or more monitoring states to ping for: "start", + # "finish", and/or "fail". Defaults to pinging for failure + # only. + # states: + # - start + # - finish + +# pushover: + # Your application's API token. Supports the "{credential + # ...}" syntax. + # token: 7ms6TXHpTokTou2P6x4SodDeentHRa + + # Your user/group key (or that of your target user), viewable + # when logged into your dashboard: often referred to as + # USER_KEY in Pushover documentation and code examples. + # Supports the "{credential ...}" syntax. + # user: hwRwoWsXMBWwgrSecfa9EfPey55WSN + + # start: + # Message to be sent to the user or group. If omitted + # the default is the name of the state. + # message: A backup job has started. + + # A value of -2, -1, 0 (default), 1 or 2 that + # indicates the message priority. + # priority: 0 + + # How many seconds your notification will continue + # to be retried (every retry seconds). Defaults to + # 600. This settings only applies to priority 2 + # notifications. + # expire: 600 + + # The retry parameter specifies how often + # (in seconds) the Pushover servers will send the + # same notification to the user. Defaults to 30. This + # settings only applies to priority 2 notifications. + # retry: 30 + + # The name of one of your devices to send just to + # that device instead of all devices. + # device: pixel8 + + # Set to True to enable HTML parsing of the message. + # Set to False for plain text. + # html: true + + # The name of a supported sound to override your + # default sound choice. All options can be found + # here: https://pushover.net/api#sounds + # sound: bike + + # Your message's title, otherwise your app's name is + # used. + # title: A backup job has started. + + # The number of seconds that the message will live, + # before being deleted automatically. The ttl + # parameter is ignored for messages with a priority. + # value of 2. + # ttl: 3600 + + # A supplementary URL to show with your message. + # url: https://pushover.net/apps/xxxxx-borgbackup + + # A title for the URL specified as the url parameter, + # otherwise just the URL is shown. + # url_title: Pushover Link + + # finish: + # Message to be sent to the user or group. If omitted + # the default is the name of the state. + # message: A backup job has finished. + + # A value of -2, -1, 0 (default), 1 or 2 that + # indicates the message priority. + # priority: 0 + + # How many seconds your notification will continue + # to be retried (every retry seconds). Defaults to + # 600. This settings only applies to priority 2 + # notifications. + # expire: 600 + + # The retry parameter specifies how often + # (in seconds) the Pushover servers will send the + # same notification to the user. Defaults to 30. This + # settings only applies to priority 2 notifications. + # retry: 30 + + # The name of one of your devices to send just to + # that device instead of all devices. + # device: pixel8 + + # Set to True to enable HTML parsing of the message. + # Set to False for plain text. + # html: true + + # The name of a supported sound to override your + # default sound choice. All options can be found + # here: https://pushover.net/api#sounds + # sound: bike + + # Your message's title, otherwise your app's name is + # used. + # title: A backup job has started. + + # The number of seconds that the message will live, + # before being deleted automatically. The ttl + # parameter is ignored for messages with a priority. + # value of 2. + # ttl: 3600 + + # A supplementary URL to show with your message. + # url: https://pushover.net/apps/xxxxx-borgbackup + + # A title for the URL specified as the url parameter, + # otherwise just the URL is shown. + # url_title: Pushover Link + + # fail: + # Message to be sent to the user or group. If omitted + # the default is the name of the state. + # message: A backup job has failed. + + # A value of -2, -1, 0 (default), 1 or 2 that + # indicates the message priority. + # priority: 0 + + # How many seconds your notification will continue + # to be retried (every retry seconds). Defaults to + # 600. This settings only applies to priority 2 + # notifications. + # expire: 600 + + # The retry parameter specifies how often + # (in seconds) the Pushover servers will send the + # same notification to the user. Defaults to 30. This + # settings only applies to priority 2 notifications. + # retry: 30 + + # The name of one of your devices to send just to + # that device instead of all devices. + # device: pixel8 + + # Set to True to enable HTML parsing of the message. + # Set to False for plain text. + # html: true + + # The name of a supported sound to override your + # default sound choice. All options can be found + # here: https://pushover.net/api#sounds + # sound: bike + + # Your message's title, otherwise your app's name is + # used. + # title: A backup job has started. + + # The number of seconds that the message will live, + # before being deleted automatically. The ttl + # parameter is ignored for messages with a priority. + # value of 2. + # ttl: 3600 + + # A supplementary URL to show with your message. + # url: https://pushover.net/apps/xxxxx-borgbackup + + # A title for the URL specified as the url parameter, + # otherwise just the URL is shown. + # url_title: Pushover Link + + # List of one or more monitoring states to ping for: "start", + # "finish", and/or "fail". Defaults to pinging for failure + # only. + # states: + # - start + # - finish + +# zabbix: + # The ID of the Zabbix item used for collecting data. + # Unique across the entire Zabbix system. + # itemid: 55105 + + # Host name where the item is stored. Required if "itemid" + # is not set. + # host: borg-server + + # Key of the host where the item is stored. Required if + # "itemid" is not set. + # key: borg.status + + # The address of your Zabbix instance. + # server: https://zabbix.your-domain.com + + # The username used for authentication. Not needed if using + # an API key. Supports the "{credential ...}" syntax. + # username: testuser + + # The password used for authentication. Not needed if using + # an API key. Supports the "{credential ...}" syntax. + # password: fakepassword + + # The API key used for authentication. Not needed if using an + # username/password. Supports the "{credential ...}" syntax. + # api_key: fakekey + + # start: + # The value to set the item to on start. + # value: STARTED + + # finish: + # The value to set the item to on finish. + # value: FINISH + + # fail: + # The value to set the item to on fail. + # value: ERROR + + # List of one or more monitoring states to ping for: "start", + # "finish", and/or "fail". Defaults to pinging for failure + # only. + # states: + # - start + # - finish + +# apprise: + # A list of Apprise services to publish to with URLs and + # labels. The labels are used for logging. A full list of + # services and their configuration can be found at + # https://github.com/caronc/apprise/wiki. + # services: + # - url: kodi://user@hostname + # label: kodi + # - url: line://Token@User + # label: line + + # Send borgmatic logs to Apprise services as part the + # "finish", "fail", and "log" states. Defaults to true. + # send_logs: false + + # Number of bytes of borgmatic logs to send to Apprise + # services. Set to 0 to send all logs and disable this + # truncation. Defaults to 1500. + # logs_size_limit: 100000 + + # start: + # Specify the message title. If left unspecified, no + # title is sent. + # title: Ping! + + # Specify the message body. + # body: Starting backup process. + + # finish: + # Specify the message title. If left unspecified, no + # title is sent. + # title: Ping! + + # Specify the message body. + # body: Backups successfully made. + + # fail: + # Specify the message title. If left unspecified, no + # title is sent. + # title: Ping! + + # Specify the message body. + # body: Your backups have failed. + + # log: + # Specify the message title. If left unspecified, no + # title is sent. + # title: Ping! + + # Specify the message body. + # body: Here is some info about your backups. + + # List of one or more monitoring states to ping for: + # "start", "finish", "fail", and/or "log". Defaults to + # pinging for failure only. For each selected state, + # corresponding configuration for the message title and body + # should be given. If any is left unspecified, a generic + # message is emitted instead. + # states: + # - start + # - finish + +# Configuration for a monitoring integration with Healthchecks. Create +# an account at https://healthchecks.io (or self-host Healthchecks) if +# you'd like to use this service. See borgmatic monitoring +# documentation for details. +# healthchecks: + # Healthchecks ping URL or UUID to notify when a backup + # begins, ends, errors, or to send only logs. + # ping_url: https://hc-ping.com/your-uuid-here + + # Verify the TLS certificate of the ping URL host. Defaults to + # true. + # verify_tls: false + + # Send borgmatic logs to Healthchecks as part the "finish", + # "fail", and "log" states. Defaults to true. + # send_logs: false + + # Number of bytes of borgmatic logs to send to Healthchecks, + # ideally the same as PING_BODY_LIMIT configured on the + # Healthchecks server. Set to 0 to send all logs and disable + # this truncation. Defaults to 100000. + # ping_body_limit: 200000 + + # List of one or more monitoring states to ping for: "start", + # "finish", "fail", and/or "log". Defaults to pinging for all + # states. + # states: + # - finish + + # Create the check if it does not exist. Only works with + # the slug URL scheme (https://hc-ping.com// + # as opposed to https://hc-ping.com/). + # Defaults to false. + # create_slug: true + +# Configuration for a monitoring integration with Uptime Kuma using +# the Push monitor type. +# See more information here: https://uptime.kuma.pet +# uptime_kuma: + # Uptime Kuma push URL without query string (do not include the + # question mark or anything after it). + # push_url: https://example.uptime.kuma/api/push/abcd1234 + + # List of one or more monitoring states to push for: "start", + # "finish", and/or "fail". Defaults to pushing for all + # states. + # states: + # - start + # - finish + # - fail + +# Configuration for a monitoring integration with Cronitor. Create an +# account at https://cronitor.io if you'd like to use this service. +# See borgmatic monitoring documentation for details. +# cronitor: + # Cronitor ping URL to notify when a backup begins, + # ends, or errors. + # ping_url: https://cronitor.link/d3x0c1 + +# Configuration for a monitoring integration with PagerDuty. Create an +# account at https://www.pagerduty.com if you'd like to use this +# service. See borgmatic monitoring documentation for details. +# pagerduty: + # PagerDuty integration key used to notify PagerDuty when a + # backup errors. Supports the "{credential ...}" syntax. + # integration_key: a177cad45bd374409f78906a810a3074 + +# Configuration for a monitoring integration with Cronhub. Create an +# account at https://cronhub.io if you'd like to use this service. See +# borgmatic monitoring documentation for details. +# cronhub: + # Cronhub ping URL to notify when a backup begins, + # ends, or errors. + # ping_url: https://cronhub.io/ping/1f5e3410-254c-5587 + +# Configuration for a monitoring integration with Grafana Loki. You +# can send the logs to a self-hosted instance or create an account at +# https://grafana.com/auth/sign-up/create-user. See borgmatic +# monitoring documentation for details. +# loki: + # Grafana loki log URL to notify when a backup begins, + # ends, or fails. + # url: http://localhost:3100/loki/api/v1/push + + # Allows setting custom labels for the logging stream. At + # least one label is required. "__hostname" gets replaced by + # the machine hostname automatically. "__config" gets replaced + # by the name of the configuration file. "__config_path" gets + # replaced by the full path of the configuration file. + # labels: + # app: borgmatic + # config: __config + # hostname: __hostname + +# Configuration for a monitoring integration with Sentry. You can use +# a self-hosted instance via https://develop.sentry.dev/self-hosted/ +# or create a cloud-hosted account at https://sentry.io. See borgmatic +# monitoring documentation for details. +# sentry: + # Sentry Data Source Name (DSN) URL, associated with a + # particular Sentry project. Used to construct a cron URL, + # notified when a backup begins, ends, or errors. + # data_source_name_url: https://5f80ec@o294220.ingest.us.sentry.io/203069 + + # Sentry monitor slug, associated with a particular Sentry + # project monitor. Used along with the data source name URL to + # construct a cron URL. + # monitor_slug: mymonitor + + # List of one or more monitoring states to ping for: "start", + # "finish", and/or "fail". Defaults to pinging for all states. + # states: + # - start + # - finish + +# Configuration for integration with the ZFS filesystem. +# zfs: + # Command to use instead of "zfs". + # zfs_command: /usr/local/bin/zfs + + # Command to use instead of "mount". + # mount_command: /usr/local/bin/mount + + # Command to use instead of "umount". + # umount_command: /usr/local/bin/umount + +# Configuration for integration with the Btrfs filesystem. +# btrfs: + # Command to use instead of "btrfs". + # btrfs_command: /usr/local/bin/btrfs + + # Command to use instead of "findmnt". + # findmnt_command: /usr/local/bin/findmnt + +# Configuration for integration with Linux LVM (Logical Volume +# Manager). +# lvm: + # Size to allocate for each snapshot taken, including the + # units to use for that size. Defaults to "10%ORIGIN" (10% + # of the size of logical volume being snapshotted). See the + # lvcreate "--size" and "--extents" documentation for more + # information: + # https://www.man7.org/linux/man-pages/man8/lvcreate.8.html + # snapshot_size: 5GB + + # Command to use instead of "lvcreate". + # lvcreate_command: /usr/local/bin/lvcreate + + # Command to use instead of "lvremove". + # lvremove_command: /usr/local/bin/lvremove + + # Command to use instead of "lvs". + # lvs_command: /usr/local/bin/lvs + + # Command to use instead of "lsblk". + # lsblk_command: /usr/local/bin/lsblk + + # Command to use instead of "mount". + # mount_command: /usr/local/bin/mount + + # Command to use instead of "umount". + # umount_command: /usr/local/bin/umount + +# Configuration for integration with Docker or Podman secrets. +# container: + # Secrets directory to use instead of "/run/secrets". + # secrets_directory: /path/to/secrets + +# Configuration for integration with the KeePassXC password manager. +# keepassxc: + # Command to use instead of "keepassxc-cli". + # keepassxc_cli_command: /usr/local/bin/keepassxc-cli diff --git a/nixos/hosts/shadowfax/config/borgmatic/jellyfin.nix b/nixos/hosts/shadowfax/config/borgmatic/jellyfin.nix new file mode 100644 index 0000000..0a098b8 --- /dev/null +++ b/nixos/hosts/shadowfax/config/borgmatic/jellyfin.nix @@ -0,0 +1,40 @@ +{ + config, + pkgs, + ... +}: { + mySystem.services.borgmatic = { + configurations.jellyfin = { + source_directories = [ + "/nahar/containers/volumes/jellyfin" + ]; + + repositories = [ + { + label = "local"; + path = "/eru/borg/jellyfin"; + } + { + label = "remote"; + path = "ssh://uy5oy4m3@uy5oy4m3.repo.borgbase.com/./repo"; + } + ]; + + ssh_command = "${pkgs.openssh}/bin/ssh -i ${config.sops.secrets."borgmatic/jellyfin/append_key".path}"; + + encryption_passcommand = ''${pkgs.coreutils-full}/bin/cat ${config.sops.secrets."borgmatic/jellyfin/encryption_passphrase".path}''; + + # Retention settings + keep_daily = 14; + exclude_patterns = [ + "*/Cache/*" + ]; + + zfs = { + zfs_command = "${pkgs.zfs}/bin/zfs"; + mount_command = "${pkgs.util-linux}/bin/mount"; + umount_command = "${pkgs.util-linux}/bin/umount"; + }; + }; + }; +} diff --git a/nixos/hosts/shadowfax/config/borgmatic/plex.nix b/nixos/hosts/shadowfax/config/borgmatic/plex.nix index 9736c1f..364475b 100644 --- a/nixos/hosts/shadowfax/config/borgmatic/plex.nix +++ b/nixos/hosts/shadowfax/config/borgmatic/plex.nix @@ -1,14 +1,12 @@ { config, - lib, pkgs, ... }: { - services.borgmatic = { - enable = true; + mySystem.services.borgmatic = { configurations.plex = { source_directories = [ - "/mnt/restic_nightly_backup/nahar/containers/volumes/plex/Library/" + "/nahar/containers/volumes/plex" ]; repositories = [ @@ -16,14 +14,22 @@ label = "local"; path = "/eru/borg/plex"; } + { + label = "remote"; + path = "ssh://kvq39z04@kvq39z04.repo.borgbase.com/./repo"; + } ]; - storage.encryption_passcommand = ''${pkgs.coreutils-full}/bin/cat ${config.sops.secrets."borgmatic/encryption_passphrase".path}''; + ssh_command = "${pkgs.openssh}/bin/ssh -i ${config.sops.secrets."borgmatic/plex/append_key".path}"; + + encryption_passcommand = ''${pkgs.coreutils-full}/bin/cat ${config.sops.secrets."borgmatic/plex/encryption_passphrase".path}''; # Retention settings - retention.keep_daily = 7; - retention.keep_weekly = 4; - retention.keep_monthly = 6; + keep_daily = 14; + exclude_patterns = [ + "*/Cache/*" + ]; + zfs = { zfs_command = "${pkgs.zfs}/bin/zfs"; mount_command = "${pkgs.util-linux}/bin/mount"; diff --git a/nixos/hosts/shadowfax/config/sops-secrets.nix b/nixos/hosts/shadowfax/config/sops-secrets.nix index 3624bda..b39a081 100644 --- a/nixos/hosts/shadowfax/config/sops-secrets.nix +++ b/nixos/hosts/shadowfax/config/sops-secrets.nix @@ -205,7 +205,23 @@ mode = "400"; restartUnits = ["unpackerr.service"]; }; - "borgmatic/encryption_passphrase" = { + # Borgmatic + "borgmatic/plex/encryption_passphrase" = { + sopsFile = ../secrets.sops.yaml; + mode = "400"; + restartUnits = ["borgmatic.service"]; + }; + "borgmatic/plex/append_key" = { + sopsFile = ../secrets.sops.yaml; + mode = "400"; + restartUnits = ["borgmatic.service"]; + }; + "borgmatic/jellyfin/encryption_passphrase" = { + sopsFile = ../secrets.sops.yaml; + mode = "400"; + restartUnits = ["borgmatic.service"]; + }; + "borgmatic/jellyfin/append_key" = { sopsFile = ../secrets.sops.yaml; mode = "400"; restartUnits = ["borgmatic.service"]; diff --git a/nixos/hosts/shadowfax/default.nix b/nixos/hosts/shadowfax/default.nix index 12fa137..361db02 100644 --- a/nixos/hosts/shadowfax/default.nix +++ b/nixos/hosts/shadowfax/default.nix @@ -260,6 +260,7 @@ in { purpose = "Production"; # Services services = { + borgmatic.enable = true; # Misc libvirt-qemu.enable = true; podman.enable = true; @@ -435,15 +436,6 @@ in { hardening = true; qbittorrentPort = 50413; }; - # ZFS nightly snapshot of container volumes - zfs-nightly-snap = { - enable = true; - mountPath = "/mnt/restic_nightly_backup"; - zfsDataset = "nahar/containers/volumes"; - snapshotName = "restic_nightly_snap"; - #startAt = "*-*-* 06:30:00 America/Chicago"; - startAt = "*-*-* 00:10:00 America/Chicago"; - }; }; # System system = { diff --git a/nixos/hosts/shadowfax/secrets.sops.yaml b/nixos/hosts/shadowfax/secrets.sops.yaml index 6290243..22db3f4 100644 --- a/nixos/hosts/shadowfax/secrets.sops.yaml +++ b/nixos/hosts/shadowfax/secrets.sops.yaml @@ -12,7 +12,12 @@ postgres: pushover: userKey: ENC[AES256_GCM,data:RYn9OCGaEgu/41kMolmqjYtr8FRmyEOvNStk+7Uz1A==,iv:L4pJJxGPhrmGSJdRDIP/OONibHvIP8KUdXwED29kTJ8=,tag:6TxYaUA6QA1NroBXhQHRlQ==,type:str] borgmatic: - encryption_passphrase: ENC[AES256_GCM,data:Rzmb+tNo0IG6Ub3Z5pB+XahW7gtZOPs5Cjvrzw4m47q0D7bErACTzQx7VdrSJcm8+g==,iv:cQsm3MfrY4KCTvByUcQe0n51UVm/kNtTUGORx0r+wjg=,tag:j/n/4TI193ec3/mOJeB1Lg==,type:str] + plex: + encryption_passphrase: ENC[AES256_GCM,data:y4B7DMDgRRsz6CEL75b+uxNSrKxv/qUB2KZowbDc7PTThsbWwEyONry1QcpZgv2OIg==,iv:vh4s0/6IACrZE90KHtXh6N7LAErFqB5eiX75jjMjSm4=,tag:7v+VgyxJN/AhFQ0z/0PtCA==,type:str] + append_key: ENC[AES256_GCM,data:yV+yhmcpubOJU4o08gH/o30ZXBDlvpmj8GNFvUJS+lIq9miWENHQxcnHSdzOwnK8WRSTyiAYvYf8tpVaGDy3DPefHb3sqw7biq1+FEyh76Q9vR9XIiKMPguxRrmu8P5H2F3QJQM7us+6Qvx/xjyTvRQcSpiEATQ1iK6BAbLTbcZ96TrN+GlNUpJcAnhuMYTCzk9qxFpHap53t0jil4BVfGlDAAdWr59gLT87S3tn8YDobtX5LUp4AB8OeOgX6e24CF4LjrfrawwG1y90AoVO0AnhdM7kJ8Mq7JcJE+P0ecUUL5kc1dGdH8E5hrETmmt/iRIbuj/yzPNqrSF/R8JHtHAx0h+zqoiMk6/fjbdVPeTmzdTyLpLE4zVVRAGprdBot0jVuNsqvmJefIQISl83ox2RfbZFPsYvIlptOARI4oA+XuDC4QBiwIFVBTf6VrjsRbd1DbGbiRq6OoXmIqIt/zCEYWaVcI8srlaAHE02QbYOxCSBM2UNuTERajJ1pAJOXrRXPhwXMAT0xSv5rsAJlWzW6RkTYqUqZSqE,iv:XNUWjWEuTcA8HYkEvBuHcEunIm+/GdpOXNmAjBdeM5M=,tag:B/EoaqPXvTBN0H/UxJt5JQ==,type:str] + jellyfin: + encryption_passphrase: ENC[AES256_GCM,data:sXMIBWQpHxSyFBhvnOzkE8Qd97aWyCsd7zyVYef4WOXF,iv:qZCzQ582/myxyNDLof2RMzHtc8YeajYB1yF3KU/0DSo=,tag:3WhcEJLSxkpup6DsQqfN1Q==,type:str] + append_key: ENC[AES256_GCM,data:tgDQFEs1aCBJkWBepA921z+bb8WoLbiUAngOnQdP9vpJszBJNVlmVOPWt7hz4na+LFv4yRuGh22p7g9Dwdjd62BygicU9lc94SxOs593gZWbtgWKG95/wnxgfUTOSCGeV3JB6VjRwRh50IFwPx2DDr1bgoZqDqEJu6Mj+pUjVMCk+r8T/i79kdpryHq2gicnzHL62Deas+BmaHZremhQx4ety28qJb2WMMo7cYhUysJIal2ClOCwqeOo6OsHRGn1ZDpfxASdzXVK2qWArIcyt3XVChVv/znojaOQK9SiXQrdC4pgm8tn5OIlFH/e+f2K/EYzuShJWiOY8fbcx159OU5/OnQSNqHjBvuXulJ8WU4iMMJatOt5OqgNTK/I3e0xntnHozxVzqKSbQO0z2Ul2r4iJXAUI53oMB/iJON2fwEF1KEvW3iCmk0M1/t7AxqECsmAzfaz2lo9YNCS5iAbCYpEmRTHHMEi24/3as2mYwo4D0iKDV7J0988/BOSSXF04wVq+x7FKEOsIiuS70O1k8T75Uvw/I15DZZ2,iv:VMgaAHgipllx8V2i3hicTgxTVVmiy1AUgGICflrA254=,tag:2k9Z6wVbYVou/Vqk6f08+Q==,type:str] arr: prowlarr: apiKey: ENC[AES256_GCM,data:qxm2yp8ReuMgQ0155mKBAWickKusOaa/FeoIopj9l1Z3,iv:pAeDxK6CGap4fKU5xQ5hZR9It6/1uo27dKZBi5Bl3rc=,tag:HZl914AfFU4D5J7cDS3I1g==,type:str] @@ -135,8 +140,8 @@ sops: aVlOSHhFb2I5UnYwVytyQzlWTXBDYUUKdQKilmfJ1F7UYKtQV9zV95FcRIK17p4M vGvu/pGJ32tH8xI7cNs9I5Hmg9c5wOam21W1FDk+VlJ/ClXqQzS0MA== -----END AGE ENCRYPTED FILE----- - lastmodified: "2025-02-24T21:27:42Z" - mac: ENC[AES256_GCM,data:5E9adS+q+Vb45MtKDuI65GaKxb/yksqSN73ZFHYhdL+w6Lk4/WPd9n7qTENKfFkYN2qIRP3S4IQUBwobep4wiEQt4v8XdNN7gR7cgI/2u4y/iKptyv/YWyj+YYfFaZjJ6lqxod3MAq92L4xYq+91aKoWEW/ErpDy8N3xOe7GI6U=,iv:WGWCD9pfu7ijiDXhcV26j7XpFl5dVglWZeMVQFyFUSA=,tag:PP4yI+iLaaPLG0YoI19zTQ==,type:str] + lastmodified: "2025-02-25T16:50:35Z" + mac: ENC[AES256_GCM,data:OEEAQJU39Io0yfPyDZTiH0MpIZz6qtEgQLSl02ysnHm3wSoAcD2LVDGadm2nqozCZ8FrYiO1p0iP/zE/WAMB7VPjGB2fkoLgKUcjMX5RP+RHREA5eIPl9anlbXh8uAFNiw/unOH36PlqivpoYoxDoc9EqSX6df14v6+gkr/9/gM=,iv:rQfEeKvJ73dyy/mIpg2QvcV5qZHM9DpHJ7lfsHJw5q8=,tag:fdPsnuHt1/cjgjtZ5UIbtw==,type:str] pgp: [] unencrypted_suffix: _unencrypted version: 3.9.4 diff --git a/nixos/lib/default.nix b/nixos/lib/default.nix index c0c209c..a20e2c8 100644 --- a/nixos/lib/default.nix +++ b/nixos/lib/default.nix @@ -20,9 +20,9 @@ with lib; rec { user = existsOrDefault "user" options "568"; group = existsOrDefault "group" options "568"; - enableBackups = - (lib.attrsets.hasAttrByPath ["persistence" "folder"] options) - && (lib.attrsets.attrByPath ["persistence" "enable"] true options); + # enableBackups = + # (lib.attrsets.hasAttrByPath ["persistence" "folder"] options) + # && (lib.attrsets.attrByPath ["persistence" "enable"] true options); # Security options for containers containerExtraOptions = diff --git a/nixos/modules/nixos/containers/jellyfin/default.nix b/nixos/modules/nixos/containers/jellyfin/default.nix index a417b99..9d690c6 100644 --- a/nixos/modules/nixos/containers/jellyfin/default.nix +++ b/nixos/modules/nixos/containers/jellyfin/default.nix @@ -88,37 +88,6 @@ in { ]; }; - sops.secrets = { - "restic/jellyfin/env" = { - inherit group; - sopsFile = ./secrets.sops.yaml; - owner = user; - mode = "0400"; - }; - "restic/jellyfin/password" = { - inherit group; - sopsFile = ./secrets.sops.yaml; - owner = user; - mode = "0400"; - }; - "restic/jellyfin/template" = { - inherit group; - sopsFile = ./secrets.sops.yaml; - owner = user; - mode = "0400"; - }; - }; - - # Restic backups for `jellyfin-local` and `jellyfin-remote` - services.restic.backups = config.lib.mySystem.mkRestic { - inherit app user; - environmentFile = config.sops.secrets."restic/jellyfin/env".path; - excludePaths = []; - localResticTemplate = "/eru/restic/jellyfin"; - passwordFile = config.sops.secrets."restic/jellyfin/password".path; - paths = [volumeLocation]; - remoteResticTemplateFile = config.sops.secrets."restic/jellyfin/template".path; - }; # TODO add nginx proxy # services.nginx.virtualHosts."${app}.${config.networking.domain}" = { # useACMEHost = config.networking.domain; diff --git a/nixos/modules/nixos/containers/plex/default.nix b/nixos/modules/nixos/containers/plex/default.nix index a774354..254e667 100644 --- a/nixos/modules/nixos/containers/plex/default.nix +++ b/nixos/modules/nixos/containers/plex/default.nix @@ -41,7 +41,6 @@ in { ${pkgs.podman}/bin/podman rm -f ${app} || true rm -f /run/${app}.ctr-id ''}"; - # TODO: mount /config instead of /config/Library/Application Support/Plex Media Server ExecStart = '' ${pkgs.podman}/bin/podman run \ --rm \ @@ -80,38 +79,6 @@ in { ]; }; - sops.secrets = { - "restic/plex/env" = { - inherit group; - sopsFile = ./secrets.sops.yaml; - owner = user; - mode = "0400"; - }; - "restic/plex/password" = { - inherit group; - sopsFile = ./secrets.sops.yaml; - owner = user; - mode = "0400"; - }; - "restic/plex/template" = { - inherit group; - sopsFile = ./secrets.sops.yaml; - owner = user; - mode = "0400"; - }; - }; - - # Restic backups for `plex-local` and `plex-remote` - services.restic.backups = config.lib.mySystem.mkRestic { - inherit app user; - environmentFile = config.sops.secrets."restic/plex/env".path; - excludePaths = ["${volumeLocation}/Library/Application Support/Plex Media Server/Cache"]; - localResticTemplate = "/eru/restic/plex"; - passwordFile = config.sops.secrets."restic/plex/password".path; - paths = ["${volumeLocation}/Library"]; - remoteResticTemplateFile = config.sops.secrets."restic/plex/template".path; - }; - # TODO add nginx proxy # services.nginx.virtualHosts."${app}.${config.networking.domain}" = { # useACMEHost = config.networking.domain; diff --git a/nixos/modules/nixos/containers/plex/secrets.sops.yaml b/nixos/modules/nixos/containers/plex/secrets.sops.yaml deleted file mode 100644 index 6078324..0000000 --- a/nixos/modules/nixos/containers/plex/secrets.sops.yaml +++ /dev/null @@ -1,88 +0,0 @@ -restic: - plex: - env: ENC[AES256_GCM,data:FwBQ9TJTiDGDEyrJkHo=,iv:pxqdwOPoxYAc+yY2xdNTi08jFNz+PvnZ9HYhmchEfiM=,tag:3uIPLUoZmDogmuShXqnAlw==,type:str] - password: ENC[AES256_GCM,data:79FMf5T1gYQX0PYTiEUhPQnHbEIekmH2vJxqwhdCw1MpoA==,iv:n3cQ4cLoEKw7rbCgysc14CMmKtYUfhZW2I6V3qrFp3Q=,tag:ooNflv+TnUOD0JX6NAqxvQ==,type:str] - template: ENC[AES256_GCM,data:br+HPd37B3rWYPLIYW8MiIHvR+PmsnBXEYLh8MT/v1rbcNH6ppyhwGMgP1kPkUX3o/0Y7PkW1pet5DRHcKUVnXpi,iv:O4MQQBpYCD8hkdTEroUn9+luUdCyz7MYUugjaYhF3Uc=,tag:db5DQBfPGX9ToQzwn1K7GA==,type:str] -sops: - kms: [] - gcp_kms: [] - azure_kv: [] - hc_vault: [] - age: - - recipient: age1d9p83j52m2xg0vh9k7q0uwlxwhs3y6tlv68yg9s2h9mdw2fmmsqshddz5m - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBCbSs2TFBpbW51aThtcEJL - eW80aG50VHJzcWVFSDlTbE40dHZqTnVpWDFBCkUwNVIrZkdyd1dKcjFzMENFdTN5 - dVBZKzVIYnFJdnkzTlRCT2hITTVsSzgKLS0tIFREVWJENUtoWGR1THlwWXNNV3p4 - cElGSzFtallzc2xBajRYSGNvOHJnM3cKIdyVG7MySM9caGUXaiTSsz1VVlD7GxRz - +5NNPoZgfe1SiptiQl3vO8FcIg5XtutI2nwYqLK5gzxZ7x6+D2Oedw== - -----END AGE ENCRYPTED FILE----- - - recipient: age1m83ups8xn2jy4ayr8gw0pyn34smr0huqc5v76e4887az4vsl4yzsj0dlhd - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA3dFAxT3ZCZ1BlV2VSQmlr - cW9SbWpLRUE4QlNGN21YdGM2NXhGdm1kVmlZClBORG5Mbmtaait4WXZiYkp3cGxR - WGFWT3NwaS9RK0IzN1FDR3ZWUjIyQVkKLS0tIDJYaVRORk94UXYySStUN0lJYlB5 - L01LdFBzYUhmcENPMGIrYWU0dW91c2sKlraBMZ30AerY2YrGnV1pkeL6xJIGUPlX - JzjzPmkvqidCaT+gADxM9xTp9S5ZavLn0sGLapqfx2P7pDndRh74Qg== - -----END AGE ENCRYPTED FILE----- - - recipient: age18kj3xhlvgjeg2awwku3r8d95w360uysu0w5ejghnp4kh8qmtge5qwa2vjp - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtanl6bWlrQlM2R1Bud0dk - cWJZdjJZUFVMY3BudEdRVVFOMy9IMTNGS1NzCnZHNXYzRVl5akFDYlNWVXZtMzNL - UnZEN3ZFUDB6b05Wa3lSc291WXVVeGMKLS0tIGk5ZTJ6d3A4M3ZqTm9KSjVudVBX - TzNNemlGc1JOckxERUx5V3VCbHBIZlkK+7+PJhU+4hnOiURvfhQOMh3Njl5E8OCj - CCH5feYLIOpfgEKQbhW8LFkakoqlU5ASdralMRq5h4OZt8hGciYgwg== - -----END AGE ENCRYPTED FILE----- - - recipient: age1lp6rrlvmytp9ka6q89m0e0am26222kwrn7aqd45hu07s3a6jv3gqty86eu - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA3VFovdW1UbjlLZnRFZWZh - MUg0RkZqckcxcENRSG5aSkdQNkoraXFTbTNrCnlYWWVOdHVxYUwwaWYvOS8xaG9y - eS9za000VmR0T0ZZeHp5RXl0c1FUZDgKLS0tIERjY0hrdDlQb29UWC8ybDgwdXQy - WEVNVjBYV3RUZUN2SksvWDlzYnJydWcKEzXYhd0GUZNDdQcJ1lc5Ci4TAebQHzdd - Nyrf7Xhgb/vNoScFAvLxpJaEP9aJzWOL7wVHgnzFdf9ViRGF0yynnw== - -----END AGE ENCRYPTED FILE----- - - recipient: age1e4sd6jjd4uxxsh9xmhdsnu6mqd5h8c4zz4gwme7lkw9ee949fc9q4px9df - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwU3JKelJlUUZxRi90RmRP - VUpoYXZaQlZpaEZiL3orb2Rva3U4TkZ2TDBVCmpwQXFtUHlicHh0S2h3TUN0U2dE - MXIrcUdhbWZLdFdhRnB1YkhDL2JkV3cKLS0tIFdCZWVmMytST3dHVG5LL1duckRj - alZDNkYxVnljUk9Gc25vVElPL0RXSDQKM84i+oIeivQFSIDBhT9Gg3XHk8GFRbzO - IwUrRIkj+yDKepz+r2Lc+yD2BOeFo+CNuReoJd2SGou7e628VysB4g== - -----END AGE ENCRYPTED FILE----- - - recipient: age19jm7uuam7gkacm3kh2v7uqgkvmmx0slmm9zwdjhd2ln9r60xzd7qh78c5a - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzRE5UbGxUenRZVjU2NVF6 - RHNUOXJ5bnJmdm13YTNKV1YwdFdJS3JpMTBrCkRNQWNiMXp4SHZ6bGdJay9pYjgr - UW1CSVRNMFFWNjA5YSttTHBGTWpCcE0KLS0tIDBUV25tdUZHbHpIb3Y1U281dGtl - bUNHazJDUnEwc015WXlybTdEK1RHL1UKZE/5YGvUN2tR1t7s/Lq1jG3FoMIOmKDK - GXwUQb1HG7PDG9V/pKWs9OVoFxv7qVuuBm29rRnI44pEERARtbs55Q== - -----END AGE ENCRYPTED FILE----- - - recipient: age1nwnqxjuaxlt5g7fe8rnspvn2c36uuef4hzwuwa6cfjfalz2lrd4q4n5fpl - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBBWHBEUDNuRDhVMmp4QUYr - cCtmZ2RMWVFNWVhVck44U3ROTE8xNm9kV0Y4CktSelh0ckdQZHNTVnVsVXJweUly - UmphNzRJU3JOSThQVXB3ZXRlY3BOK1UKLS0tIG1nT09WUm1YcVFJRHZyWFJOKzZx - OTFDbExmeXBBWmRjSE5BUnpGY0xLRjAKnLWKZEmlI9SsfZgus7tuCOFzokDobz8F - s7zQ078Dv7R55EPoYPfq8rsMvFpELrAqrNLAR9x4W5YledBDJV8s+A== - -----END AGE ENCRYPTED FILE----- - - recipient: age1a8z3p24v32l9yxm5z2l8h7rpc3nhacyfv4jvetk2lenrvsdstd3sdu2kaf - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNRSttM1NDdFJib2FleTY0 - UnkrUFhBUFlWNkxEZUNLMjVTUWh4VkhPbkY4CllRY3d0ZXpGRkM0ZG45TVE5SGx3 - ek9BNW9SUGVLZjRiSkVlT2MrSU85VGsKLS0tIEtlcklOOXZldUJwZmVDaWhNeFh2 - RDgrMDlLVm9rN2JRZ3gxSCtxOWlhWkEKkXtZtmXnRn1ukRI4CkjkYefyGOuCw+GC - HCKKdsASQm4JjcnlUbkL97bC0H+VcLNqHm6NR9dghI9IYuYAeLqMNA== - -----END AGE ENCRYPTED FILE----- - lastmodified: "2024-12-27T09:27:41Z" - mac: ENC[AES256_GCM,data:OU23F2vdLKE2aas9xUsx5cmObBmdqybXSfdUT+BGd/mdhThF6vNR3Xwo4PcaK8VPmQ8JmXjOUJ/A9vKvcgz1LuEywgAacayDf6TUu1yXPDm09wFwWGTAYugy2Z54a0VQ8u7Cu/4Ijx0hU0luaYsbCyr7FmKgeO+H+L47JKnrPp8=,iv:dowA2KQqSjNIoPq1A0Yv9g71FSJgey5mMQMuJJMSSWA=,tag:eJrk49soG6dA8UilhuKGaw==,type:str] - pgp: [] - unencrypted_suffix: _unencrypted - version: 3.9.1 diff --git a/nixos/modules/nixos/lib.nix b/nixos/modules/nixos/lib.nix index 6cfd4a0..2c362c0 100644 --- a/nixos/modules/nixos/lib.nix +++ b/nixos/modules/nixos/lib.nix @@ -77,10 +77,10 @@ # - nextcloud-remote: backs up to remote storage (e.g. S3) lib.mySystem.mkRestic = options: let # excludePaths is optional - excludePaths = - if builtins.hasAttr "excludePaths" options - then options.excludePaths - else []; + # excludePaths = + # if builtins.hasAttr "excludePaths" options + # then options.excludePaths + # else []; # Decide which mutually exclusive options to use remoteResticTemplateFile = if builtins.hasAttr "remoteResticTemplateFile" options diff --git a/nixos/modules/nixos/services/borgmatic/default.nix b/nixos/modules/nixos/services/borgmatic/default.nix new file mode 100644 index 0000000..f841281 --- /dev/null +++ b/nixos/modules/nixos/services/borgmatic/default.nix @@ -0,0 +1,141 @@ +{ + config, + lib, + pkgs, + myPkgs, + ... +}: +with lib; let + cfg = config.mySystem.services.borgmatic; + settingsFormat = pkgs.formats.yaml {}; + + repository = with types; + submodule { + options = { + path = mkOption { + type = str; + description = '' + Path to the repository + ''; + }; + label = mkOption { + type = str; + description = '' + Label to the repository + ''; + }; + }; + }; + cfgType = with types; + submodule { + freeformType = settingsFormat.type; + options = { + source_directories = mkOption { + type = listOf str; + default = []; + description = '' + List of source directories and files to backup. Globs and tildes are + expanded. Do not backslash spaces in path names. + ''; + example = [ + "/home" + "/etc" + "/var/log/syslog*" + "/home/user/path with spaces" + ]; + }; + repositories = mkOption { + type = listOf repository; + default = []; + description = '' + A required list of local or remote repositories with paths and + optional labels (which can be used with the --repository flag to + select a repository). Tildes are expanded. Multiple repositories are + backed up to in sequence. Borg placeholders can be used. See the + output of "borg help placeholders" for details. See ssh_command for + SSH options like identity file or port. If systemd service is used, + then add local repository paths in the systemd service file to the + ReadWritePaths list. + ''; + example = [ + { + path = "ssh://user@backupserver/./sourcehostname.borg"; + label = "backupserver"; + } + { + path = "/mnt/backup"; + label = "local"; + } + ]; + }; + }; + }; + + cfgfile = settingsFormat.generate "config.yaml" cfg.settings; +in { + options.mySystem.services.borgmatic = { + enable = mkEnableOption "borgmatic"; + + settings = mkOption { + description = '' + See https://torsion.org/borgmatic/docs/reference/configuration/ + ''; + default = null; + type = types.nullOr cfgType; + }; + + configurations = mkOption { + description = '' + Set of borgmatic configurations, see https://torsion.org/borgmatic/docs/reference/configuration/ + ''; + default = {}; + type = types.attrsOf cfgType; + }; + + enableConfigCheck = + mkEnableOption "checking all configurations during build time" + // { + default = true; + }; + }; + + config = let + configFiles = + (optionalAttrs (cfg.settings != null) {"borgmatic/config.yaml".source = cfgfile;}) + // mapAttrs' ( + name: value: + nameValuePair "borgmatic.d/${name}.yaml" {source = settingsFormat.generate "${name}.yaml" value;} + ) + cfg.configurations; + borgmaticCheck = name: f: + pkgs.runCommandCC "${name} validation" {} '' + ${myPkgs.borgmatic}/bin/borgmatic -c ${f.source} config validate + touch $out + ''; + in + mkIf cfg.enable { + warnings = + [] + ++ optional (cfg.settings != null && cfg.settings ? location) + "`services.borgmatic.settings.location` is deprecated, please move your options out of sections to the global scope" + ++ optional (catAttrs "location" (attrValues cfg.configurations) != []) + "`services.borgmatic.configurations..location` is deprecated, please move your options out of sections to the global scope"; + + environment.systemPackages = [ + myPkgs.borgmatic + pkgs.borgbackup + ]; + + environment.etc = configFiles; + + systemd.packages = [ + myPkgs.borgmatic + pkgs.borgbackup + ]; + + # Workaround: https://github.com/NixOS/nixpkgs/issues/81138 + systemd.timers.borgmatic.wantedBy = ["timers.target"]; + + system.checks = mkIf cfg.enableConfigCheck (mapAttrsToList borgmaticCheck configFiles); + }; +} diff --git a/nixos/modules/nixos/services/default.nix b/nixos/modules/nixos/services/default.nix index cad1fa4..fd68c9e 100644 --- a/nixos/modules/nixos/services/default.nix +++ b/nixos/modules/nixos/services/default.nix @@ -1,5 +1,6 @@ { imports = [ + ./borgmatic ./bind ./dnsmasq ./forgejo diff --git a/nixos/packages/borgmatic/default.nix b/nixos/packages/borgmatic/default.nix index f30576b..8884746 100644 --- a/nixos/packages/borgmatic/default.nix +++ b/nixos/packages/borgmatic/default.nix @@ -2,6 +2,7 @@ lib, python3, fetchFromGitHub, + installShellFiles, }: python3.pkgs.buildPythonApplication rec { pname = "borgmatic"; @@ -19,6 +20,8 @@ python3.pkgs.buildPythonApplication rec { python3.pkgs.setuptools ]; + nativeBuildInputs = [installShellFiles]; + dependencies = with python3.pkgs; [ jsonschema packaging @@ -36,6 +39,13 @@ python3.pkgs.buildPythonApplication rec { "borgmatic" ]; + postInstall = '' + installShellCompletion --cmd borgmatic \ + --bash <($out/bin/borgmatic --bash-completion) + # installShellCompletion --cmd borgmatic \ + # --fish <($out/bin/borgmatic --fish-completion | sed '20d) + ''; + meta = { description = "Simple, configuration-driven backup software for servers and workstations"; homepage = "https://github.com/borgmatic-collective/borgmatic/";