declarative-data-backup 0.2.0__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.
- {declarative_data_backup-0.2.0 → declarative_data_backup-0.3.0}/PKG-INFO +27 -24
- {declarative_data_backup-0.2.0 → declarative_data_backup-0.3.0}/README.md +26 -18
- {declarative_data_backup-0.2.0 → declarative_data_backup-0.3.0}/pyproject.toml +2 -2
- {declarative_data_backup-0.2.0 → declarative_data_backup-0.3.0}/src/declarative_data_backup/backup.py +7 -0
- {declarative_data_backup-0.2.0 → declarative_data_backup-0.3.0}/src/declarative_data_backup/borg/borg.py +13 -7
- {declarative_data_backup-0.2.0 → declarative_data_backup-0.3.0}/src/declarative_data_backup/environment.py +10 -0
- {declarative_data_backup-0.2.0 → declarative_data_backup-0.3.0}/src/declarative_data_backup.egg-info/PKG-INFO +27 -24
- declarative_data_backup-0.3.0/src/declarative_data_backup.egg-info/requires.txt +1 -0
- {declarative_data_backup-0.2.0 → declarative_data_backup-0.3.0}/tests/test_backup.py +4 -0
- declarative_data_backup-0.2.0/src/declarative_data_backup.egg-info/requires.txt +0 -7
- {declarative_data_backup-0.2.0 → declarative_data_backup-0.3.0}/setup.cfg +0 -0
- {declarative_data_backup-0.2.0 → declarative_data_backup-0.3.0}/src/declarative_data_backup/__init__.py +0 -0
- {declarative_data_backup-0.2.0 → declarative_data_backup-0.3.0}/src/declarative_data_backup/__main__.py +0 -0
- {declarative_data_backup-0.2.0 → declarative_data_backup-0.3.0}/src/declarative_data_backup/borg/__init__.py +0 -0
- {declarative_data_backup-0.2.0 → declarative_data_backup-0.3.0}/src/declarative_data_backup/borg/archive_naming.py +0 -0
- {declarative_data_backup-0.2.0 → declarative_data_backup-0.3.0}/src/declarative_data_backup/borg/borg_cli.py +0 -0
- {declarative_data_backup-0.2.0 → declarative_data_backup-0.3.0}/src/declarative_data_backup/config/__init__.py +0 -0
- {declarative_data_backup-0.2.0 → declarative_data_backup-0.3.0}/src/declarative_data_backup/config/backup_config/__init__.py +0 -0
- {declarative_data_backup-0.2.0 → declarative_data_backup-0.3.0}/src/declarative_data_backup/config/backup_config/models.py +0 -0
- {declarative_data_backup-0.2.0 → declarative_data_backup-0.3.0}/src/declarative_data_backup/config/backup_config/utils.py +0 -0
- {declarative_data_backup-0.2.0 → declarative_data_backup-0.3.0}/src/declarative_data_backup/config/backup_config/yaml_parser.py +0 -0
- {declarative_data_backup-0.2.0 → declarative_data_backup-0.3.0}/src/declarative_data_backup/config/backup_config/yaml_raw_loader.py +0 -0
- {declarative_data_backup-0.2.0 → declarative_data_backup-0.3.0}/src/declarative_data_backup/config/logging.py +0 -0
- {declarative_data_backup-0.2.0 → declarative_data_backup-0.3.0}/src/declarative_data_backup/errors.py +0 -0
- {declarative_data_backup-0.2.0 → declarative_data_backup-0.3.0}/src/declarative_data_backup.egg-info/SOURCES.txt +0 -0
- {declarative_data_backup-0.2.0 → declarative_data_backup-0.3.0}/src/declarative_data_backup.egg-info/dependency_links.txt +0 -0
- {declarative_data_backup-0.2.0 → declarative_data_backup-0.3.0}/src/declarative_data_backup.egg-info/top_level.txt +0 -0
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: declarative-data-backup
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Declarative Borg-based data backups
|
|
5
5
|
Requires-Python: >=3.11
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
7
7
|
Requires-Dist: PyYAML<7,>=6
|
|
8
|
-
Provides-Extra: dev
|
|
9
|
-
Requires-Dist: pre-commit<5,>=4; extra == "dev"
|
|
10
|
-
Requires-Dist: pyright<2,>=1.1.400; extra == "dev"
|
|
11
|
-
Requires-Dist: pytest<10,>=8; extra == "dev"
|
|
12
|
-
Requires-Dist: ruff<1,>=0.11; extra == "dev"
|
|
13
8
|
|
|
14
9
|
# Declarative Data Backup
|
|
15
10
|
|
|
@@ -31,18 +26,20 @@ The application never initializes a repository. Borg 2 is not supported.
|
|
|
31
26
|
|
|
32
27
|
## Installation
|
|
33
28
|
|
|
34
|
-
Install the package from PyPI:
|
|
29
|
+
Install the package from PyPI into a `uv`-managed environment:
|
|
35
30
|
|
|
36
31
|
```shell
|
|
37
|
-
|
|
32
|
+
uv venv
|
|
33
|
+
uv pip install declarative-data-backup
|
|
38
34
|
```
|
|
39
35
|
|
|
40
|
-
|
|
36
|
+
For a checkout, install the development dependencies with:
|
|
41
37
|
|
|
42
38
|
```shell
|
|
43
|
-
|
|
39
|
+
make install
|
|
44
40
|
```
|
|
45
41
|
|
|
42
|
+
To also install the repository's pre-commit hooks, run `make setup`.
|
|
46
43
|
The PyPI distribution is named `declarative-data-backup`; its importable
|
|
47
44
|
package is `declarative_data_backup`.
|
|
48
45
|
|
|
@@ -56,8 +53,8 @@ release pipeline.
|
|
|
56
53
|
|
|
57
54
|
For each version tag, the pipeline:
|
|
58
55
|
|
|
59
|
-
1. Sets the package version in the CI checkout's `pyproject.toml
|
|
60
|
-
|
|
56
|
+
1. Sets the package version in the CI checkout's `pyproject.toml` and uses
|
|
57
|
+
`uv build` to create a wheel and source distribution.
|
|
61
58
|
2. Uploads `declarative-data-backup` to PyPI.
|
|
62
59
|
3. Builds the existing Python 3.13 Dockerfile with the same package version,
|
|
63
60
|
verifies the installed version, and pushes
|
|
@@ -152,6 +149,8 @@ Optional variables:
|
|
|
152
149
|
| --- | --- |
|
|
153
150
|
| `BORG_REMOTE_PATH` | Remote Borg executable path, passed as Borg's `--remote-path`. Leave unset to use Borg's default. |
|
|
154
151
|
| `BORG_EXIT_CODES` | Borg exit-code mode: `legacy` or `modern`. |
|
|
152
|
+
| `BACKUP_PROGRESS` | Set to `true` to enable Borg's live progress output during archive creation. Defaults to `false` to limit log volume. |
|
|
153
|
+
| `BACKUP_VERBOSE` | Set to `true` to show Borg's per-file create and per-archive prune output. Defaults to `false` for concise logs. |
|
|
155
154
|
|
|
156
155
|
Provide credentials through a secret manager or protected files; do not put
|
|
157
156
|
passphrases, private keys, or credentials in the YAML file, source control, or
|
|
@@ -164,7 +163,10 @@ python -m declarative_data_backup
|
|
|
164
163
|
|
|
165
164
|
The command exits with status `0` on success, nonzero on configuration or Borg
|
|
166
165
|
failure, and `130` when interrupted. Borg's exit code `1` indicates warnings:
|
|
167
|
-
the run fails and pruning is skipped.
|
|
166
|
+
the run fails and pruning is skipped. Logs include group and source start/end
|
|
167
|
+
messages, while Borg's per-file and per-archive output is disabled by default.
|
|
168
|
+
Set `BACKUP_VERBOSE=true` for detailed Borg output or `BACKUP_PROGRESS=true`
|
|
169
|
+
for live progress during archive creation; either can increase log volume.
|
|
168
170
|
|
|
169
171
|
## Configuration reference
|
|
170
172
|
|
|
@@ -292,24 +294,25 @@ container integration test.
|
|
|
292
294
|
|
|
293
295
|
## Testing
|
|
294
296
|
|
|
295
|
-
Run the unit tests:
|
|
297
|
+
Run the unit tests, integration tests, or both:
|
|
296
298
|
|
|
297
299
|
```shell
|
|
298
|
-
|
|
300
|
+
make test-unit
|
|
301
|
+
make test-integration
|
|
302
|
+
make test
|
|
299
303
|
```
|
|
300
304
|
|
|
301
|
-
The
|
|
305
|
+
The integration target opts in to both local Borg tests (which use temporary
|
|
306
|
+
encrypted repositories) and the Docker SSH test (which uses disposable
|
|
307
|
+
containers and a temporary repository). It does not use production credentials
|
|
308
|
+
or BorgBase. Docker must be installed and its daemon available.
|
|
302
309
|
|
|
303
|
-
|
|
304
|
-
RUN_BORG_LOCAL_INTEGRATION=1 python -m pytest -m integration \
|
|
305
|
-
tests/integration/test_local_borg_integration.py
|
|
306
|
-
```
|
|
307
|
-
|
|
308
|
-
The opt-in Docker SSH integration test uses disposable containers and a
|
|
309
|
-
temporary repository; it does not use production credentials or BorgBase:
|
|
310
|
+
To run either integration suite individually:
|
|
310
311
|
|
|
311
312
|
```shell
|
|
312
|
-
|
|
313
|
+
RUN_BORG_LOCAL_INTEGRATION=1 uv run pytest -m integration \
|
|
314
|
+
tests/integration/test_local_borg_integration.py
|
|
315
|
+
RUN_BORG_DOCKER_INTEGRATION=1 uv run pytest -m integration \
|
|
313
316
|
tests/integration/test_docker_integration.py
|
|
314
317
|
```
|
|
315
318
|
|
|
@@ -18,18 +18,20 @@ The application never initializes a repository. Borg 2 is not supported.
|
|
|
18
18
|
|
|
19
19
|
## Installation
|
|
20
20
|
|
|
21
|
-
Install the package from PyPI:
|
|
21
|
+
Install the package from PyPI into a `uv`-managed environment:
|
|
22
22
|
|
|
23
23
|
```shell
|
|
24
|
-
|
|
24
|
+
uv venv
|
|
25
|
+
uv pip install declarative-data-backup
|
|
25
26
|
```
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
For a checkout, install the development dependencies with:
|
|
28
29
|
|
|
29
30
|
```shell
|
|
30
|
-
|
|
31
|
+
make install
|
|
31
32
|
```
|
|
32
33
|
|
|
34
|
+
To also install the repository's pre-commit hooks, run `make setup`.
|
|
33
35
|
The PyPI distribution is named `declarative-data-backup`; its importable
|
|
34
36
|
package is `declarative_data_backup`.
|
|
35
37
|
|
|
@@ -43,8 +45,8 @@ release pipeline.
|
|
|
43
45
|
|
|
44
46
|
For each version tag, the pipeline:
|
|
45
47
|
|
|
46
|
-
1. Sets the package version in the CI checkout's `pyproject.toml
|
|
47
|
-
|
|
48
|
+
1. Sets the package version in the CI checkout's `pyproject.toml` and uses
|
|
49
|
+
`uv build` to create a wheel and source distribution.
|
|
48
50
|
2. Uploads `declarative-data-backup` to PyPI.
|
|
49
51
|
3. Builds the existing Python 3.13 Dockerfile with the same package version,
|
|
50
52
|
verifies the installed version, and pushes
|
|
@@ -139,6 +141,8 @@ Optional variables:
|
|
|
139
141
|
| --- | --- |
|
|
140
142
|
| `BORG_REMOTE_PATH` | Remote Borg executable path, passed as Borg's `--remote-path`. Leave unset to use Borg's default. |
|
|
141
143
|
| `BORG_EXIT_CODES` | Borg exit-code mode: `legacy` or `modern`. |
|
|
144
|
+
| `BACKUP_PROGRESS` | Set to `true` to enable Borg's live progress output during archive creation. Defaults to `false` to limit log volume. |
|
|
145
|
+
| `BACKUP_VERBOSE` | Set to `true` to show Borg's per-file create and per-archive prune output. Defaults to `false` for concise logs. |
|
|
142
146
|
|
|
143
147
|
Provide credentials through a secret manager or protected files; do not put
|
|
144
148
|
passphrases, private keys, or credentials in the YAML file, source control, or
|
|
@@ -151,7 +155,10 @@ python -m declarative_data_backup
|
|
|
151
155
|
|
|
152
156
|
The command exits with status `0` on success, nonzero on configuration or Borg
|
|
153
157
|
failure, and `130` when interrupted. Borg's exit code `1` indicates warnings:
|
|
154
|
-
the run fails and pruning is skipped.
|
|
158
|
+
the run fails and pruning is skipped. Logs include group and source start/end
|
|
159
|
+
messages, while Borg's per-file and per-archive output is disabled by default.
|
|
160
|
+
Set `BACKUP_VERBOSE=true` for detailed Borg output or `BACKUP_PROGRESS=true`
|
|
161
|
+
for live progress during archive creation; either can increase log volume.
|
|
155
162
|
|
|
156
163
|
## Configuration reference
|
|
157
164
|
|
|
@@ -279,24 +286,25 @@ container integration test.
|
|
|
279
286
|
|
|
280
287
|
## Testing
|
|
281
288
|
|
|
282
|
-
Run the unit tests:
|
|
289
|
+
Run the unit tests, integration tests, or both:
|
|
283
290
|
|
|
284
291
|
```shell
|
|
285
|
-
|
|
292
|
+
make test-unit
|
|
293
|
+
make test-integration
|
|
294
|
+
make test
|
|
286
295
|
```
|
|
287
296
|
|
|
288
|
-
The
|
|
297
|
+
The integration target opts in to both local Borg tests (which use temporary
|
|
298
|
+
encrypted repositories) and the Docker SSH test (which uses disposable
|
|
299
|
+
containers and a temporary repository). It does not use production credentials
|
|
300
|
+
or BorgBase. Docker must be installed and its daemon available.
|
|
289
301
|
|
|
290
|
-
|
|
291
|
-
RUN_BORG_LOCAL_INTEGRATION=1 python -m pytest -m integration \
|
|
292
|
-
tests/integration/test_local_borg_integration.py
|
|
293
|
-
```
|
|
294
|
-
|
|
295
|
-
The opt-in Docker SSH integration test uses disposable containers and a
|
|
296
|
-
temporary repository; it does not use production credentials or BorgBase:
|
|
302
|
+
To run either integration suite individually:
|
|
297
303
|
|
|
298
304
|
```shell
|
|
299
|
-
|
|
305
|
+
RUN_BORG_LOCAL_INTEGRATION=1 uv run pytest -m integration \
|
|
306
|
+
tests/integration/test_local_borg_integration.py
|
|
307
|
+
RUN_BORG_DOCKER_INTEGRATION=1 uv run pytest -m integration \
|
|
300
308
|
tests/integration/test_docker_integration.py
|
|
301
309
|
```
|
|
302
310
|
|
|
@@ -4,13 +4,13 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "declarative-data-backup"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.3.0"
|
|
8
8
|
description = "Declarative Borg-based data backups"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
11
11
|
dependencies = ["PyYAML>=6,<7"]
|
|
12
12
|
|
|
13
|
-
[
|
|
13
|
+
[dependency-groups]
|
|
14
14
|
dev = [
|
|
15
15
|
"pre-commit>=4,<5",
|
|
16
16
|
"pyright>=1.1.400,<2",
|
|
@@ -70,8 +70,14 @@ def run_backup(
|
|
|
70
70
|
run_id,
|
|
71
71
|
definition.excludes,
|
|
72
72
|
)
|
|
73
|
+
logger.info("Backup group '%s' completed.", definition.name)
|
|
73
74
|
|
|
74
75
|
for definition in definitions:
|
|
76
|
+
logger.info(
|
|
77
|
+
"Starting retention pruning for group '%s' (%d sources).",
|
|
78
|
+
definition.name,
|
|
79
|
+
len(definition.sources),
|
|
80
|
+
)
|
|
75
81
|
for folder in definition.sources:
|
|
76
82
|
prune(
|
|
77
83
|
folder,
|
|
@@ -79,6 +85,7 @@ def run_backup(
|
|
|
79
85
|
definition.name,
|
|
80
86
|
settings,
|
|
81
87
|
)
|
|
88
|
+
logger.info("Retention pruning for group '%s' completed.", definition.name)
|
|
82
89
|
|
|
83
90
|
|
|
84
91
|
def main(environ: Mapping[str, str] | None = None) -> int:
|
|
@@ -41,11 +41,14 @@ def backup_folder(
|
|
|
41
41
|
logger.info("Starting backup for %s as archive %s.", context, name)
|
|
42
42
|
args = [
|
|
43
43
|
"create",
|
|
44
|
-
"--verbose",
|
|
45
44
|
"--stats",
|
|
46
45
|
"--compression",
|
|
47
46
|
compression,
|
|
48
47
|
]
|
|
48
|
+
if settings.backup_verbose:
|
|
49
|
+
args.append("--verbose")
|
|
50
|
+
if settings.backup_progress:
|
|
51
|
+
args.append("--progress")
|
|
49
52
|
for pattern in excludes:
|
|
50
53
|
args.extend(("--exclude", pattern))
|
|
51
54
|
args.extend((f"{settings.borg_repo}::{name}", str(folder)))
|
|
@@ -85,17 +88,20 @@ def prune(
|
|
|
85
88
|
retention_days,
|
|
86
89
|
)
|
|
87
90
|
try:
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
91
|
+
args = ["prune"]
|
|
92
|
+
if settings.backup_verbose:
|
|
93
|
+
args.extend(("--verbose", "--list"))
|
|
94
|
+
args.extend(
|
|
95
|
+
(
|
|
93
96
|
"--glob-archives",
|
|
94
97
|
selector,
|
|
95
98
|
"--keep-daily",
|
|
96
99
|
str(retention_days),
|
|
97
100
|
settings.borg_repo,
|
|
98
|
-
|
|
101
|
+
)
|
|
102
|
+
)
|
|
103
|
+
run_borg(
|
|
104
|
+
args,
|
|
99
105
|
settings,
|
|
100
106
|
"prune",
|
|
101
107
|
context,
|
|
@@ -17,6 +17,8 @@ class Environment:
|
|
|
17
17
|
borg_passcommand: str
|
|
18
18
|
borg_remote_path: str | None
|
|
19
19
|
borg_exit_codes: str | None
|
|
20
|
+
backup_progress: bool
|
|
21
|
+
backup_verbose: bool
|
|
20
22
|
|
|
21
23
|
@classmethod
|
|
22
24
|
def from_env(
|
|
@@ -46,6 +48,12 @@ class Environment:
|
|
|
46
48
|
borg_exit_codes = source.get("BORG_EXIT_CODES")
|
|
47
49
|
if borg_exit_codes not in (None, "legacy", "modern"):
|
|
48
50
|
fail("BORG_EXIT_CODES must be either 'legacy' or 'modern'.")
|
|
51
|
+
backup_progress_value = source.get("BACKUP_PROGRESS", "false").lower()
|
|
52
|
+
if backup_progress_value not in ("true", "false"):
|
|
53
|
+
fail("BACKUP_PROGRESS must be either 'true' or 'false'.")
|
|
54
|
+
backup_verbose_value = source.get("BACKUP_VERBOSE", "false").lower()
|
|
55
|
+
if backup_verbose_value not in ("true", "false"):
|
|
56
|
+
fail("BACKUP_VERBOSE must be either 'true' or 'false'.")
|
|
49
57
|
|
|
50
58
|
try:
|
|
51
59
|
server_root = required_path("SERVER_ROOT").resolve(strict=True)
|
|
@@ -62,6 +70,8 @@ class Environment:
|
|
|
62
70
|
borg_passcommand=required("BORG_PASSCOMMAND"),
|
|
63
71
|
borg_remote_path=source.get("BORG_REMOTE_PATH"),
|
|
64
72
|
borg_exit_codes=borg_exit_codes,
|
|
73
|
+
backup_progress=backup_progress_value == "true",
|
|
74
|
+
backup_verbose=backup_verbose_value == "true",
|
|
65
75
|
)
|
|
66
76
|
|
|
67
77
|
|
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: declarative-data-backup
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Declarative Borg-based data backups
|
|
5
5
|
Requires-Python: >=3.11
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
7
7
|
Requires-Dist: PyYAML<7,>=6
|
|
8
|
-
Provides-Extra: dev
|
|
9
|
-
Requires-Dist: pre-commit<5,>=4; extra == "dev"
|
|
10
|
-
Requires-Dist: pyright<2,>=1.1.400; extra == "dev"
|
|
11
|
-
Requires-Dist: pytest<10,>=8; extra == "dev"
|
|
12
|
-
Requires-Dist: ruff<1,>=0.11; extra == "dev"
|
|
13
8
|
|
|
14
9
|
# Declarative Data Backup
|
|
15
10
|
|
|
@@ -31,18 +26,20 @@ The application never initializes a repository. Borg 2 is not supported.
|
|
|
31
26
|
|
|
32
27
|
## Installation
|
|
33
28
|
|
|
34
|
-
Install the package from PyPI:
|
|
29
|
+
Install the package from PyPI into a `uv`-managed environment:
|
|
35
30
|
|
|
36
31
|
```shell
|
|
37
|
-
|
|
32
|
+
uv venv
|
|
33
|
+
uv pip install declarative-data-backup
|
|
38
34
|
```
|
|
39
35
|
|
|
40
|
-
|
|
36
|
+
For a checkout, install the development dependencies with:
|
|
41
37
|
|
|
42
38
|
```shell
|
|
43
|
-
|
|
39
|
+
make install
|
|
44
40
|
```
|
|
45
41
|
|
|
42
|
+
To also install the repository's pre-commit hooks, run `make setup`.
|
|
46
43
|
The PyPI distribution is named `declarative-data-backup`; its importable
|
|
47
44
|
package is `declarative_data_backup`.
|
|
48
45
|
|
|
@@ -56,8 +53,8 @@ release pipeline.
|
|
|
56
53
|
|
|
57
54
|
For each version tag, the pipeline:
|
|
58
55
|
|
|
59
|
-
1. Sets the package version in the CI checkout's `pyproject.toml
|
|
60
|
-
|
|
56
|
+
1. Sets the package version in the CI checkout's `pyproject.toml` and uses
|
|
57
|
+
`uv build` to create a wheel and source distribution.
|
|
61
58
|
2. Uploads `declarative-data-backup` to PyPI.
|
|
62
59
|
3. Builds the existing Python 3.13 Dockerfile with the same package version,
|
|
63
60
|
verifies the installed version, and pushes
|
|
@@ -152,6 +149,8 @@ Optional variables:
|
|
|
152
149
|
| --- | --- |
|
|
153
150
|
| `BORG_REMOTE_PATH` | Remote Borg executable path, passed as Borg's `--remote-path`. Leave unset to use Borg's default. |
|
|
154
151
|
| `BORG_EXIT_CODES` | Borg exit-code mode: `legacy` or `modern`. |
|
|
152
|
+
| `BACKUP_PROGRESS` | Set to `true` to enable Borg's live progress output during archive creation. Defaults to `false` to limit log volume. |
|
|
153
|
+
| `BACKUP_VERBOSE` | Set to `true` to show Borg's per-file create and per-archive prune output. Defaults to `false` for concise logs. |
|
|
155
154
|
|
|
156
155
|
Provide credentials through a secret manager or protected files; do not put
|
|
157
156
|
passphrases, private keys, or credentials in the YAML file, source control, or
|
|
@@ -164,7 +163,10 @@ python -m declarative_data_backup
|
|
|
164
163
|
|
|
165
164
|
The command exits with status `0` on success, nonzero on configuration or Borg
|
|
166
165
|
failure, and `130` when interrupted. Borg's exit code `1` indicates warnings:
|
|
167
|
-
the run fails and pruning is skipped.
|
|
166
|
+
the run fails and pruning is skipped. Logs include group and source start/end
|
|
167
|
+
messages, while Borg's per-file and per-archive output is disabled by default.
|
|
168
|
+
Set `BACKUP_VERBOSE=true` for detailed Borg output or `BACKUP_PROGRESS=true`
|
|
169
|
+
for live progress during archive creation; either can increase log volume.
|
|
168
170
|
|
|
169
171
|
## Configuration reference
|
|
170
172
|
|
|
@@ -292,24 +294,25 @@ container integration test.
|
|
|
292
294
|
|
|
293
295
|
## Testing
|
|
294
296
|
|
|
295
|
-
Run the unit tests:
|
|
297
|
+
Run the unit tests, integration tests, or both:
|
|
296
298
|
|
|
297
299
|
```shell
|
|
298
|
-
|
|
300
|
+
make test-unit
|
|
301
|
+
make test-integration
|
|
302
|
+
make test
|
|
299
303
|
```
|
|
300
304
|
|
|
301
|
-
The
|
|
305
|
+
The integration target opts in to both local Borg tests (which use temporary
|
|
306
|
+
encrypted repositories) and the Docker SSH test (which uses disposable
|
|
307
|
+
containers and a temporary repository). It does not use production credentials
|
|
308
|
+
or BorgBase. Docker must be installed and its daemon available.
|
|
302
309
|
|
|
303
|
-
|
|
304
|
-
RUN_BORG_LOCAL_INTEGRATION=1 python -m pytest -m integration \
|
|
305
|
-
tests/integration/test_local_borg_integration.py
|
|
306
|
-
```
|
|
307
|
-
|
|
308
|
-
The opt-in Docker SSH integration test uses disposable containers and a
|
|
309
|
-
temporary repository; it does not use production credentials or BorgBase:
|
|
310
|
+
To run either integration suite individually:
|
|
310
311
|
|
|
311
312
|
```shell
|
|
312
|
-
|
|
313
|
+
RUN_BORG_LOCAL_INTEGRATION=1 uv run pytest -m integration \
|
|
314
|
+
tests/integration/test_local_borg_integration.py
|
|
315
|
+
RUN_BORG_DOCKER_INTEGRATION=1 uv run pytest -m integration \
|
|
313
316
|
tests/integration/test_docker_integration.py
|
|
314
317
|
```
|
|
315
318
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
PyYAML<7,>=6
|
|
@@ -29,6 +29,7 @@ def _configure_preflight(monkeypatch):
|
|
|
29
29
|
def test_main_runs_all_creates_before_any_prune(
|
|
30
30
|
settings_factory,
|
|
31
31
|
monkeypatch,
|
|
32
|
+
caplog,
|
|
32
33
|
):
|
|
33
34
|
settings = settings_factory()
|
|
34
35
|
media = settings.server_root / "media"
|
|
@@ -62,6 +63,7 @@ def test_main_runs_all_creates_before_any_prune(
|
|
|
62
63
|
monkeypatch.setattr(
|
|
63
64
|
backup.uuid, "uuid4", lambda: type("UUID", (), {"hex": "a" * 32})()
|
|
64
65
|
)
|
|
66
|
+
caplog.set_level(logging.INFO)
|
|
65
67
|
|
|
66
68
|
assert backup.main(_settings_environment(settings)) == 0
|
|
67
69
|
assert [event[0] for event in events] == [
|
|
@@ -73,6 +75,8 @@ def test_main_runs_all_creates_before_any_prune(
|
|
|
73
75
|
assert events[0][3] == "zstd,5"
|
|
74
76
|
assert events[1][3] == "auto,zstd,22"
|
|
75
77
|
assert events[2][3] == 30
|
|
78
|
+
assert "Backup group 'media_backup' completed." in caplog.text
|
|
79
|
+
assert "Retention pruning for group 'media_backup' completed." in caplog.text
|
|
76
80
|
|
|
77
81
|
|
|
78
82
|
def test_main_warning_aborts_remaining_creates_and_all_pruning(
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|