dar-backup 0.8.1__py3-none-any.whl → 0.8.3__py3-none-any.whl
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.
- dar_backup/Changelog.md +28 -0
- dar_backup/README.md +192 -64
- dar_backup/__about__.py +1 -1
- dar_backup/command_runner.py +100 -19
- dar_backup/dar_backup.py +5 -5
- {dar_backup-0.8.1.dist-info → dar_backup-0.8.3.dist-info}/METADATA +193 -65
- {dar_backup-0.8.1.dist-info → dar_backup-0.8.3.dist-info}/RECORD +10 -10
- {dar_backup-0.8.1.dist-info → dar_backup-0.8.3.dist-info}/WHEEL +0 -0
- {dar_backup-0.8.1.dist-info → dar_backup-0.8.3.dist-info}/entry_points.txt +0 -0
- {dar_backup-0.8.1.dist-info → dar_backup-0.8.3.dist-info}/licenses/LICENSE +0 -0
dar_backup/Changelog.md
CHANGED
|
@@ -1,6 +1,34 @@
|
|
|
1
1
|
<!-- markdownlint-disable MD024 -->
|
|
2
2
|
# dar-backup Changelog
|
|
3
3
|
|
|
4
|
+
## v2-beta-0.8.3 - 2025-08-23
|
|
5
|
+
|
|
6
|
+
Github link: [v2-beta-0.8.3](https://github.com/per2jensen/dar-backup/tree/v2-beta-0.8.3/v2)
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- Dar-backup now deletes files if noted as "removed" in the archive catalog for DIFF and INCR backups.
|
|
11
|
+
- This ensures a restore of a FULL + DIFF + INCR matches the files in the source directories.
|
|
12
|
+
- Options '-wa' & '-/ Oo' added to the restore command.
|
|
13
|
+
|
|
14
|
+
## v2-beta-0.8.2 - 2025-07-17
|
|
15
|
+
|
|
16
|
+
Github link: [v2-beta-0.8.2](https://github.com/per2jensen/dar-backup/tree/v2-beta-0.8.2/v2)
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- Security hardening: CommandRunner now performs strict command-line sanitization
|
|
21
|
+
- Disallows potentially dangerous characters (e.g. ;, &, |) in command arguments
|
|
22
|
+
- Prevents injection-style misuse when restoring specific files or invoking custom commands
|
|
23
|
+
|
|
24
|
+
- Documentation:
|
|
25
|
+
- New [README section](https://github.com/per2jensen/dar-backup?tab=readme-ov-file#limitations-on-file-names-with-special-characters) explains filename restrictions and safe workarounds (e.g. restoring directly with dar, if needed)
|
|
26
|
+
- Includes a Markdown table listing all disallowed characters
|
|
27
|
+
|
|
28
|
+
- Test suite:
|
|
29
|
+
- Existing test cases updated to comply with the new sanitization rules
|
|
30
|
+
- Additional tests ensure CommandRunner handles large binary output and edge cases cleanly
|
|
31
|
+
|
|
4
32
|
## v2-beta-0.8.1 - 2025-07-16
|
|
5
33
|
|
|
6
34
|
Github link: [v2-beta-0.8.1](https://github.com/per2jensen/dar-backup/tree/v2-beta-0.8.1/v2)
|
dar_backup/README.md
CHANGED
|
@@ -22,71 +22,90 @@ This is the `Python` based [**version 2**](https://github.com/per2jensen/dar-bac
|
|
|
22
22
|
|
|
23
23
|
## Table of Contents
|
|
24
24
|
|
|
25
|
-
- [
|
|
26
|
-
- [
|
|
27
|
-
- [
|
|
28
|
-
- [
|
|
29
|
-
- [
|
|
30
|
-
- [
|
|
31
|
-
- [
|
|
32
|
-
- [
|
|
33
|
-
|
|
34
|
-
- [
|
|
35
|
-
- [
|
|
36
|
-
- [
|
|
37
|
-
- [
|
|
38
|
-
- [
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
- [
|
|
43
|
-
|
|
44
|
-
- [
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
- [
|
|
25
|
+
- [`dar-backup`](#dar-backup)
|
|
26
|
+
- [TL;DR](#tldr)
|
|
27
|
+
- [Table of Contents](#table-of-contents)
|
|
28
|
+
- [My use case](#my-use-case)
|
|
29
|
+
- [Features](#features)
|
|
30
|
+
- [License](#license)
|
|
31
|
+
- [Quick Guide](#quick-guide)
|
|
32
|
+
- [Status](#status)
|
|
33
|
+
- [GPG Signing key](#gpg-signing-key)
|
|
34
|
+
- [Breaking change in version 0.6.0](#breaking-change-in-version-060)
|
|
35
|
+
- [Homepage - Github](#homepage---github)
|
|
36
|
+
- [Community](#community)
|
|
37
|
+
- [Requirements](#requirements)
|
|
38
|
+
- [dar-backup principles](#dar-backup-principles)
|
|
39
|
+
- [dar-backup](#dar-backup-1)
|
|
40
|
+
- [cleanup](#cleanup)
|
|
41
|
+
- [manager](#manager)
|
|
42
|
+
- [How to run](#how-to-run)
|
|
43
|
+
- [1 - installation](#1---installation)
|
|
44
|
+
- [2 - configuration](#2---configuration)
|
|
45
|
+
- [3 - generate catalog databases](#3---generate-catalog-databases)
|
|
46
|
+
- [4 - give dar-backup a spin](#4---give-dar-backup-a-spin)
|
|
47
|
+
- [5 - deactivate venv](#5---deactivate-venv)
|
|
48
|
+
- [Config](#config)
|
|
49
|
+
- [Config file](#config-file)
|
|
50
|
+
- [.darrc](#darrc)
|
|
51
|
+
- [Backup definition example](#backup-definition-example)
|
|
49
52
|
- [Generate systemd files](#generate-systemd-files)
|
|
50
|
-
- [
|
|
51
|
-
- [
|
|
52
|
-
- [
|
|
53
|
-
- [
|
|
54
|
-
- [
|
|
55
|
-
- [
|
|
56
|
-
|
|
57
|
-
- [
|
|
58
|
-
- [
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
- [
|
|
66
|
-
- [Par2
|
|
67
|
-
|
|
68
|
-
- [
|
|
69
|
-
- [
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
53
|
+
- [Systemctl examples](#systemctl-examples)
|
|
54
|
+
- [Service: dar-backup --incremental-backup](#service-dar-backup---incremental-backup)
|
|
55
|
+
- [Timer: dar-backup --incremental-backup](#timer-dar-backup---incremental-backup)
|
|
56
|
+
- [systemd timer note](#systemd-timer-note)
|
|
57
|
+
- [list contents of an archive](#list-contents-of-an-archive)
|
|
58
|
+
- [dar file selection examples](#dar-file-selection-examples)
|
|
59
|
+
- [select a directory](#select-a-directory)
|
|
60
|
+
- [select files with "Z50" in the file name and exclude .xmp files](#select-files-with-z50-in-the-file-name-and-exclude-xmp-files)
|
|
61
|
+
- [Restoring](#restoring)
|
|
62
|
+
- [default location for restores](#default-location-for-restores)
|
|
63
|
+
- [--restore-dir option](#--restore-dir-option)
|
|
64
|
+
- [a single file](#a-single-file)
|
|
65
|
+
- [a directory](#a-directory)
|
|
66
|
+
- [.NEF from a specific date](#nef-from-a-specific-date)
|
|
67
|
+
- [restore test fails with exit code 4](#restore-test-fails-with-exit-code-4)
|
|
68
|
+
- [restore test fails with exit code 5](#restore-test-fails-with-exit-code-5)
|
|
69
|
+
- [Par2](#par2)
|
|
70
|
+
- [Par2 to verify/repair](#par2-to-verifyrepair)
|
|
71
|
+
- [Par2 create redundancy files](#par2-create-redundancy-files)
|
|
72
|
+
- [Points of interest](#points-of-interest)
|
|
73
|
+
- [Limitations on File Names with Special Characters](#limitations-on-file-names-with-special-characters)
|
|
74
|
+
- [Why this matters](#why-this-matters)
|
|
75
|
+
- [Workarounds](#workarounds)
|
|
76
|
+
- [Restoring Files with Forbidden Characters in Their Names](#restoring-files-with-forbidden-characters-in-their-names)
|
|
77
|
+
- [Backups: Safe and Fully Functional](#backups-safe-and-fully-functional)
|
|
78
|
+
- [Restores via CLI: Limited by Sanitizer](#restores-via-cli-limited-by-sanitizer)
|
|
79
|
+
- [Workaround: Use `dar` Directly](#workaround-use-dar-directly)
|
|
80
|
+
- [Example: Manual Restore Using `dar`](#example-manual-restore-using-dar)
|
|
81
|
+
- [🧪 How to Locate Files with Forbidden Characters](#-how-to-locate-files-with-forbidden-characters)
|
|
82
|
+
- [Summary](#summary)
|
|
83
|
+
- [Merge FULL with DIFF, creating new FULL](#merge-full-with-diff-creating-new-full)
|
|
84
|
+
- [dar manager databases](#dar-manager-databases)
|
|
85
|
+
- [Performance tip due to par2](#performance-tip-due-to-par2)
|
|
86
|
+
- [.darrc sets -vd -vf (since v0.6.4)](#darrc-sets--vd--vf-since-v064)
|
|
87
|
+
- [Separate log file for command output](#separate-log-file-for-command-output)
|
|
88
|
+
- [Skipping cache directories](#skipping-cache-directories)
|
|
89
|
+
- [Progress bar and current directory](#progress-bar-and-current-directory)
|
|
90
|
+
- [Shell autocompletion](#shell-autocompletion)
|
|
91
|
+
- [Use it](#use-it)
|
|
92
|
+
- [Archive name completion (smart, context-aware)](#archive-name-completion-smart-context-aware)
|
|
93
|
+
- [Enabling Bash completion](#enabling-bash-completion)
|
|
94
|
+
- [Enable Zsh Completion](#enable-zsh-completion)
|
|
77
95
|
- [Easy development setup](#easy-development-setup)
|
|
78
|
-
- [Todo](#todo)
|
|
79
|
-
- [Known Limitations / Edge Cases](#known-limitations--edge-cases)
|
|
80
|
-
- [
|
|
81
|
-
- [
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
96
|
+
- [Todo](#todo)
|
|
97
|
+
- [Known Limitations / Edge Cases](#known-limitations--edge-cases)
|
|
98
|
+
- [Projects these scripts benefit from](#projects-these-scripts-benefit-from)
|
|
99
|
+
- [Reference](#reference)
|
|
100
|
+
- [CLI Tools Overview](#cli-tools-overview)
|
|
101
|
+
- [test coverage](#test-coverage)
|
|
102
|
+
- [Dar-backup options](#dar-backup-options)
|
|
103
|
+
- [Manager Options](#manager-options)
|
|
104
|
+
- [Cleanup options](#cleanup-options)
|
|
105
|
+
- [Clean-log options](#clean-log-options)
|
|
106
|
+
- [Dar-backup-systemd options](#dar-backup-systemd-options)
|
|
107
|
+
- [Installer options](#installer-options)
|
|
108
|
+
- [Demo options](#demo-options)
|
|
90
109
|
|
|
91
110
|
## My use case
|
|
92
111
|
|
|
@@ -1183,6 +1202,109 @@ where "c" is create, -r5 is 5% redundency and -n1 is 1 redundency file
|
|
|
1183
1202
|
|
|
1184
1203
|
## Points of interest
|
|
1185
1204
|
|
|
1205
|
+
### Limitations on File Names with Special Characters
|
|
1206
|
+
|
|
1207
|
+
`dar-backup` strictly validates all command-line arguments passed to its internal execution engine to protect against command injection and shell-based attacks. As part of this security measure, certain characters are disallowed in user-provided inputs — particularly those that carry special meaning in shell environments:
|
|
1208
|
+
|
|
1209
|
+
Disallowed characters include:
|
|
1210
|
+
|
|
1211
|
+
```text
|
|
1212
|
+
\$ & ; | > < ` \n
|
|
1213
|
+
```
|
|
1214
|
+
|
|
1215
|
+
#### Why this matters
|
|
1216
|
+
|
|
1217
|
+
When restoring specific files using the --selection argument or similar mechanisms, filenames that contain one or more of these characters (e.g., file_with_currency$.txt) cannot be safely passed as command-line arguments. As a result, attempting to restore such a file by name using the CLI will result in a validation error.
|
|
1218
|
+
|
|
1219
|
+
✅ Backups and Restores Still Work
|
|
1220
|
+
|
|
1221
|
+
✅ These files are still backed up and restored automatically as part of normal FULL, DIFF, or INCR operations.
|
|
1222
|
+
|
|
1223
|
+
❌ They cannot be explicitly specified for restore using CLI options like --selection="-g path/to/file_with_currency$.txt".
|
|
1224
|
+
|
|
1225
|
+
#### Workarounds
|
|
1226
|
+
|
|
1227
|
+
If you need to restore such a file:
|
|
1228
|
+
|
|
1229
|
+
Perform a restore of the entire directory using a more general selection (e.g., --selection="-g path/to/parent-directory").
|
|
1230
|
+
|
|
1231
|
+
Manually retrieve the restored file afterward.
|
|
1232
|
+
|
|
1233
|
+
##### Restoring Files with Forbidden Characters in Their Names
|
|
1234
|
+
|
|
1235
|
+
The DAR Backup system enforces a strict command-line argument sanitizer to improve security and prevent shell injection attacks. As a result, certain characters are **not allowed** in filenames or arguments passed to the CLI, especially during restore operations. This includes characters like:
|
|
1236
|
+
|
|
1237
|
+
| Character | Reason Blocked |
|
|
1238
|
+
|----------:|---------------------------------|
|
|
1239
|
+
| `;` | Shell command separator |
|
|
1240
|
+
| `&` | Background execution operator |
|
|
1241
|
+
| `\|` | Pipe operator |
|
|
1242
|
+
| `<` / `>` | Redirection operators |
|
|
1243
|
+
| `#` | Shell comment |
|
|
1244
|
+
| `` ` `` | Command substitution |
|
|
1245
|
+
| `"` / `'` | Quoting that may be unbalanced |
|
|
1246
|
+
|
|
1247
|
+
However, **backups of files with such names still work** — they are preserved correctly within the archive. The limitation only applies to **invoking restore commands via the CLI**, where such filenames cannot be safely passed as arguments.
|
|
1248
|
+
|
|
1249
|
+
##### Backups: Safe and Fully Functional
|
|
1250
|
+
|
|
1251
|
+
Files with special characters in their names **are backed up without issue**. The only issue you might encounter is restoring a file and giving the file name on the command line (with forbidden characters.)
|
|
1252
|
+
|
|
1253
|
+
##### Restores via CLI: Limited by Sanitizer
|
|
1254
|
+
|
|
1255
|
+
Attempting to restore such files via:
|
|
1256
|
+
|
|
1257
|
+
```bash
|
|
1258
|
+
dar-backup restore --file "weird#name.txt"
|
|
1259
|
+
```
|
|
1260
|
+
|
|
1261
|
+
...will fail with an error like:
|
|
1262
|
+
|
|
1263
|
+
```bash
|
|
1264
|
+
Unsafe argument detected: weird#name.txt
|
|
1265
|
+
```
|
|
1266
|
+
|
|
1267
|
+
---
|
|
1268
|
+
|
|
1269
|
+
##### Workaround: Use `dar` Directly
|
|
1270
|
+
|
|
1271
|
+
You can always restore the file manually using the `dar` command-line utility itself, bypassing any CLI restrictions imposed by the backup tool.
|
|
1272
|
+
|
|
1273
|
+
##### Example: Manual Restore Using `dar`
|
|
1274
|
+
|
|
1275
|
+
```bash
|
|
1276
|
+
dar -x /path/to/backup/example -g "weird#name.txt"
|
|
1277
|
+
```
|
|
1278
|
+
|
|
1279
|
+
Where:
|
|
1280
|
+
|
|
1281
|
+
- `/path/to/backup/example` is the base name of the archive (without `.dar`, `.1.dar`, etc.).
|
|
1282
|
+
- `"weird#name.txt"` is the exact filename with the special character(s).
|
|
1283
|
+
|
|
1284
|
+
You may need to quote the argument or escape characters depending on your shell.
|
|
1285
|
+
|
|
1286
|
+
---
|
|
1287
|
+
|
|
1288
|
+
##### 🧪 How to Locate Files with Forbidden Characters
|
|
1289
|
+
|
|
1290
|
+
To search for such files inside the archive:
|
|
1291
|
+
|
|
1292
|
+
```bash
|
|
1293
|
+
dar -l /path/to/backup/example | grep '[#;<>|&]'
|
|
1294
|
+
```
|
|
1295
|
+
|
|
1296
|
+
This will help you identify files that require manual restoration.
|
|
1297
|
+
|
|
1298
|
+
---
|
|
1299
|
+
|
|
1300
|
+
#### Summary
|
|
1301
|
+
|
|
1302
|
+
- 🚫 Forbidden characters are blocked **only** in CLI arguments to maintain safety.
|
|
1303
|
+
- ✅ Files containing these characters are **still archived and restorable**.
|
|
1304
|
+
- 🛠 Use `dar` directly for full manual control when restoring such files.
|
|
1305
|
+
|
|
1306
|
+
|
|
1307
|
+
|
|
1186
1308
|
### Merge FULL with DIFF, creating new FULL
|
|
1187
1309
|
|
|
1188
1310
|
Over time, the DIFF archives become larger and larger. At some point one wishes to create a new FULL archive to do DIFF's on.
|
|
@@ -1516,12 +1638,18 @@ Available options:
|
|
|
1516
1638
|
--list-contents <archive> List the contents of a specified archive.
|
|
1517
1639
|
--selection <params> Define file selection for listing/restoring.
|
|
1518
1640
|
--restore <archive> Restore a specified archive.
|
|
1519
|
-
-r, --restore
|
|
1641
|
+
-r, --restore <archive> Restore archive.
|
|
1642
|
+
--restore-dir Directory on which to restore
|
|
1520
1643
|
--verbose Enable verbose output.
|
|
1521
1644
|
--suppress-dar-msg Filter out this from the darrc: "-vt", "-vs", "-vd", "-vf", "-va"
|
|
1522
1645
|
--log-level <level> `debug` or `trace`, default is `info`.
|
|
1523
1646
|
--log-stdout Also print log messages to stdout.
|
|
1524
1647
|
--do-not-compare Do not compare restores to file system.
|
|
1648
|
+
--examples Show examples of using dar-backup.
|
|
1649
|
+
--readme Print README.md and exit
|
|
1650
|
+
--readme-pretty Print README.md with Markdown styling and exit
|
|
1651
|
+
--changelog Print Changelog and exit
|
|
1652
|
+
--changelog-pretty Print Changelog with Markdown styling and exit
|
|
1525
1653
|
-v, --version Show version and license information.
|
|
1526
1654
|
```
|
|
1527
1655
|
|
dar_backup/__about__.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
__version__ = "0.8.
|
|
1
|
+
__version__ = "0.8.3"
|
|
2
2
|
|
|
3
3
|
__license__ = '''Licensed under GNU GENERAL PUBLIC LICENSE v3, see the supplied file "LICENSE" for details.
|
|
4
4
|
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW, not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
dar_backup/command_runner.py
CHANGED
|
@@ -5,33 +5,76 @@ import logging
|
|
|
5
5
|
import traceback
|
|
6
6
|
import threading
|
|
7
7
|
import os
|
|
8
|
+
import re
|
|
9
|
+
import shlex
|
|
8
10
|
import sys
|
|
9
11
|
import tempfile
|
|
10
12
|
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../src")))
|
|
11
|
-
from typing import List, Optional
|
|
13
|
+
from typing import List, Optional, Union
|
|
12
14
|
from dar_backup.util import get_logger
|
|
13
15
|
|
|
14
16
|
|
|
17
|
+
def is_safe_arg(arg: str) -> bool:
|
|
18
|
+
"""
|
|
19
|
+
Check if the argument is safe by rejecting dangerous shell characters.
|
|
20
|
+
"""
|
|
21
|
+
return not re.search(r'[;&|><`$\n]', arg)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def sanitize_cmd(cmd: List[str]) -> List[str]:
|
|
25
|
+
"""
|
|
26
|
+
Validate and sanitize a list of command-line arguments.
|
|
27
|
+
Ensures all elements are strings and do not contain dangerous shell characters.
|
|
28
|
+
Raises ValueError if any argument is unsafe.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
if not isinstance(cmd, list):
|
|
32
|
+
raise ValueError("Command must be a list of strings")
|
|
33
|
+
for arg in cmd:
|
|
34
|
+
if not isinstance(arg, str):
|
|
35
|
+
raise ValueError(f"Invalid argument type: {arg} (must be string)")
|
|
36
|
+
if not is_safe_arg(arg):
|
|
37
|
+
raise ValueError(f"Unsafe argument detected: {arg}")
|
|
38
|
+
return cmd
|
|
39
|
+
|
|
40
|
+
def _safe_str(s):
|
|
41
|
+
if isinstance(s, bytes):
|
|
42
|
+
return f"<{len(s)} bytes of binary data>"
|
|
43
|
+
return s
|
|
44
|
+
|
|
45
|
+
|
|
15
46
|
class CommandResult:
|
|
16
|
-
def __init__(
|
|
47
|
+
def __init__(
|
|
48
|
+
self,
|
|
49
|
+
returncode: int,
|
|
50
|
+
stdout: Union[str, bytes],
|
|
51
|
+
stderr: Union[str, bytes],
|
|
52
|
+
stack: Optional[str] = None,
|
|
53
|
+
note: Optional[str] = None
|
|
54
|
+
):
|
|
17
55
|
self.returncode = returncode
|
|
18
56
|
self.stdout = stdout
|
|
19
57
|
self.stderr = stderr
|
|
20
58
|
self.stack = stack
|
|
59
|
+
self.note = note
|
|
60
|
+
|
|
61
|
+
|
|
21
62
|
|
|
22
63
|
def __repr__(self):
|
|
23
64
|
return f"<CommandResult returncode={self.returncode}\nstdout={self.stdout}\nstderr={self.stderr}\nstack={self.stack}>"
|
|
24
|
-
|
|
65
|
+
|
|
25
66
|
|
|
26
67
|
def __str__(self):
|
|
27
68
|
return (
|
|
28
|
-
|
|
69
|
+
"CommandResult:\n"
|
|
29
70
|
f" Return code: {self.returncode}\n"
|
|
30
|
-
f"
|
|
31
|
-
f"
|
|
32
|
-
f"
|
|
71
|
+
f" Note: {self.note if self.note else '<none>'}\n"
|
|
72
|
+
f" STDOUT: {_safe_str(self.stdout)}\n"
|
|
73
|
+
f" STDERR: {_safe_str(self.stderr)}\n"
|
|
74
|
+
f" Stacktrace: {self.stack if self.stack else '<none>'}"
|
|
33
75
|
)
|
|
34
76
|
|
|
77
|
+
|
|
35
78
|
class CommandRunner:
|
|
36
79
|
def __init__(
|
|
37
80
|
self,
|
|
@@ -46,6 +89,7 @@ class CommandRunner:
|
|
|
46
89
|
if not self.logger or not self.command_logger:
|
|
47
90
|
self.logger_fallback()
|
|
48
91
|
|
|
92
|
+
|
|
49
93
|
def logger_fallback(self):
|
|
50
94
|
"""
|
|
51
95
|
Setup temporary log files
|
|
@@ -83,9 +127,31 @@ class CommandRunner:
|
|
|
83
127
|
capture_output: bool = True,
|
|
84
128
|
text: bool = True
|
|
85
129
|
) -> CommandResult:
|
|
130
|
+
self._text_mode = text
|
|
86
131
|
timeout = timeout or self.default_timeout
|
|
87
132
|
|
|
88
|
-
|
|
133
|
+
cmd_sanitized = None
|
|
134
|
+
|
|
135
|
+
try:
|
|
136
|
+
cmd_sanitized = sanitize_cmd(cmd)
|
|
137
|
+
except ValueError as e:
|
|
138
|
+
stack = traceback.format_exc()
|
|
139
|
+
self.logger.error(f"Command sanitation failed: {e}")
|
|
140
|
+
return CommandResult(
|
|
141
|
+
returncode=-1,
|
|
142
|
+
note=f"Sanitizing failed: command: {' '.join(cmd)}",
|
|
143
|
+
stdout='',
|
|
144
|
+
stderr=str(e),
|
|
145
|
+
stack=stack,
|
|
146
|
+
|
|
147
|
+
)
|
|
148
|
+
finally:
|
|
149
|
+
cmd = cmd_sanitized
|
|
150
|
+
|
|
151
|
+
#command = f"Executing command: {' '.join(cmd)} (timeout={timeout}s)"
|
|
152
|
+
command = f"Executing command: {' '.join(shlex.quote(arg) for arg in cmd)} (timeout={timeout}s)"
|
|
153
|
+
|
|
154
|
+
|
|
89
155
|
self.command_logger.info(command)
|
|
90
156
|
self.logger.debug(command)
|
|
91
157
|
|
|
@@ -115,9 +181,13 @@ class CommandRunner:
|
|
|
115
181
|
chunk = stream.read(1024)
|
|
116
182
|
if not chunk:
|
|
117
183
|
break
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
184
|
+
if self._text_mode:
|
|
185
|
+
decoded = chunk.decode('utf-8', errors='replace')
|
|
186
|
+
lines.append(decoded)
|
|
187
|
+
self.command_logger.log(level, decoded.strip())
|
|
188
|
+
else:
|
|
189
|
+
lines.append(chunk)
|
|
190
|
+
# Avoid logging raw binary data to prevent garbled logs
|
|
121
191
|
except Exception as e:
|
|
122
192
|
self.logger.warning(f"stream_output decode error: {e}")
|
|
123
193
|
finally:
|
|
@@ -139,29 +209,40 @@ class CommandRunner:
|
|
|
139
209
|
process.wait(timeout=timeout)
|
|
140
210
|
except subprocess.TimeoutExpired:
|
|
141
211
|
process.kill()
|
|
142
|
-
|
|
143
|
-
|
|
212
|
+
log_msg = f"Command timed out after {timeout} seconds: {' '.join(cmd)}:\n"
|
|
213
|
+
self.logger.error(log_msg)
|
|
214
|
+
return CommandResult(-1, ''.join(stdout_lines), log_msg.join(stderr_lines))
|
|
144
215
|
except Exception as e:
|
|
145
216
|
stack = traceback.format_exc()
|
|
146
|
-
|
|
147
|
-
|
|
217
|
+
log_msg = f"Command execution failed: {' '.join(cmd)} with error: {e}\n"
|
|
218
|
+
self.logger.error(log_msg)
|
|
219
|
+
return CommandResult(-1, ''.join(stdout_lines), log_msg.join(stderr_lines), stack)
|
|
148
220
|
|
|
149
221
|
for t in threads:
|
|
150
222
|
t.join()
|
|
151
223
|
|
|
152
224
|
|
|
225
|
+
|
|
226
|
+
if self._text_mode:
|
|
227
|
+
stdout_combined = ''.join(stdout_lines)
|
|
228
|
+
stderr_combined = ''.join(stderr_lines)
|
|
229
|
+
else:
|
|
230
|
+
stdout_combined = b''.join(stdout_lines)
|
|
231
|
+
stderr_combined = b''.join(stderr_lines)
|
|
232
|
+
|
|
233
|
+
|
|
153
234
|
if check and process.returncode != 0:
|
|
154
235
|
self.logger.error(f"Command failed with exit code {process.returncode}")
|
|
155
236
|
return CommandResult(
|
|
156
237
|
process.returncode,
|
|
157
|
-
|
|
158
|
-
|
|
238
|
+
stdout_combined,
|
|
239
|
+
stderr_combined,
|
|
159
240
|
stack=traceback.format_stack()
|
|
160
241
|
)
|
|
161
242
|
|
|
162
243
|
return CommandResult(
|
|
163
244
|
process.returncode,
|
|
164
|
-
|
|
165
|
-
|
|
245
|
+
stdout_combined,
|
|
246
|
+
stderr_combined
|
|
166
247
|
)
|
|
167
248
|
|
dar_backup/dar_backup.py
CHANGED
|
@@ -248,7 +248,7 @@ def verify(args: argparse.Namespace, backup_file: str, backup_definition: str, c
|
|
|
248
248
|
PermissionError: If a permission error occurs while comparing files.
|
|
249
249
|
"""
|
|
250
250
|
result = True
|
|
251
|
-
command = ['dar', '-t', backup_file, '-Q']
|
|
251
|
+
command = ['dar', '-t', backup_file, '-N', '-Q']
|
|
252
252
|
|
|
253
253
|
|
|
254
254
|
log_basename = os.path. dirname(config_settings.logfile_location)
|
|
@@ -315,7 +315,7 @@ def verify(args: argparse.Namespace, backup_file: str, backup_definition: str, c
|
|
|
315
315
|
for restored_file_path in random_files:
|
|
316
316
|
try:
|
|
317
317
|
args.verbose and logger.info(f"Restoring file: '{restored_file_path}' from backup to: '{config_settings.test_restore_dir}' for file comparing")
|
|
318
|
-
command = ['dar', '-x', backup_file, '-g', restored_file_path.lstrip("/"), '-R', config_settings.test_restore_dir, '-Q', '-B', args.darrc, 'restore-options']
|
|
318
|
+
command = ['dar', '-x', backup_file, '-g', restored_file_path.lstrip("/"), '-R', config_settings.test_restore_dir, '--noconf', '-Q', '-B', args.darrc, 'restore-options']
|
|
319
319
|
args.verbose and logger.info(f"Running command: {' '.join(map(shlex.quote, command))}")
|
|
320
320
|
process = runner.run(command, timeout = config_settings.command_timeout_secs)
|
|
321
321
|
if process.returncode != 0:
|
|
@@ -347,7 +347,7 @@ def restore_backup(backup_name: str, config_settings: ConfigSettings, restore_di
|
|
|
347
347
|
results: List[tuple] = []
|
|
348
348
|
try:
|
|
349
349
|
backup_file = os.path.join(config_settings.backup_dir, backup_name)
|
|
350
|
-
command = ['dar', '-x', backup_file, '-Q', '-D']
|
|
350
|
+
command = ['dar', '-x', backup_file, '-wa', '-/ Oo', '--noconf', '-Q', '-D']
|
|
351
351
|
if restore_dir:
|
|
352
352
|
if not os.path.exists(restore_dir):
|
|
353
353
|
os.makedirs(restore_dir)
|
|
@@ -390,7 +390,7 @@ def get_backed_up_files(backup_name: str, backup_dir: str):
|
|
|
390
390
|
logger.debug(f"Getting backed up files in xml from DAR archive: '{backup_name}'")
|
|
391
391
|
backup_path = os.path.join(backup_dir, backup_name)
|
|
392
392
|
try:
|
|
393
|
-
command = ['dar', '-l', backup_path, '-am', '-as', "-Txml" , '-Q']
|
|
393
|
+
command = ['dar', '-l', backup_path, '--noconf', '-am', '-as', "-Txml" , '-Q']
|
|
394
394
|
logger.debug(f"Running command: {' '.join(map(shlex.quote, command))}")
|
|
395
395
|
command_result = runner.run(command)
|
|
396
396
|
# Parse the XML data
|
|
@@ -418,7 +418,7 @@ def list_contents(backup_name, backup_dir, selection=None):
|
|
|
418
418
|
backup_path = os.path.join(backup_dir, backup_name)
|
|
419
419
|
|
|
420
420
|
try:
|
|
421
|
-
command = ['dar', '-l', backup_path, '-am', '-as', '-Q']
|
|
421
|
+
command = ['dar', '-l', backup_path, '--noconf', '-am', '-as', '-Q']
|
|
422
422
|
if selection:
|
|
423
423
|
selection_criteria = shlex.split(selection)
|
|
424
424
|
command.extend(selection_criteria)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dar-backup
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.3
|
|
4
4
|
Summary: A script to do full, differential and incremental backups using dar. Some files are restored from the backups during verification, after which par2 redundancy files are created. The script also has a cleanup feature to remove old backups and par2 files.
|
|
5
5
|
Project-URL: GPG Public Key, https://keys.openpgp.org/search?q=dar-backup@pm.me
|
|
6
6
|
Project-URL: Homepage, https://github.com/per2jensen/dar-backup/tree/main/v2
|
|
@@ -740,71 +740,90 @@ This is the `Python` based [**version 2**](https://github.com/per2jensen/dar-bac
|
|
|
740
740
|
|
|
741
741
|
## Table of Contents
|
|
742
742
|
|
|
743
|
-
- [
|
|
744
|
-
- [
|
|
745
|
-
- [
|
|
746
|
-
- [
|
|
747
|
-
- [
|
|
748
|
-
- [
|
|
749
|
-
- [
|
|
750
|
-
- [
|
|
751
|
-
|
|
752
|
-
- [
|
|
753
|
-
- [
|
|
754
|
-
- [
|
|
755
|
-
- [
|
|
756
|
-
- [
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
- [
|
|
761
|
-
|
|
762
|
-
- [
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
- [
|
|
743
|
+
- [`dar-backup`](#dar-backup)
|
|
744
|
+
- [TL;DR](#tldr)
|
|
745
|
+
- [Table of Contents](#table-of-contents)
|
|
746
|
+
- [My use case](#my-use-case)
|
|
747
|
+
- [Features](#features)
|
|
748
|
+
- [License](#license)
|
|
749
|
+
- [Quick Guide](#quick-guide)
|
|
750
|
+
- [Status](#status)
|
|
751
|
+
- [GPG Signing key](#gpg-signing-key)
|
|
752
|
+
- [Breaking change in version 0.6.0](#breaking-change-in-version-060)
|
|
753
|
+
- [Homepage - Github](#homepage---github)
|
|
754
|
+
- [Community](#community)
|
|
755
|
+
- [Requirements](#requirements)
|
|
756
|
+
- [dar-backup principles](#dar-backup-principles)
|
|
757
|
+
- [dar-backup](#dar-backup-1)
|
|
758
|
+
- [cleanup](#cleanup)
|
|
759
|
+
- [manager](#manager)
|
|
760
|
+
- [How to run](#how-to-run)
|
|
761
|
+
- [1 - installation](#1---installation)
|
|
762
|
+
- [2 - configuration](#2---configuration)
|
|
763
|
+
- [3 - generate catalog databases](#3---generate-catalog-databases)
|
|
764
|
+
- [4 - give dar-backup a spin](#4---give-dar-backup-a-spin)
|
|
765
|
+
- [5 - deactivate venv](#5---deactivate-venv)
|
|
766
|
+
- [Config](#config)
|
|
767
|
+
- [Config file](#config-file)
|
|
768
|
+
- [.darrc](#darrc)
|
|
769
|
+
- [Backup definition example](#backup-definition-example)
|
|
767
770
|
- [Generate systemd files](#generate-systemd-files)
|
|
768
|
-
- [
|
|
769
|
-
- [
|
|
770
|
-
- [
|
|
771
|
-
- [
|
|
772
|
-
- [
|
|
773
|
-
- [
|
|
774
|
-
|
|
775
|
-
- [
|
|
776
|
-
- [
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
- [
|
|
784
|
-
- [Par2
|
|
785
|
-
|
|
786
|
-
- [
|
|
787
|
-
- [
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
771
|
+
- [Systemctl examples](#systemctl-examples)
|
|
772
|
+
- [Service: dar-backup --incremental-backup](#service-dar-backup---incremental-backup)
|
|
773
|
+
- [Timer: dar-backup --incremental-backup](#timer-dar-backup---incremental-backup)
|
|
774
|
+
- [systemd timer note](#systemd-timer-note)
|
|
775
|
+
- [list contents of an archive](#list-contents-of-an-archive)
|
|
776
|
+
- [dar file selection examples](#dar-file-selection-examples)
|
|
777
|
+
- [select a directory](#select-a-directory)
|
|
778
|
+
- [select files with "Z50" in the file name and exclude .xmp files](#select-files-with-z50-in-the-file-name-and-exclude-xmp-files)
|
|
779
|
+
- [Restoring](#restoring)
|
|
780
|
+
- [default location for restores](#default-location-for-restores)
|
|
781
|
+
- [--restore-dir option](#--restore-dir-option)
|
|
782
|
+
- [a single file](#a-single-file)
|
|
783
|
+
- [a directory](#a-directory)
|
|
784
|
+
- [.NEF from a specific date](#nef-from-a-specific-date)
|
|
785
|
+
- [restore test fails with exit code 4](#restore-test-fails-with-exit-code-4)
|
|
786
|
+
- [restore test fails with exit code 5](#restore-test-fails-with-exit-code-5)
|
|
787
|
+
- [Par2](#par2)
|
|
788
|
+
- [Par2 to verify/repair](#par2-to-verifyrepair)
|
|
789
|
+
- [Par2 create redundancy files](#par2-create-redundancy-files)
|
|
790
|
+
- [Points of interest](#points-of-interest)
|
|
791
|
+
- [Limitations on File Names with Special Characters](#limitations-on-file-names-with-special-characters)
|
|
792
|
+
- [Why this matters](#why-this-matters)
|
|
793
|
+
- [Workarounds](#workarounds)
|
|
794
|
+
- [Restoring Files with Forbidden Characters in Their Names](#restoring-files-with-forbidden-characters-in-their-names)
|
|
795
|
+
- [Backups: Safe and Fully Functional](#backups-safe-and-fully-functional)
|
|
796
|
+
- [Restores via CLI: Limited by Sanitizer](#restores-via-cli-limited-by-sanitizer)
|
|
797
|
+
- [Workaround: Use `dar` Directly](#workaround-use-dar-directly)
|
|
798
|
+
- [Example: Manual Restore Using `dar`](#example-manual-restore-using-dar)
|
|
799
|
+
- [🧪 How to Locate Files with Forbidden Characters](#-how-to-locate-files-with-forbidden-characters)
|
|
800
|
+
- [Summary](#summary)
|
|
801
|
+
- [Merge FULL with DIFF, creating new FULL](#merge-full-with-diff-creating-new-full)
|
|
802
|
+
- [dar manager databases](#dar-manager-databases)
|
|
803
|
+
- [Performance tip due to par2](#performance-tip-due-to-par2)
|
|
804
|
+
- [.darrc sets -vd -vf (since v0.6.4)](#darrc-sets--vd--vf-since-v064)
|
|
805
|
+
- [Separate log file for command output](#separate-log-file-for-command-output)
|
|
806
|
+
- [Skipping cache directories](#skipping-cache-directories)
|
|
807
|
+
- [Progress bar and current directory](#progress-bar-and-current-directory)
|
|
808
|
+
- [Shell autocompletion](#shell-autocompletion)
|
|
809
|
+
- [Use it](#use-it)
|
|
810
|
+
- [Archive name completion (smart, context-aware)](#archive-name-completion-smart-context-aware)
|
|
811
|
+
- [Enabling Bash completion](#enabling-bash-completion)
|
|
812
|
+
- [Enable Zsh Completion](#enable-zsh-completion)
|
|
795
813
|
- [Easy development setup](#easy-development-setup)
|
|
796
|
-
- [Todo](#todo)
|
|
797
|
-
- [Known Limitations / Edge Cases](#known-limitations--edge-cases)
|
|
798
|
-
- [
|
|
799
|
-
- [
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
814
|
+
- [Todo](#todo)
|
|
815
|
+
- [Known Limitations / Edge Cases](#known-limitations--edge-cases)
|
|
816
|
+
- [Projects these scripts benefit from](#projects-these-scripts-benefit-from)
|
|
817
|
+
- [Reference](#reference)
|
|
818
|
+
- [CLI Tools Overview](#cli-tools-overview)
|
|
819
|
+
- [test coverage](#test-coverage)
|
|
820
|
+
- [Dar-backup options](#dar-backup-options)
|
|
821
|
+
- [Manager Options](#manager-options)
|
|
822
|
+
- [Cleanup options](#cleanup-options)
|
|
823
|
+
- [Clean-log options](#clean-log-options)
|
|
824
|
+
- [Dar-backup-systemd options](#dar-backup-systemd-options)
|
|
825
|
+
- [Installer options](#installer-options)
|
|
826
|
+
- [Demo options](#demo-options)
|
|
808
827
|
|
|
809
828
|
## My use case
|
|
810
829
|
|
|
@@ -1901,6 +1920,109 @@ where "c" is create, -r5 is 5% redundency and -n1 is 1 redundency file
|
|
|
1901
1920
|
|
|
1902
1921
|
## Points of interest
|
|
1903
1922
|
|
|
1923
|
+
### Limitations on File Names with Special Characters
|
|
1924
|
+
|
|
1925
|
+
`dar-backup` strictly validates all command-line arguments passed to its internal execution engine to protect against command injection and shell-based attacks. As part of this security measure, certain characters are disallowed in user-provided inputs — particularly those that carry special meaning in shell environments:
|
|
1926
|
+
|
|
1927
|
+
Disallowed characters include:
|
|
1928
|
+
|
|
1929
|
+
```text
|
|
1930
|
+
\$ & ; | > < ` \n
|
|
1931
|
+
```
|
|
1932
|
+
|
|
1933
|
+
#### Why this matters
|
|
1934
|
+
|
|
1935
|
+
When restoring specific files using the --selection argument or similar mechanisms, filenames that contain one or more of these characters (e.g., file_with_currency$.txt) cannot be safely passed as command-line arguments. As a result, attempting to restore such a file by name using the CLI will result in a validation error.
|
|
1936
|
+
|
|
1937
|
+
✅ Backups and Restores Still Work
|
|
1938
|
+
|
|
1939
|
+
✅ These files are still backed up and restored automatically as part of normal FULL, DIFF, or INCR operations.
|
|
1940
|
+
|
|
1941
|
+
❌ They cannot be explicitly specified for restore using CLI options like --selection="-g path/to/file_with_currency$.txt".
|
|
1942
|
+
|
|
1943
|
+
#### Workarounds
|
|
1944
|
+
|
|
1945
|
+
If you need to restore such a file:
|
|
1946
|
+
|
|
1947
|
+
Perform a restore of the entire directory using a more general selection (e.g., --selection="-g path/to/parent-directory").
|
|
1948
|
+
|
|
1949
|
+
Manually retrieve the restored file afterward.
|
|
1950
|
+
|
|
1951
|
+
##### Restoring Files with Forbidden Characters in Their Names
|
|
1952
|
+
|
|
1953
|
+
The DAR Backup system enforces a strict command-line argument sanitizer to improve security and prevent shell injection attacks. As a result, certain characters are **not allowed** in filenames or arguments passed to the CLI, especially during restore operations. This includes characters like:
|
|
1954
|
+
|
|
1955
|
+
| Character | Reason Blocked |
|
|
1956
|
+
|----------:|---------------------------------|
|
|
1957
|
+
| `;` | Shell command separator |
|
|
1958
|
+
| `&` | Background execution operator |
|
|
1959
|
+
| `\|` | Pipe operator |
|
|
1960
|
+
| `<` / `>` | Redirection operators |
|
|
1961
|
+
| `#` | Shell comment |
|
|
1962
|
+
| `` ` `` | Command substitution |
|
|
1963
|
+
| `"` / `'` | Quoting that may be unbalanced |
|
|
1964
|
+
|
|
1965
|
+
However, **backups of files with such names still work** — they are preserved correctly within the archive. The limitation only applies to **invoking restore commands via the CLI**, where such filenames cannot be safely passed as arguments.
|
|
1966
|
+
|
|
1967
|
+
##### Backups: Safe and Fully Functional
|
|
1968
|
+
|
|
1969
|
+
Files with special characters in their names **are backed up without issue**. The only issue you might encounter is restoring a file and giving the file name on the command line (with forbidden characters.)
|
|
1970
|
+
|
|
1971
|
+
##### Restores via CLI: Limited by Sanitizer
|
|
1972
|
+
|
|
1973
|
+
Attempting to restore such files via:
|
|
1974
|
+
|
|
1975
|
+
```bash
|
|
1976
|
+
dar-backup restore --file "weird#name.txt"
|
|
1977
|
+
```
|
|
1978
|
+
|
|
1979
|
+
...will fail with an error like:
|
|
1980
|
+
|
|
1981
|
+
```bash
|
|
1982
|
+
Unsafe argument detected: weird#name.txt
|
|
1983
|
+
```
|
|
1984
|
+
|
|
1985
|
+
---
|
|
1986
|
+
|
|
1987
|
+
##### Workaround: Use `dar` Directly
|
|
1988
|
+
|
|
1989
|
+
You can always restore the file manually using the `dar` command-line utility itself, bypassing any CLI restrictions imposed by the backup tool.
|
|
1990
|
+
|
|
1991
|
+
##### Example: Manual Restore Using `dar`
|
|
1992
|
+
|
|
1993
|
+
```bash
|
|
1994
|
+
dar -x /path/to/backup/example -g "weird#name.txt"
|
|
1995
|
+
```
|
|
1996
|
+
|
|
1997
|
+
Where:
|
|
1998
|
+
|
|
1999
|
+
- `/path/to/backup/example` is the base name of the archive (without `.dar`, `.1.dar`, etc.).
|
|
2000
|
+
- `"weird#name.txt"` is the exact filename with the special character(s).
|
|
2001
|
+
|
|
2002
|
+
You may need to quote the argument or escape characters depending on your shell.
|
|
2003
|
+
|
|
2004
|
+
---
|
|
2005
|
+
|
|
2006
|
+
##### 🧪 How to Locate Files with Forbidden Characters
|
|
2007
|
+
|
|
2008
|
+
To search for such files inside the archive:
|
|
2009
|
+
|
|
2010
|
+
```bash
|
|
2011
|
+
dar -l /path/to/backup/example | grep '[#;<>|&]'
|
|
2012
|
+
```
|
|
2013
|
+
|
|
2014
|
+
This will help you identify files that require manual restoration.
|
|
2015
|
+
|
|
2016
|
+
---
|
|
2017
|
+
|
|
2018
|
+
#### Summary
|
|
2019
|
+
|
|
2020
|
+
- 🚫 Forbidden characters are blocked **only** in CLI arguments to maintain safety.
|
|
2021
|
+
- ✅ Files containing these characters are **still archived and restorable**.
|
|
2022
|
+
- 🛠 Use `dar` directly for full manual control when restoring such files.
|
|
2023
|
+
|
|
2024
|
+
|
|
2025
|
+
|
|
1904
2026
|
### Merge FULL with DIFF, creating new FULL
|
|
1905
2027
|
|
|
1906
2028
|
Over time, the DIFF archives become larger and larger. At some point one wishes to create a new FULL archive to do DIFF's on.
|
|
@@ -2234,12 +2356,18 @@ Available options:
|
|
|
2234
2356
|
--list-contents <archive> List the contents of a specified archive.
|
|
2235
2357
|
--selection <params> Define file selection for listing/restoring.
|
|
2236
2358
|
--restore <archive> Restore a specified archive.
|
|
2237
|
-
-r, --restore
|
|
2359
|
+
-r, --restore <archive> Restore archive.
|
|
2360
|
+
--restore-dir Directory on which to restore
|
|
2238
2361
|
--verbose Enable verbose output.
|
|
2239
2362
|
--suppress-dar-msg Filter out this from the darrc: "-vt", "-vs", "-vd", "-vf", "-va"
|
|
2240
2363
|
--log-level <level> `debug` or `trace`, default is `info`.
|
|
2241
2364
|
--log-stdout Also print log messages to stdout.
|
|
2242
2365
|
--do-not-compare Do not compare restores to file system.
|
|
2366
|
+
--examples Show examples of using dar-backup.
|
|
2367
|
+
--readme Print README.md and exit
|
|
2368
|
+
--readme-pretty Print README.md with Markdown styling and exit
|
|
2369
|
+
--changelog Print Changelog and exit
|
|
2370
|
+
--changelog-pretty Print Changelog with Markdown styling and exit
|
|
2243
2371
|
-v, --version Show version and license information.
|
|
2244
2372
|
```
|
|
2245
2373
|
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
dar_backup/.darrc,sha256=-aerqivZmOsW_XBCh9IfbYTUvw0GkzDSr3Vx4GcNB1g,2113
|
|
2
|
-
dar_backup/Changelog.md,sha256=
|
|
3
|
-
dar_backup/README.md,sha256=
|
|
4
|
-
dar_backup/__about__.py,sha256=
|
|
2
|
+
dar_backup/Changelog.md,sha256=bTVj2BamYKOHQtqVCf9D_YAwu_TrUR7cX3mkF4UUHRk,13383
|
|
3
|
+
dar_backup/README.md,sha256=NwxPE_rm54sPNlQIJIDkESzLhUy-1nW8Eu0XD3JiDCk,65675
|
|
4
|
+
dar_backup/__about__.py,sha256=KvK8jpeBGIXtEcfE_bSR6i55LW5IToi6U4J7zwfnIXc,344
|
|
5
5
|
dar_backup/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
6
|
dar_backup/clean_log.py,sha256=pmmyPmLWbm3_3sHwJt9V_xBwUF8v015iS17ypJAGAZ4,6023
|
|
7
7
|
dar_backup/cleanup.py,sha256=_ggDcpMCB1MhXStvYussp_PdGfhIFtEutT5BNrNkMSY,13297
|
|
8
|
-
dar_backup/command_runner.py,sha256=
|
|
8
|
+
dar_backup/command_runner.py,sha256=AeS8jqx2i6RX7UW6QZKvWEau3_MCGL181LvYCKFBdqg,7939
|
|
9
9
|
dar_backup/config_settings.py,sha256=2UAHvatrVO4ark6lCn2Q7qBvZN6DUMK2ftlNrKpzlWc,5792
|
|
10
10
|
dar_backup/dar-backup.conf,sha256=46V2zdvjj_aThFY11wWlffjmoiChYmatdf5DXCsmmao,1208
|
|
11
11
|
dar_backup/dar-backup.conf.j2,sha256=z3epGo6nB_Jh3liTOp93wJO_HKUsf7qghe9cdtFH7cY,2021
|
|
12
|
-
dar_backup/dar_backup.py,sha256=
|
|
12
|
+
dar_backup/dar_backup.py,sha256=wLF4W-bgTBqPBGViCpgy02qXy0ciebn5VpLY3glCQkg,43073
|
|
13
13
|
dar_backup/dar_backup_systemd.py,sha256=PwAc2H2J3hQLWpnC6Ib95NZYtB2G2NDgkSblfLj1n10,3875
|
|
14
14
|
dar_backup/demo.py,sha256=bxEq_nJwHuQydERPppkvhotg1fdwBX_CE33m5fX_kxw,7945
|
|
15
15
|
dar_backup/demo_backup_def.j2,sha256=hQW2Glp0QGV3Kt8cwjS0mpOCdyzjVlpgbgL6LpXTKJA,1793
|
|
@@ -18,8 +18,8 @@ dar_backup/installer.py,sha256=xSXh77qquIZbUTSY3AbhERQbS7bnrPE__M_yqpszdhM,6883
|
|
|
18
18
|
dar_backup/manager.py,sha256=d1zliFpSuWc8JhjKqLMC-xOhp5kSIcfeGkMZOVuZcM0,27143
|
|
19
19
|
dar_backup/rich_progress.py,sha256=SfwFxebBl6jnDQMUQr4McknkW1yQWaJVo1Ju1OD3okA,3221
|
|
20
20
|
dar_backup/util.py,sha256=iTOGsZyIdkvh9tIu7hD_IXi-9HO6GhVgqact5GGInEY,26063
|
|
21
|
-
dar_backup-0.8.
|
|
22
|
-
dar_backup-0.8.
|
|
23
|
-
dar_backup-0.8.
|
|
24
|
-
dar_backup-0.8.
|
|
25
|
-
dar_backup-0.8.
|
|
21
|
+
dar_backup-0.8.3.dist-info/METADATA,sha256=meBMdEXLKK7NxmJ2HpKOjEZ4WZ62imJWjPz4Z0Qkf6k,108366
|
|
22
|
+
dar_backup-0.8.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
23
|
+
dar_backup-0.8.3.dist-info/entry_points.txt,sha256=pOK9M8cHeAcGIatrYzkm_1O89kPk0enyYONALYjFBx4,286
|
|
24
|
+
dar_backup-0.8.3.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
25
|
+
dar_backup-0.8.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|