restic-profile-cli 0.2.1__tar.gz → 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/.github/workflows/docs.yaml +2 -2
  2. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/AGENTS.md +2 -2
  3. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/CHANGELOG.md +12 -0
  4. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/PKG-INFO +4 -2
  5. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/README.md +3 -1
  6. restic_profile_cli-0.3.0/README.zh-CN.md +67 -0
  7. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/docs/index.md +1 -1
  8. restic_profile_cli-0.3.0/docs/index.zh.md +65 -0
  9. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/docs/restic-profile/cli.md +1 -1
  10. restic_profile_cli-0.3.0/docs/restic-profile/cli.zh.md +65 -0
  11. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/docs/restic-profile/examples.md +40 -0
  12. restic_profile_cli-0.3.0/docs/restic-profile/examples.zh.md +307 -0
  13. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/docs/restic-profile/toml-config.md +2 -1
  14. restic_profile_cli-0.3.0/docs/restic-profile/toml-config.zh.md +190 -0
  15. restic_profile_cli-0.3.0/docs/restic-rest-server.zh.md +85 -0
  16. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/galaxy.yml +3 -2
  17. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/justfile +5 -5
  18. restic_profile_cli-0.3.0/mkdocs.yml +54 -0
  19. restic_profile_cli-0.3.0/plugins/filter/restic_profile.py +386 -0
  20. restic_profile_cli-0.3.0/plugins/modules/systemd_timer_state.py +154 -0
  21. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/pyproject.toml +1 -1
  22. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/roles/restic_profile/defaults/main.yaml +40 -37
  23. restic_profile_cli-0.3.0/roles/restic_profile/tasks/_config_target.yaml +148 -0
  24. restic_profile_cli-0.3.0/roles/restic_profile/tasks/_remove_target.yaml +86 -0
  25. restic_profile_cli-0.3.0/roles/restic_profile/tasks/_service_target.yaml +170 -0
  26. restic_profile_cli-0.3.0/roles/restic_profile/tasks/cleanup_orphans.yaml +11 -0
  27. restic_profile_cli-0.3.0/roles/restic_profile/tasks/config.yaml +7 -0
  28. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/roles/restic_profile/tasks/hooks_phase.yaml +4 -4
  29. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/roles/restic_profile/tasks/main.yaml +7 -0
  30. restic_profile_cli-0.3.0/roles/restic_profile/tasks/persist_registry.yaml +21 -0
  31. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/roles/restic_profile/tasks/preflight.yaml +74 -1
  32. restic_profile_cli-0.3.0/roles/restic_profile/tasks/remove.yaml +31 -0
  33. restic_profile_cli-0.3.0/roles/restic_profile/tasks/service.yaml +7 -0
  34. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/roles/restic_profile/templates/etc/restic-profile/restic-profile.env.j2 +2 -2
  35. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/roles/restic_profile/templates/etc/restic-profile/restic-profile.toml.j2 +2 -0
  36. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/roles/restic_profile/templates/etc/systemd/system/restic-profile.service.j2 +4 -4
  37. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/roles/restic_profile/templates/etc/systemd/system/restic-profile.timer.j2 +4 -4
  38. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/roles/restic_profile/vars/main.yaml +5 -0
  39. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/src/restic_profile/cli.py +28 -2
  40. restic_profile_cli-0.3.0/tests/restic_profile/test_filters.py +532 -0
  41. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/uv.lock +171 -83
  42. restic_profile_cli-0.2.1/roles/restic_profile/tasks/config.yaml +0 -189
  43. restic_profile_cli-0.2.1/roles/restic_profile/tasks/remove.yaml +0 -91
  44. restic_profile_cli-0.2.1/roles/restic_profile/tasks/service.yaml +0 -141
  45. restic_profile_cli-0.2.1/zensical.toml +0 -42
  46. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/.ansible-lint +0 -0
  47. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/.copier-answers.yaml +0 -0
  48. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/.devcontainer/devcontainer.json +0 -0
  49. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/.dockerignore +0 -0
  50. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/.editorconfig +0 -0
  51. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/.github/workflows/publish-to-pypi.yaml +0 -0
  52. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/.github/workflows/publish-to-test-pypi.yaml +0 -0
  53. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/.gitignore +0 -0
  54. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/.pre-commit-config.yaml +0 -0
  55. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/.prettierignore +0 -0
  56. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/.yamlfmt.yaml +0 -0
  57. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/Dockerfile +0 -0
  58. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/LICENSE +0 -0
  59. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/ansible.cfg +0 -0
  60. /restic_profile_cli-0.2.1/docs/restic-rest-server/index.md → /restic_profile_cli-0.3.0/docs/restic-rest-server.md +0 -0
  61. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/meta/runtime.yml +0 -0
  62. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/playbooks/go_build/restic-rest-server.yaml +0 -0
  63. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/playbooks/go_build/restic.yaml +0 -0
  64. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/playbooks/restic-profile.yaml +0 -0
  65. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/playbooks/restic-rest-server.yaml +0 -0
  66. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/requirements.yml +0 -0
  67. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/roles/restic_profile/handlers/main.yaml +0 -0
  68. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/roles/restic_profile/meta/main.yaml +0 -0
  69. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/roles/restic_profile/molecule/default/converge.yaml +0 -0
  70. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/roles/restic_profile/molecule/default/molecule.yaml +0 -0
  71. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/roles/restic_profile/molecule/default/prepare.yaml +0 -0
  72. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/roles/restic_profile/molecule/default/verify.yaml +0 -0
  73. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/roles/restic_profile/tasks/hooks.yaml +0 -0
  74. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/roles/restic_profile/tasks/install.yaml +0 -0
  75. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/roles/restic_profile/templates/usr/local/bin/restic-profile-scope.j2 +0 -0
  76. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/roles/restic_rest_server/defaults/main.yaml +0 -0
  77. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/roles/restic_rest_server/files/users.htpasswd +0 -0
  78. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/roles/restic_rest_server/handlers/main.yaml +0 -0
  79. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/roles/restic_rest_server/meta/main.yaml +0 -0
  80. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/roles/restic_rest_server/tasks/install.yaml +0 -0
  81. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/roles/restic_rest_server/tasks/main.yaml +0 -0
  82. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/roles/restic_rest_server/tasks/service.yaml +0 -0
  83. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/roles/restic_rest_server/tasks/validation.yaml +0 -0
  84. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/roles/restic_rest_server/templates/restic-rest-server.default.j2 +0 -0
  85. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/roles/restic_rest_server/templates/restic-rest-server.service.j2 +0 -0
  86. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/ruff.toml +0 -0
  87. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/src/restic_profile/__init__.py +0 -0
  88. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/src/restic_profile/__main__.py +0 -0
  89. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/src/restic_profile/config.py +0 -0
  90. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/src/restic_profile/notify.py +0 -0
  91. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/src/restic_profile/runner.py +0 -0
  92. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/src/restic_profile/templates/notify_failure.md.j2 +0 -0
  93. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/src/restic_profile/templates/notify_success.md.j2 +0 -0
  94. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/tests/restic_profile/conftest.py +0 -0
  95. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/tests/restic_profile/test_cli.py +0 -0
  96. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/tests/restic_profile/test_config.py +0 -0
  97. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/tests/restic_profile/test_notify.py +0 -0
  98. {restic_profile_cli-0.2.1 → restic_profile_cli-0.3.0}/tests/restic_profile/test_runner.py +0 -0
