From ad5c4453373374d99af92e7bdf601ff56f6b2e6e Mon Sep 17 00:00:00 2001 From: Amolith Date: Thu, 19 Mar 2026 11:17:43 -0600 Subject: [PATCH] Update examples and docs for path-based repos and _COMMAND Rework examples/keld/config.toml to demonstrate: - Path-based repository URLs for rclone and S3 backends - _COMMAND environ for credential injection (B2 and rclone) - BorgBase per-repo presets with randomized example creds Rename example timer env files to _backup/_integrity suffixes. Rename keld-verify to keld-integrity with --read-data for monthly full data verification; daily backup unit now chains backup && check. Add FOO_COMMAND to the special config keys table in AGENTS.md. --- AGENTS.md | 13 +++-- examples/keld/config.toml | 57 +++++++++++++++---- ...ia.env => media@borgbase_media_backup.env} | 0 ...env => media@borgbase_media_integrity.env} | 0 4 files changed, 53 insertions(+), 17 deletions(-) rename examples/keld/timers/{media@rest_repo_media.env => media@borgbase_media_backup.env} (100%) rename examples/keld/timers/{media@rest_repo_media-verify.env => media@borgbase_media_integrity.env} (100%) diff --git a/AGENTS.md b/AGENTS.md index 6fa385cdcc6e9270a3d9adbaa73ee87fd8dea4b9..f2ebd6bb882a35c677a71cac50617be411f4e252 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -56,12 +56,13 @@ CLI overrides ### Special Config Keys -| Key | Purpose | -| ------------ | ------------------------------------------------------------------ | -| `_arguments` | Positional args passed to restic (array or space-separated string) | -| `_workdir` | Directory to chdir before exec | -| `_command` | Restic subcommand (allows aliasing) | -| `*.environ` | Section suffix for environment variables | +| Key | Purpose | +| ---------------- | ------------------------------------------------------------------ | +| `_arguments` | Positional args passed to restic (array or space-separated string) | +| `_workdir` | Directory to chdir before exec | +| `_command` | Restic subcommand (allows aliasing) | +| `*.environ` | Section suffix for environment variables | +| `FOO_COMMAND` | In `.environ`: executed via `sh -c`, stdout sets `FOO` | ### Interpolation diff --git a/examples/keld/config.toml b/examples/keld/config.toml index 8ad775286f989596e5945e3c6572f2e56a5c91a9..949f017321053008c647145533dd5bee3f511b83 100644 --- a/examples/keld/config.toml +++ b/examples/keld/config.toml @@ -1,21 +1,56 @@ [global.backup] exclude-if-present = ".nobackup" +# ── Credentials (shared per backend) ───────────────────────── +# +# Suffix sections define the "where" — backend-specific settings shared +# by every preset that targets this backend. Because S3/B2 credentials +# apply to the whole account, they live here once. + +# Keys ending in _COMMAND are executed by keld; stdout (with trailing +# newlines stripped) becomes the env var with the suffix removed. +# This keeps secrets out of config files entirely. +# +# rclone credentials can be supplied the same way via env vars named +# RCLONE_CONFIG__. Remote names must use underscores, not +# hyphens. Passwords must be piped through `rclone obscure -`. +["@hetzner".environ] +RCLONE_CONFIG_HETZNER_RESTIC_USER_COMMAND = "op read 'op://Vault/Hetzner Storage Box/username'" +RCLONE_CONFIG_HETZNER_RESTIC_PASS_COMMAND = "op read 'op://Vault/Hetzner Storage Box/password' | rclone obscure -" + +["@b2".environ] +AWS_ACCESS_KEY_ID_COMMAND = "op read 'op://Vault/B2/access-key-id'" +AWS_SECRET_ACCESS_KEY_COMMAND = "op read 'op://Vault/B2/secret-access-key'" + +# ── What to back up ────────────────────────────────────────── +# +# Prefix sections define the "what" — sources, excludes, tags, and the +# restic encryption password. The password is per-prefix so each dataset +# gets its own encryption key, even when stored on the same backend. + ["media@".environ] -RESTIC_PASSWORD_COMMAND = "op read 'op://Example Vault/Media Backup/password'" +RESTIC_PASSWORD_COMMAND = "op read 'op://Vault/Media Backup/password'" ["media@".backup] -_arguments = "/home/example/Music/Final" +_arguments = ["/home/user/Music/Final"] + +# ── Where to back up ───────────────────────────────────────── +# +# Full preset sections combine prefix + suffix and set the repository +# path within each backend. Restic supports paths inside a single +# rclone remote or S3 bucket, so you don't need a separate remote or +# bucket per dataset. -["media@hetzner_media"] -repository = "rclone:hetzner-restic-media:/" +["media@hetzner"] +repository = "rclone:hetzner_restic:/media" -["media@b2_media"] -repository = "s3:https://s3.us-west-004.backblazeb2.com/example-bucket-id" +["media@b2"] +repository = "s3:https://s3.us-west-004.backblazeb2.com/fe0ae843eb0e5fb6/media" -["media@b2_media".environ] -AWS_ACCESS_KEY_ID = "B2_EXAMPLE_ACCESS_KEY_ID" -AWS_SECRET_ACCESS_KEY = "B2_EXAMPLE_SECRET_ACCESS_KEY" +# BorgBase provides per-repository URLs with embedded credentials, so +# each BorgBase repo is specific to a single dataset — there's no shared +# @borgbase suffix to reuse. Use a plain preset name (no @) or keep the +# split form to inherit the prefix's _arguments and password settings. -["media@rest_repo_media"] -repository = "rest:https://example-user:example-password@example.repo.borgbase.com" +["media@borgbase_media"] +repository = "rest:https://d6c83eee:e5ffbc1195c714996205@d6c83eee.repo.borgbase.com" diff --git a/examples/keld/timers/media@rest_repo_media.env b/examples/keld/timers/media@borgbase_media_backup.env similarity index 100% rename from examples/keld/timers/media@rest_repo_media.env rename to examples/keld/timers/media@borgbase_media_backup.env diff --git a/examples/keld/timers/media@rest_repo_media-verify.env b/examples/keld/timers/media@borgbase_media_integrity.env similarity index 100% rename from examples/keld/timers/media@rest_repo_media-verify.env rename to examples/keld/timers/media@borgbase_media_integrity.env