@@ -9,7 +9,7 @@ on:
9
9
  paths:
10
10
  - "docs/**"
11
11
  - "README.md"
12
- - "zensical.toml"
12
+ - "mkdocs.yml"
13
13
  - ".github/workflows/docs.yaml"
14
14
 
15
15
  permissions:
@@ -39,7 +39,7 @@ jobs:
39
39
  run: uv sync --locked --group docs
40
40
 
41
41
  - name: Build documentation
42
- run: uv run zensical build
42
+ run: NO_MKDOCS_2_WARNING=1 uv run mkdocs build
43
43
 
44
44
  - name: Upload artifact
45
45
  uses: actions/upload-pages-artifact@v4
@@ -9,12 +9,12 @@ setup, usage, and the development workflow.
9
9
  ## Environment & Tooling - CRITICAL
10
10
 
11
11
  - Environment manager: **uv**. Sync with `uv sync --group dev`.
12
- - Lint & format: **ruff**. Run `just lint` (or `uv run ruff check --fix src/ tests/` then `uv run ruff format src/ tests/`).
12
+ - Lint & format: **ruff**. Run `just lint` (or `uv run ruff check --fix src/ tests/ plugins/` then `uv run ruff format src/ tests/ plugins/`).
13
13
  - Type check: **ty** (`astral-sh/ty`). Run `just typecheck`.
14
14
  - Test runner: **pytest** (`uv run pytest -v tests/` or `just test`).
15
15
  - Ansible lint: `ansible-lint` (global install, see `README.md`).
16
16
  - Build: `uv build -v` (or `just build`).
17
- - Docs: `uv run zensical build` (or `just docs-build`).
17
+ - Docs: `uv run mkdocs build` (or `just docs-build`).
18
18
 
19
19
  You MUST NOT use `pip`, `poetry`, `pipenv`, `mypy`, `black`, `flake8`, `isort`,
20
20
  or `mkdocs` directly. All Python tooling flows through **uv** and **ruff**/**ty**.
@@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.3.0] - 2026-07-13
9
+
10
+ ### Added
11
+
12
+ - Per-profile systemd user-scope support via `systemd_scope: user` and
13
+ `systemd_user` fields — deploys config to `~/.config/restic-profile/`
14
+ and systemd units to `~/.config/systemd/user/` with automatic
15
+ `loginctl enable-linger` and `XDG_RUNTIME_DIR` handling
16
+ - CLI config resolution via XDG search path — when `--config` is omitted,
17
+ searches `~/.config/restic-profile/restic-profile.toml` then falls back
18
+ to `/etc/restic-profile/restic-profile.toml`
19
+
8
20
  ## [0.2.1] - 2026-07-07
9
21
 
10
22
  ### Fixed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: restic-profile-cli
3
- Version: 0.2.1
3
+ Version: 0.3.0
4
4
  Summary: Profile-based restic wrapper with Ansible deployment support
5
5
  Project-URL: Homepage, https://github.com/ak1ra-lab/restic-profile
6
6
  Project-URL: Repository, https://github.com/ak1ra-lab/restic-profile
@@ -24,6 +24,8 @@ Description-Content-Type: text/markdown
24
24
 
25
25
  # restic-profile
26
26
 
27
+ **English** | [简体中文](README.zh-CN.md)
28
+
27
29
  [![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/ak1ra-lab/restic-profile/.github%2Fworkflows%2Fpublish-to-pypi.yaml)](https://github.com/ak1ra-lab/restic-profile/actions/workflows/publish-to-pypi.yaml)
28
30
  [![PyPI - Version](https://img.shields.io/pypi/v/restic-profile-cli)](https://pypi.org/project/restic-profile-cli/)
29
31
  [![PyPI - Version](https://img.shields.io/pypi/v/restic-profile-cli?label=test-pypi&pypiBaseUrl=https%3A%2F%2Ftest.pypi.org)](https://test.pypi.org/project/restic-profile-cli/)
@@ -87,4 +89,4 @@ ansible-lint
87
89
 
88
90
  ## Documentation
89
91
 
90
- The published documentation site lives at <https://ak1ra-lab.github.io/restic-profile/>, and local docs configuration is stored in `zensical.toml`.
92
+ The published documentation site lives at <https://ak1ra-lab.github.io/restic-profile/>, and local docs configuration is stored in `mkdocs.yml`.
@@ -1,5 +1,7 @@
1
1
  # restic-profile
2
2
 
3
+ **English** | [简体中文](README.zh-CN.md)
4
+
3
5
  [![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/ak1ra-lab/restic-profile/.github%2Fworkflows%2Fpublish-to-pypi.yaml)](https://github.com/ak1ra-lab/restic-profile/actions/workflows/publish-to-pypi.yaml)
4
6
  [![PyPI - Version](https://img.shields.io/pypi/v/restic-profile-cli)](https://pypi.org/project/restic-profile-cli/)
5
7
  [![PyPI - Version](https://img.shields.io/pypi/v/restic-profile-cli?label=test-pypi&pypiBaseUrl=https%3A%2F%2Ftest.pypi.org)](https://test.pypi.org/project/restic-profile-cli/)
@@ -63,4 +65,4 @@ ansible-lint
63
65
 
64
66
  ## Documentation
65
67
 
66
- The published documentation site lives at <https://ak1ra-lab.github.io/restic-profile/>, and local docs configuration is stored in `zensical.toml`.
68
+ The published documentation site lives at <https://ak1ra-lab.github.io/restic-profile/>, and local docs configuration is stored in `mkdocs.yml`.
@@ -0,0 +1,67 @@
1
+ # restic-profile
2
+
3
+ [English](README.md) | **简体中文**
4
+
5
+ [![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/ak1ra-lab/restic-profile/.github%2Fworkflows%2Fpublish-to-pypi.yaml)](https://github.com/ak1ra-lab/restic-profile/actions/workflows/publish-to-pypi.yaml)
6
+ [![PyPI - Version](https://img.shields.io/pypi/v/restic-profile-cli)](https://pypi.org/project/restic-profile-cli/)
7
+ [![PyPI - Version](https://img.shields.io/pypi/v/restic-profile-cli?label=test-pypi&pypiBaseUrl=https%3A%2F%2Ftest.pypi.org)](https://test.pypi.org/project/restic-profile-cli/)
8
+ [![Docs](https://img.shields.io/badge/docs-online-0a7ea4)](https://ak1ra-lab.github.io/restic-profile/)
9
+
10
+ # restic-profile
11
+
12
+ 基于配置文件的 restic 自动化工具,支持 Ansible 部署。
13
+
14
+ 包含 `restic-profile` Python CLI 以及用于 `restic-profile` 和 `restic-rest-server` 部署的 Ansible 角色。
15
+
16
+ ## 安装
17
+
18
+ ```shell
19
+ uv sync --group dev
20
+ ```
21
+
22
+ ## 可选的 Ansible 工具链
23
+
24
+ 如需使用 Ansible 角色,可在用户级别安装工具链一次:
25
+
26
+ ```shell
27
+ uv tool install ansible-dev-tools --with ansible \
28
+ --with-executables-from ansible-builder,ansible-core,ansible-creator,ansible-dev-environment,ansible-lint,ansible-navigator,ansible-sign,molecule
29
+ ```
30
+
31
+ 日常 Ansible 验证目前使用 `ansible-lint`。Molecule 场景保留在仓库中作为闲置资产,不属于支持的验证流程。
32
+
33
+ 如果你使用 `roles/go_build` 或 `playbooks/go_build/` 下的 playbook,控制节点还需要在 `PATH` 中有可用的 `go` 工具链。
34
+
35
+ ## 仓库开发流程
36
+
37
+ 将 collections 克隆到 `ansible_collections/ak1ra_lab/` 命名空间布局:
38
+
39
+ ```shell
40
+ mkdir -p ~/code/github.com/ansible/collections/ansible_collections/ak1ra_lab
41
+ git clone https://github.com/ak1ra-lab/ansible-collection-general.git \
42
+ ~/code/github.com/ansible/collections/ansible_collections/ak1ra_lab/general
43
+ git clone https://github.com/ak1ra-lab/restic-profile.git \
44
+ ~/code/github.com/ansible/collections/ansible_collections/ak1ra_lab/restic_profile
45
+ ```
46
+
47
+ ## 用法
48
+
49
+ ```shell
50
+ uv run restic-profile --help
51
+ ```
52
+
53
+ 对于 Ansible 管理的备份服务器,请参见 `restic_rest_server` 角色和 `docs/restic-rest-server/` 下的文档。
54
+
55
+ ## 开发
56
+
57
+ ```shell
58
+ just lint
59
+ just typecheck
60
+ just test
61
+ just docs-build
62
+ ansible-lint
63
+ ```
64
+
65
+ ## 文档
66
+
67
+ 已发布的文档站点位于 <https://ak1ra-lab.github.io/restic-profile/>,本地文档配置存储在 `mkdocs.yml` 中。
@@ -63,6 +63,6 @@ and fill in your host_vars.
63
63
  | Deploy backup profiles with Ansible | [Ansible examples](restic-profile/examples.md) |
64
64
  | Write a TOML config for use without Ansible | [TOML config template](restic-profile/toml-config.md) |
65
65
  | Understand CLI flags | [CLI reference](restic-profile/cli.md) |
66
- | Deploy a backup server (rest-server) | [restic-rest-server](restic-rest-server/index.md) |
66
+ | Deploy a backup server (rest-server) | [restic-rest-server](restic-rest-server.md) |
67
67
 
68
68
  See `roles/restic_profile/defaults/main.yaml` for all role variables and their defaults.
@@ -0,0 +1,65 @@
1
+ # restic-profile
2
+
3
+ 基于配置文件的 [restic](https://restic.net/) 自动化工具 —— Python CLI + Ansible 角色。
4
+
5
+ - **restic-profile** CLI:读取 TOML 配置文件,运行 `restic backup` / `forget` / `prune`,支持钩子和即时通讯通知。
6
+ - **restic_profile** Ansible 角色:部署 CLI,渲染 TOML 配置,为每个备份配置文件管理一个 systemd 定时器。支持 `systemd_scope: user` 的用户级部署。
7
+ - **restic_rest_server** Ansible 角色:部署 [rest-server](https://github.com/restic/rest-server) 实例,提供远程备份存储。
8
+
9
+ ## 安装
10
+
11
+ ### 独立 CLI(无需 Ansible、root 或 systemd)
12
+
13
+ ```shell
14
+ uv tool install restic-profile-cli
15
+ ```
16
+
17
+ 然后编写配置文件 —— 可以从 [TOML 配置模板](restic-profile/toml-config.md) 开始 ——
18
+ 然后交互式运行:
19
+
20
+ ```shell
21
+ restic-profile -c /path/to/my.toml --check
22
+ restic-profile -c /path/to/my.toml myprofile
23
+ restic-profile -c /path/to/my.toml myprofile -n
24
+ ```
25
+
26
+ 不涉及 systemd 定时器;你可以手动调用 CLI 或将其包装在 cron 中。
27
+
28
+ ### Ansible 部署
29
+
30
+ 本仓库是一个 Ansible 集合。将其克隆到标准命名空间布局下:
31
+
32
+ ```shell
33
+ mkdir -p collections/ansible_collections/ak1ra_lab
34
+ cd collections/ansible_collections/ak1ra_lab
35
+ git clone https://github.com/ak1ra-lab/restic-profile.git restic_profile
36
+ ```
37
+
38
+ 该角色依赖 **ak1ra_lab.general.pyproject_install** 角色。将其一并安装:
39
+
40
+ ```shell
41
+ cd collections/ansible_collections/ak1ra_lab
42
+ git clone https://github.com/ak1ra-lab/ansible-collection-general.git general
43
+ ```
44
+
45
+ 或通过 `ansible-galaxy` 安装依赖:
46
+
47
+ ```shell
48
+ ansible-galaxy collection install -r requirements.yml
49
+ ```
50
+
51
+ 附带的 `ansible.cfg` 要求仓库恰好位于 4 层目录深度
52
+ (`collections/ansible_collections/ak1ra_lab/restic_profile/ansible.cfg`)。如果你的检出路径不同,请调整 `ansible.cfg` 中的 `collections_path`。
53
+
54
+ 现在从 [restic-profile 示例](restic-profile/examples.md) 中选择一个示例并填写你的 host_vars。
55
+
56
+ ## 页面
57
+
58
+ | 你想... | 从这里开始 |
59
+ | ------------------------------------------- | ----------------------------------------------------- |
60
+ | 使用 Ansible 部署备份配置文件 | [Ansible 示例](restic-profile/examples.md) |
61
+ | 编写用于非 Ansible 场景的 TOML 配置 | [TOML 配置模板](restic-profile/toml-config.md) |
62
+ | 了解 CLI 参数 | [CLI 参考](restic-profile/cli.md) |
63
+ | 部署备份服务器 (rest-server) | [restic-rest-server](restic-rest-server.md) |
64
+
65
+ 参见 `roles/restic_profile/defaults/main.yaml` 了解所有角色变量及其默认值。
@@ -9,7 +9,7 @@ restic-profile -U [-c PATH] [-n] PROFILE # --unlock
9
9
 
10
10
  | Flag | Alias | Purpose |
11
11
  | -------------------------- | ------------ | --------------------------------------------------------------------------------------------------- |
12
- | `--config PATH` | `-c` | Config file (default: `/etc/restic-profile/restic-profile.toml`) |
12
+ | `--config PATH` | `-c` | Config file. When omitted, searches ``$RESTIC_PROFILE_CONFIG``, then ``$XDG_CONFIG_HOME/restic-profile/restic-profile.toml``, then ``/etc/restic-profile/restic-profile.toml`` |
13
13
  | `--check` | `-C` | Parse and validate the config, then exit |
14
14
  | `--list` | `-l` | Print profile table (name, type, schedule, repository) |
15
15
  | `--unlock PROFILE` | `-U` | Remove stale restic locks for the profile's repository |
@@ -0,0 +1,65 @@
1
+ # CLI 参考
2
+
3
+ ```text
4
+ restic-profile [-c PATH] [-n [{all,notify}]] PROFILE
5
+ restic-profile -C [-c PATH] # --check
6
+ restic-profile -l [-c PATH] # --list
7
+ restic-profile -U [-c PATH] [-n] PROFILE # --unlock
8
+ ```
9
+
10
+ | 参数 | 别名 | 说明 |
11
+ | -------------------------- | ------------ | --------------------------------------------------------------------------------------------------- |
12
+ | `--config PATH` | `-c` | 配置文件路径。省略时依次搜索 ``$RESTIC_PROFILE_CONFIG``、``$XDG_CONFIG_HOME/restic-profile/restic-profile.toml``、``/etc/restic-profile/restic-profile.toml`` |
13
+ | `--check` | `-C` | 解析并验证配置文件,然后退出 |
14
+ | `--list` | `-l` | 打印配置文件列表(名称、类型、计划、仓库) |
15
+ | `--unlock PROFILE` | `-U` | 为配置文件的仓库解除过期 restic 锁 |
16
+ | `--dry-run [{all,notify}]` | `-n` | `all`(默认):仅记录日志不执行。`notify`:空运行子进程但发送真实通知 |
17
+ | `PROFILE` | (位置参数) | 要执行的配置文件名 |
18
+
19
+ `--check`、`--list` 和 `--unlock` 互斥。不能同时使用配置文件名称与其中任何一个。
20
+
21
+ ```shell
22
+ # 运行配置文件
23
+ restic-profile myapp
24
+ restic-profile myapp -n # 空运行所有
25
+ restic-profile myapp -n notify # 空运行 + 真实通知
26
+ restic-profile myapp -c /path/to/custom.toml
27
+
28
+ # 验证配置
29
+ restic-profile -C
30
+ restic-profile -C -c /path/to/custom.toml
31
+
32
+ # 列出配置文件
33
+ restic-profile -l
34
+
35
+ # 解除过期锁
36
+ restic-profile -U myapp
37
+ restic-profile -U myapp -n
38
+ ```
39
+
40
+ ## Shell 补全
41
+
42
+ ```bash
43
+ # bash — 添加到 ~/.bashrc
44
+ if command -v register-python-argcomplete >/dev/null 2>&1; then
45
+ eval "$(register-python-argcomplete restic-profile)"
46
+ fi
47
+
48
+ # zsh — 添加到 ~/.zshrc (需要 bashcompinit)
49
+ autoload -U +X bashcompinit && bashcompinit
50
+ if command -v register-python-argcomplete >/dev/null 2>&1; then
51
+ eval "$(register-python-argcomplete restic-profile)"
52
+ fi
53
+ ```
54
+
55
+ 或使用 `activate-global-python-argcomplete` 进行系统级补全:
56
+
57
+ ```bash
58
+ # 按用户安装
59
+ activate-global-python-argcomplete --user
60
+
61
+ # 系统级安装
62
+ sudo activate-global-python-argcomplete
63
+ ```
64
+
65
+ 这会将补全脚本写入全局位置,因此不需要 `.bashrc`/`.zshrc` 片段。
@@ -271,6 +271,46 @@ cleanup is needed. Set a smaller value if disk space is tight.
271
271
 
272
272
  ---
273
273
 
274
+ ## 8. User-scope backup for an unprivileged user
275
+
276
+ ```yaml
277
+ restic_profile_repositories:
278
+ r1:
279
+ repository: "rest:https://backup.example.com:8000/alice/laptop"
280
+ password: "{{ vault_alice_restic_password }}"
281
+ rest_username: "alice"
282
+ rest_password: "{{ vault_rest_server_alice_password }}"
283
+
284
+ restic_profile_profiles:
285
+ alice-home:
286
+ repository_ref: r1
287
+ systemd_scope: user
288
+ systemd_user: alice
289
+ on_calendar: "daily"
290
+ randomized_delay_sec: "30min"
291
+ backup:
292
+ sources:
293
+ - /home/alice
294
+ - /home/alice/Documents
295
+ exclude_patterns:
296
+ - "*.tmp"
297
+ - ".cache/"
298
+ retention:
299
+ keep_daily: 14
300
+ ```
301
+
302
+ User-scope profiles require `systemd_scope: user` and an explicit
303
+ `systemd_user`. The role deploys config under
304
+ `~/.config/restic-profile/`, units under `~/.config/systemd/user/`, and
305
+ state under `~/.local/share/restic-profile/`. Timers start and stop
306
+ with the user's session without requiring `root` privileges.
307
+
308
+ The `restic-profile` CLI automatically resolves config from
309
+ `~/.config/restic-profile/restic-profile.toml` when available
310
+ (controlled by `$XDG_CONFIG_HOME` and `$RESTIC_PROFILE_CONFIG`).
311
+
312
+ ---
313
+
274
314
  ## Global role variables
275
315
 
276
316
  These affect every profile unless a profile overrides its copy.
@@ -0,0 +1,307 @@
1
+ # Ansible host_vars 示例
2
+
3
+ 所有示例都是 `restic_profile` 角色的 `host_vars` 片段。每个字段都有合理的默认值 —— 完整参考和内联注释见 `roles/restic_profile/defaults/main.yaml`。
4
+
5
+ ```yaml
6
+ # playbooks/restic-profile.yaml
7
+ ---
8
+ - name: manage restic backup profiles
9
+ hosts: "{{ playbook_hosts | default('restic_profile_nodes') }}"
10
+ gather_facts: false
11
+ become: true
12
+ tasks:
13
+ - name: apply restic_profile role
14
+ ansible.builtin.import_role:
15
+ name: ak1ra_lab.restic_profile.restic_profile
16
+ ```
17
+
18
+ ---
19
+
20
+ ## 1. 备份到 REST 服务器的最简配置
21
+
22
+ ```yaml
23
+ restic_profile_repositories:
24
+ r1:
25
+ repository: "rest:https://backup.example.com:8000/alice/laptop"
26
+ password: "{{ vault_laptop_restic_password }}"
27
+ rest_username: "alice"
28
+ rest_password: "{{ vault_rest_server_alice_password }}"
29
+
30
+ restic_profile_profiles:
31
+ laptop-home:
32
+ repository_ref: r1
33
+ on_calendar: "hourly"
34
+ randomized_delay_sec: "15min"
35
+ backup:
36
+ sources:
37
+ - /home/alice
38
+ ```
39
+
40
+ 一个配置文件,一个定时器,无保留策略。`tag` 默认值为配置文件名称 `laptop-home`。
41
+
42
+ ---
43
+
44
+ ## 2. 备份 + 保留策略 + Telegram 通知 + 钩子
45
+
46
+ ```yaml
47
+ restic_profile_notify_configs:
48
+ tg:
49
+ type: telegram
50
+ token: "{{ vault_telegram_bot_token }}"
51
+ chat_id: -1001234567890
52
+ env:
53
+ HTTPS_PROXY: "http://proxy.example.com:8080"
54
+ NO_PROXY: "localhost,127.0.0.1,.local"
55
+
56
+ restic_profile_repositories:
57
+ r1:
58
+ repository: "rest:https://backup.example.com:8000/apps/myapp"
59
+ password: "{{ vault_myapp_restic_password }}"
60
+ rest_username: "myapp"
61
+ rest_password: "{{ vault_rest_server_myapp_password }}"
62
+
63
+ restic_profile_profiles:
64
+ myapp:
65
+ repository_ref: r1
66
+ notify_ref: tg
67
+ on_calendar: "daily"
68
+ randomized_delay_sec: "30min"
69
+ hooks:
70
+ prevalidate:
71
+ - "test -d /srv/myapp || exit 1"
72
+ before:
73
+ - "systemctl stop myapp.service"
74
+ after:
75
+ - "systemctl start myapp.service"
76
+ backup:
77
+ sources:
78
+ - /srv/myapp
79
+ - /etc/myapp
80
+ exclude_patterns:
81
+ - "*.tmp"
82
+ - ".venv/"
83
+ exclude_file_content: |
84
+ __pycache__/
85
+ node_modules/
86
+ retention:
87
+ keep_daily: 14
88
+ keep_weekly: 8
89
+ keep_monthly: 12
90
+ ```
91
+
92
+ 先执行备份,然后执行内联保留策略(以本机为范围)。成功时 Telegram 会收到快照统计信息和前 N 个最大文件。
93
+
94
+ 在配置文件上设置 `enabled: false` 可在下次运行时停止并移除其单元。设置 `timer_enabled: false` 可部署单元但保持定时器停止状态。
95
+
96
+ ---
97
+
98
+ ## 3. 仓库主机上的纯保留策略
99
+
100
+ ```yaml
101
+ restic_profile_repositories:
102
+ r1:
103
+ repository: "/srv/restic/apps/myapp"
104
+ password: "{{ vault_myapp_restic_password }}"
105
+
106
+ restic_profile_profiles:
107
+ myapp-retention:
108
+ repository_ref: r1
109
+ tag: "myapp"
110
+ on_calendar: "daily"
111
+ retention:
112
+ forget_current_host: false
113
+ prune: true
114
+ keep_daily: 14
115
+ keep_weekly: 8
116
+ keep_monthly: 12
117
+ ```
118
+
119
+ 无 `backup` 块 —— 这是一个纯保留配置文件。`forget_current_host: false` 使其可以管理来自共享同一 tag 的多个备份客户端的快照。
120
+
121
+ ---
122
+
123
+ ## 4. S3 兼容后端与 PostgreSQL
124
+
125
+ ```yaml
126
+ restic_profile_repositories:
127
+ s3:
128
+ repository: "s3:https://s3.example.com/backups/postgresql"
129
+ password: "{{ vault_postgres_restic_password }}"
130
+ aws_default_region: "us-east-1"
131
+ aws_access_key_id: "{{ vault_s3_access_key }}"
132
+ aws_secret_access_key: "{{ vault_s3_secret_key }}"
133
+
134
+ restic_profile_profiles:
135
+ postgres:
136
+ repository_ref: s3
137
+ on_calendar: "03:15"
138
+ randomized_delay_sec: "5min"
139
+ env:
140
+ PGHOST: "{{ vault_postgres_host }}"
141
+ PGPORT: "{{ vault_postgres_port | default('5432') }}"
142
+ PGUSER: "{{ vault_postgres_user }}"
143
+ PGPASSWORD: "{{ vault_postgres_password }}"
144
+ hooks:
145
+ before:
146
+ - "mkdir -p /var/backups/postgresql"
147
+ - "pg_dumpall -U postgres > /var/backups/postgresql/all.sql"
148
+ success:
149
+ - "rm -f /var/backups/postgresql/all.sql"
150
+ backup:
151
+ sources:
152
+ - /var/backups/postgresql
153
+ retention:
154
+ keep_last: 7
155
+ keep_daily: 7
156
+ keep_weekly: 4
157
+ ```
158
+
159
+ S3 端点嵌入在 `repository` URL 中(`s3:https://host/bucket`)。对于 GCS,使用 `gs:bucket-name:/prefix` 并设置 `google_project_id`。
160
+
161
+ 使用 `pg_dumpall` 进行完整集群导出(角色 + 所有数据库),或使用 `pg_dump <dbname>` 导出单个数据库。切勿直接备份 PostgreSQL 数据目录。
162
+
163
+ ---
164
+
165
+ ## 5. MySQL 备份
166
+
167
+ ```yaml
168
+ restic_profile_repositories:
169
+ r1:
170
+ repository: "rest:https://backup.example.com:8000/apps/mysql"
171
+ password: "{{ vault_mysql_restic_password }}"
172
+ rest_username: "mysql"
173
+ rest_password: "{{ vault_rest_server_mysql_password }}"
174
+
175
+ restic_profile_profiles:
176
+ mysql:
177
+ repository_ref: r1
178
+ on_calendar: "daily"
179
+ randomized_delay_sec: "10min"
180
+ env:
181
+ MYSQL_HOST: "{{ vault_mysql_host }}"
182
+ MYSQL_TCP_PORT: "{{ vault_mysql_port | default('3306') }}"
183
+ MYSQL_PWD: "{{ vault_mysql_root_password }}"
184
+ hooks:
185
+ before:
186
+ - "mkdir -p /var/backups/mysql"
187
+ - "mysqldump --all-databases --single-transaction -u root > /var/backups/mysql/all.sql"
188
+ success:
189
+ - "rm -f /var/backups/mysql/all.sql"
190
+ backup:
191
+ sources:
192
+ - /var/backups/mysql
193
+ retention:
194
+ keep_daily: 7
195
+ ```
196
+
197
+ `--single-transaction` 确保 InnoDB 表在不阻塞写入的情况下获得一致性快照。对于 MyISAM,使用 `--lock-tables`。切勿直接备份 `/var/lib/mysql`。
198
+
199
+ ---
200
+
201
+ ## 6. SQLite 备份
202
+
203
+ ```yaml
204
+ restic_profile_repositories:
205
+ r1:
206
+ repository: "/srv/restic/apps/sqlite"
207
+ password: "{{ vault_sqlite_restic_password }}"
208
+
209
+ restic_profile_profiles:
210
+ sqlite:
211
+ repository_ref: r1
212
+ on_calendar: "daily"
213
+ hooks:
214
+ before:
215
+ - "mkdir -p /var/backups/sqlite"
216
+ - "sqlite3 /srv/myapp/data.db '.backup /var/backups/sqlite/data.db'"
217
+ success:
218
+ - "rm -f /var/backups/sqlite/data.db"
219
+ backup:
220
+ sources:
221
+ - /var/backups/sqlite
222
+ retention:
223
+ keep_daily: 7
224
+ ```
225
+
226
+ SQLite 的 `.backup` 命令使用在线备份 API 创建一致性快照。避免在使用中直接复制数据库文件。
227
+
228
+ ---
229
+
230
+ ## 7. GitLab 备份
231
+
232
+ ```yaml
233
+ restic_profile_repositories:
234
+ r1:
235
+ repository: "rest:https://backup.example.com:8000/apps/gitlab"
236
+ password: "{{ vault_gitlab_restic_password }}"
237
+
238
+ restic_profile_profiles:
239
+ gitlab:
240
+ repository_ref: r1
241
+ on_calendar: "daily"
242
+ randomized_delay_sec: "15min"
243
+ hooks:
244
+ before:
245
+ - "/usr/bin/gitlab-rake gitlab:backup:create"
246
+ backup:
247
+ sources:
248
+ - /var/opt/gitlab/backups
249
+ retention:
250
+ keep_daily: 7
251
+ keep_weekly: 4
252
+ ```
253
+
254
+ `gitlab:backup:create` 将带时间戳的 tar 包写入 `/var/opt/gitlab/backups`。GitLab 内置的 `gitlab_rails['backup_keep_time']`(默认 `604800` —— `/etc/gitlab/gitlab.rb` 中为 7 天)会自动清理旧的本地归档文件,因此无需手动清理。如果磁盘空间紧张,可设置较小的值。
255
+
256
+ ---
257
+
258
+ ## 8. 非特权用户的 user-scope 备份
259
+
260
+ ```yaml
261
+ restic_profile_repositories:
262
+ r1:
263
+ repository: "rest:https://backup.example.com:8000/alice/laptop"
264
+ password: "{{ vault_alice_restic_password }}"
265
+ rest_username: "alice"
266
+ rest_password: "{{ vault_rest_server_alice_password }}"
267
+
268
+ restic_profile_profiles:
269
+ alice-home:
270
+ repository_ref: r1
271
+ systemd_scope: user
272
+ systemd_user: alice
273
+ on_calendar: "daily"
274
+ randomized_delay_sec: "30min"
275
+ backup:
276
+ sources:
277
+ - /home/alice
278
+ - /home/alice/Documents
279
+ exclude_patterns:
280
+ - "*.tmp"
281
+ - ".cache/"
282
+ retention:
283
+ keep_daily: 14
284
+ ```
285
+
286
+ User-scope 配置文件需要 `systemd_scope: user` 和显式的 `systemd_user`。角色将配置部署在 `~/.config/restic-profile/` 下,单元部署在 `~/.config/systemd/user/` 下,状态部署在 `~/.local/share/restic-profile/` 下。定时器随用户会话启动和停止,无需 `root` 权限。
287
+
288
+ `restic-profile` CLI 在可用时自动从 `~/.config/restic-profile/restic-profile.toml` 解析配置(由 `$XDG_CONFIG_HOME` 和 `$RESTIC_PROFILE_CONFIG` 控制)。
289
+
290
+ ---
291
+
292
+ ## 全局角色变量
293
+
294
+ 以下变量影响所有配置文件,除非配置文件单独覆盖。
295
+
296
+ | 变量 | 默认值 | 含义 |
297
+ | -------------------------------------- | --------- | ------------------------------------------------------------ |
298
+ | `restic_profile_state` | `present` | 设置为 `absent` 以停止定时器并移除所有受管理文件 |
299
+ | `restic_profile_restic_binary` | `""` | 从 PATH 解析;设置为指定特定的二进制文件 |
300
+ | `restic_profile_no_cache` | `false` | 为每个 restic 调用添加 `--no-cache` |
301
+ | `restic_profile_retry_lock` | `""` | `--retry-lock` 持续时间(与旧版 restic ≤0.14 不兼容) |
302
+ | `restic_profile_unlock` | `false` | 在每个备份/保留操作之前运行 `restic unlock` |
303
+ | `restic_profile_systemd_cpu_quota` | `"100%"` | 生成的 service 单元中的 CPUQuota= |
304
+ | `restic_profile_pip_install_source` | `local` | 如何安装 restic-profile:`local` / `pypi` / `testpypi` |
305
+ | `restic_profile_restic_install_source` | `apt` | 如何安装 restic:`apt` / `go_build` / `existing` |
306
+
307
+ 完整列表和注释见 `roles/restic_profile/defaults/main.yaml`。
@@ -1,7 +1,8 @@
1
1
  ```toml
2
2
  # restic-profile.toml — well-commented starting config
3
3
  #
4
- # Copy this file to /etc/restic-profile/restic-profile.toml, fill in your
4
+ # Copy this file to /etc/restic-profile/restic-profile.toml (system scope)
5
+ # or ~/.config/restic-profile/restic-profile.toml (user scope), fill in your
5
6
  # credentials and paths, then run:
6
7
  # restic-profile --check # validate the config
7
8
  # restic-profile --list # list all profiles