dar-backup 1.0.2__py3-none-any.whl → 1.1.0__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/README.md DELETED
@@ -1,2105 +0,0 @@
1
- <!-- markdownlint-disable MD024 -->
2
- # `dar-backup`
3
-
4
- **Reliable DAR backups, automated in clean Python**
5
-
6
- [![Codecov](https://codecov.io/gh/per2jensen/dar-backup/branch/main/graph/badge.svg)](https://codecov.io/gh/per2jensen/dar-backup)
7
- [![Snyk Vuln findings](https://snyk.io/test/github/per2jensen/dar-backup/badge.svg)](https://security.snyk.io/vuln/?search=dar-backup)
8
- ![CI](https://github.com/per2jensen/dar-backup/actions/workflows/py-tests.yml/badge.svg)
9
- [![PyPI version](https://img.shields.io/pypi/v/dar-backup.svg)](https://pypi.org/project/dar-backup/)
10
- [![PyPI downloads](https://img.shields.io/badge/dynamic/json?color=blue&label=PyPI%20downloads&query=total&url=https%3A%2F%2Fraw.githubusercontent.com%2Fper2jensen%2Fdar-backup%2Fmain%2Fdownloads.json)](https://pypi.org/project/dar-backup/)
11
- [![# clones](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/per2jensen/dar-backup/main/clonepulse/badge_clones.json)](https://github.com/per2jensen/dar-backup/blob/main/clonepulse/weekly_clones.png)
12
- [![Milestone](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/per2jensen/dar-backup/main/clonepulse/milestone_badge.json)](https://github.com/per2jensen/dar-backup/blob/main/clonepulse/weekly_clones.png) <sub>🎯 Stats powered by [ClonePulse](https://github.com/per2jensen/clonepulse)</sub>
13
-
14
- The wonderful 'dar' [Disk Archiver](https://github.com/Edrusb/DAR) is used for
15
- the heavy lifting, together with the [parchive](https://github.com/Parchive/par2cmdline) suite in these scripts.
16
-
17
- This is the `Python` based [**version 2**](v2) of `dar-backup`.
18
-
19
- You can see the [v2 Changelog](v2/Changelog.md) for details on features and progress.
20
-
21
- ## TL;DR
22
-
23
- `dar-backup` is a Python-powered CLI for creating and validating full, differential, and incremental backups using `dar` and `par2`. Designed for long-term restore integrity, even on user-space filesystems like FUSE.
24
-
25
- Version **1.0.0** was reached on October 9, 2025.
26
-
27
- ## Table of Contents
28
-
29
- - [`dar-backup`](#dar-backup)
30
- - [TL;DR](#tldr)
31
- - [Table of Contents](#table-of-contents)
32
- - [My use case](#my-use-case)
33
- - [My setup](#my-setup)
34
- - [Why PAR2 is especially good for portable / offsite copies](#why-par2-is-especially-good-for-portable--offsite-copies)
35
- - [Design choices](#design-choices)
36
- - [Features](#features)
37
- - [License](#license)
38
- - [Quick Guide](#quick-guide)
39
- - [Status](#status)
40
- - [GPG Signing key](#gpg-signing-key)
41
- - [Breaking change in version 0.6.0](#breaking-change-in-version-060)
42
- - [Homepage - Github](#homepage---github)
43
- - [Community](#community)
44
- - [Requirements](#requirements)
45
- - [dar-backup principles](#dar-backup-principles)
46
- - [dar-backup overview](#dar-backup-overview)
47
- - [dar-backup](#dar-backup-1)
48
- - [cleanup](#cleanup)
49
- - [manager](#manager)
50
- - [How to run](#how-to-run)
51
- - [1 - installation](#1---installation)
52
- - [2 - configuration](#2---configuration)
53
- - [3 - generate catalog databases](#3---generate-catalog-databases)
54
- - [4 - give dar-backup a spin](#4---give-dar-backup-a-spin)
55
- - [5 - deactivate venv](#5---deactivate-venv)
56
- - [Config](#config)
57
- - [Config file](#config-file)
58
- - [.darrc](#darrc)
59
- - [Backup definition example](#backup-definition-example)
60
- - [Generate systemd files](#generate-systemd-files)
61
- - [Systemctl examples](#systemctl-examples)
62
- - [Service: dar-backup --incremental-backup](#service-dar-backup---incremental-backup)
63
- - [Timer: dar-backup --incremental-backup](#timer-dar-backup---incremental-backup)
64
- - [systemd timer note](#systemd-timer-note)
65
- - [list contents of an archive](#list-contents-of-an-archive)
66
- - [dar file selection examples](#dar-file-selection-examples)
67
- - [select a directory](#select-a-directory)
68
- - [select files with "Z50" in the file name and exclude .xmp files](#select-files-with-z50-in-the-file-name-and-exclude-xmp-files)
69
- - [Restoring](#restoring)
70
- - [default location for restores](#default-location-for-restores)
71
- - [--restore-dir option](#--restore-dir-option)
72
- - [a single file](#a-single-file)
73
- - [a directory](#a-directory)
74
- - [.NEF from a specific date](#nef-from-a-specific-date)
75
- - [restore test fails with exit code 4](#restore-test-fails-with-exit-code-4)
76
- - [restore test fails with exit code 5](#restore-test-fails-with-exit-code-5)
77
- - [Par2](#par2)
78
- - [Par2 to verify/repair](#par2-to-verifyrepair)
79
- - [Par2 files kept with archives](#par2-files-kept-with-archives)
80
- - [Par2 files in separate directory](#par2-files-in-separate-directory)
81
- - [Par2 create redundancy files](#par2-create-redundancy-files)
82
- - [Points of interest](#points-of-interest)
83
- - [Limitations on File Names with Special Characters](#limitations-on-file-names-with-special-characters)
84
- - [Why this matters](#why-this-matters)
85
- - [Workarounds](#workarounds)
86
- - [Restoring Files with Forbidden Characters in Their Names](#restoring-files-with-forbidden-characters-in-their-names)
87
- - [Backups: Safe and Fully Functional](#backups-safe-and-fully-functional)
88
- - [Restores via CLI: Limited by Sanitizer](#restores-via-cli-limited-by-sanitizer)
89
- - [Workaround: Use `dar` Directly](#workaround-use-dar-directly)
90
- - [Example: Manual Restore Using `dar`](#example-manual-restore-using-dar)
91
- - [🧪 How to Locate Files with Forbidden Characters](#-how-to-locate-files-with-forbidden-characters)
92
- - [Summary](#summary)
93
- - [Merge FULL with DIFF, creating new FULL](#merge-full-with-diff-creating-new-full)
94
- - [dar manager databases](#dar-manager-databases)
95
- - [Performance tip due to par2](#performance-tip-due-to-par2)
96
- - [.darrc sets -vd -vf (since v0.6.4)](#darrc-sets--vd--vf-since-v064)
97
- - [Separate log file for command output](#separate-log-file-for-command-output)
98
- - [Trace Logging (Debug details)](#trace-logging-debug-details)
99
- - [Skipping cache directories](#skipping-cache-directories)
100
- - [Shell autocompletion](#shell-autocompletion)
101
- - [Use it](#use-it)
102
- - [Archive name completion (smart, context-aware)](#archive-name-completion-smart-context-aware)
103
- - [Enabling Bash completion](#enabling-bash-completion)
104
- - [Enable Zsh Completion](#enable-zsh-completion)
105
- - [Easy development setup](#easy-development-setup)
106
- - [Todo](#todo)
107
- - [Known Limitations / Edge Cases](#known-limitations--edge-cases)
108
- - [Projects these scripts benefit from](#projects-these-scripts-benefit-from)
109
- - [Reference](#reference)
110
- - [CLI Tools Overview](#cli-tools-overview)
111
- - [test coverage](#test-coverage)
112
- - [Dar-backup options](#dar-backup-options)
113
- - [Dar-backup exit codes](#dar-backup-exit-codes)
114
- - [Dar-backup env vars](#dar-backup-env-vars)
115
- - [Manager Options](#manager-options)
116
- - [Cleanup env vars](#cleanup-env-vars)
117
- - [Clean-log options](#clean-log-options)
118
- - [Dar-backup-systemd options](#dar-backup-systemd-options)
119
- - [Installer options](#installer-options)
120
- - [Demo options](#demo-options)
121
- - [Config changes](#config-changes)
122
- - [1.0.1](#101)
123
- - [DISCORD WEBHOOK](#discord-webhook)
124
- - [Restore test config](#restore-test-config)
125
- - [Par2](#par2-1)
126
- - [1.0.2](#102)
127
- - [Trace Logging](#trace-logging)
128
- - [Command output Capture](#command-output-capture)
129
-
130
- ## My use case
131
-
132
- I needed the following:
133
-
134
- - Backup my workstation to a remote server
135
- - Backup primarily photos, home made video and different types of documents
136
- - I have cloud storage mounted on a directory within my home dir. The filesystem is [FUSE based](https://www.kernel.org/doc/html/latest/filesystems/fuse.html), which gives it a few special features
137
-
138
- - Backup my cloud storage (cloud is convenient, but I want control over my backups)
139
- - A non-privileged user can perform a mount
140
- - A privileged user cannot look into the filesystem --> a backup script running as root is not suitable
141
-
142
- - Have a simple way of restoring, possibly years into the future. 'dar' fits that scenario with a single statically linked binary (kept with the archives). There is no need install/configure anything - restoring is simple and works well.
143
- - During backup archives must be tested and a restore test (however small) performed
144
- - Archives stored on a server with a reliable file system (easy to mount a directory over sshfs)
145
- - Easy to verify archive's integrity, after being moved around.
146
-
147
- I do not need the encryption features of dar, as all storage is already encrypted.
148
-
149
- ## My setup
150
-
151
- 1. Primary backup to server with an ext4 file system on mdadm RAID1
152
-
153
- 2. Secondary copies to multiple USB disks / cloud
154
-
155
- 3. Archive integrity verification anywhere using [Par2](#par2) and `dar -t`.
156
-
157
- 4. Archive repair anywhere if needed. By default `dar-backup` creates par2 redundancy files with 5% coverage. Enough to fix localized bitrot.
158
-
159
- 5. No dependency on original system
160
-
161
- ### Why PAR2 is especially good for portable / offsite copies
162
-
163
- PAR2 parity is:
164
-
165
- > Self-contained (travels with the data)
166
- >
167
- >Format-agnostic (works on any filesystem)
168
- >
169
- >Location-agnostic (local disk, USB, cloud object storage)
170
- >
171
- >Tool-stable (PAR2 spec has not changed in years)
172
- >
173
- >That means:
174
- >
175
- >**Integrity protection moves with the archive**.
176
-
177
- ### Design choices
178
-
179
- My design choices are boring, proven and pragmatic:
180
- >
181
- >mdadm handles disks
182
- >
183
- >PAR2 handles data integrity
184
- >
185
- >You control when and how verification happens
186
- >
187
- >Errors have a fair chance of being diagnosed and fixed, due to well known tooling.
188
- >
189
- >No hidden magic, no lock-in
190
-
191
- ## Features
192
-
193
- - The battle tested [dar](https://github.com/Edrusb/DAR) Disk Archiver is used for the actual backups - it comes highly recommended.
194
- - Backup with test of backup and (configurable) restore tests of files with comparison to source
195
- - [Redundancy files](#par2) created for patching bitrot of the archives (size configurable)
196
- - Simple [backup definitions](#backup-definition-example) defining what to backup (as many as you need)
197
- - [Backup catalogs](#dar-manager-databases) in databases, optionally on a disk different from the backups
198
- - Flexible and precise logging
199
- - Bash and zsh shell autocompletion for a nice CLI experience, [available completions](#shell-autocompletion):
200
-
201
- - Options for `dar-backup`, `cleanup`, `manager`
202
- - Backup definitions
203
- - Archives - filtered to backup definition if given
204
- - Catalogs - filtered to backup definition if given
205
-
206
- - `dar-backup` is easy to install and configure.
207
-
208
- - ✅ The author has used dar-backup since > 4 years, and has been saved multiple times.
209
-
210
- ## License
211
-
212
- These scripts are licensed under the GPLv3 license.
213
- Read more here: [GNU GPL3.0](https://www.gnu.org/licenses/gpl-3.0.en.html), or have a look at the ["LICENSE"](LICENSE) file in this repository.
214
-
215
- ## Quick Guide
216
-
217
- This purpose of this quick guide is to show how `dar-backup` works in a few simple steps.
218
-
219
- The package include a `demo`application, that can help you set up `dar-backup` quickly.
220
-
221
- > ⚠️ **Assumption**
222
- >
223
- > The demo program uses these directories in your home directory:
224
- >
225
- > - $HOME/dar-backup
226
- > - $HOME/.config/dar-backup
227
- >
228
- > It is assumed they **do not exist** before running the demo.
229
- >
230
- > Python **>= 3.9** is required
231
-
232
- <br>
233
-
234
- **Let's roll** with installation, backup, list backup content, restore & restore check
235
-
236
- The demo is known to work on an Ubuntu 24.04 clean VM as delivered from `Multipass`
237
-
238
- ```bash
239
- sudo apt -y install dar par2 python3 python3-venv
240
- INSTALL_DIR=/tmp/dar-backup
241
- mkdir "$INSTALL_DIR"
242
- cd "$INSTALL_DIR"
243
- python3 -m venv venv # create the virtual environment
244
- . venv/bin/activate # activate the virtual environment
245
- pip install dar-backup # run pip to install `dar-backup` into the virtual environment
246
- ```
247
-
248
- <details>
249
-
250
- <summary>🎯 Install details</summary>
251
-
252
- ```bash
253
- (venv) $ INSTALL_DIR=/tmp/dar-backup
254
- mkdir "$INSTALL_DIR"
255
- cd "$INSTALL_DIR"
256
- python3 -m venv venv # create the virtual environment
257
- . venv/bin/activate # activate the virtual environment
258
- pip install dar-backup # run pip to install `dar-backup`
259
- Collecting dar-backup
260
- Downloading dar_backup-0.6.21-py3-none-any.whl.metadata (88 kB)
261
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 88.5/88.5 kB 3.7 MB/s eta 0:00:00
262
- Collecting argcomplete>=3.6.2 (from dar-backup)
263
- Using cached argcomplete-3.6.2-py3-none-any.whl.metadata (16 kB)
264
- Collecting inputimeout>=1.0.4 (from dar-backup)
265
- Using cached inputimeout-1.0.4-py3-none-any.whl.metadata (2.2 kB)
266
- Collecting rich>=13.0.0 (from dar-backup)
267
- Using cached rich-14.0.0-py3-none-any.whl.metadata (18 kB)
268
- Collecting markdown-it-py>=2.2.0 (from rich>=13.0.0->dar-backup)
269
- Using cached markdown_it_py-3.0.0-py3-none-any.whl.metadata (6.9 kB)
270
- Collecting pygments<3.0.0,>=2.13.0 (from rich>=13.0.0->dar-backup)
271
- Using cached pygments-2.19.1-py3-none-any.whl.metadata (2.5 kB)
272
- Collecting mdurl~=0.1 (from markdown-it-py>=2.2.0->rich>=13.0.0->dar-backup)
273
- Using cached mdurl-0.1.2-py3-none-any.whl.metadata (1.6 kB)
274
- Downloading dar_backup-0.6.21-py3-none-any.whl (101 kB)
275
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 101.9/101.9 kB 16.2 MB/s eta 0:00:00
276
- Using cached argcomplete-3.6.2-py3-none-any.whl (43 kB)
277
- Using cached inputimeout-1.0.4-py3-none-any.whl (4.6 kB)
278
- Using cached rich-14.0.0-py3-none-any.whl (243 kB)
279
- Using cached markdown_it_py-3.0.0-py3-none-any.whl (87 kB)
280
- Using cached pygments-2.19.1-py3-none-any.whl (1.2 MB)
281
- Using cached mdurl-0.1.2-py3-none-any.whl (10.0 kB)
282
- Installing collected packages: pygments, mdurl, inputimeout, argcomplete, markdown-it-py, rich, dar-backup
283
- Successfully installed argcomplete-3.6.2 dar-backup-0.6.21 inputimeout-1.0.4 markdown-it-py-3.0.0 mdurl-0.1.2 pygments-2.19.1 rich-14.0.0
284
- ```
285
-
286
- </details>
287
-
288
- Setup the demo configurations and show a few operations
289
-
290
- <br>
291
-
292
- ```bash
293
- # See reference section for options tweaking the install
294
- demo --install
295
-
296
- # create catalog database
297
- manager --create-db
298
-
299
- # FULL backup as defined in backup definition `demo`
300
- dar-backup --full-backup
301
-
302
- # List the contents of the backup
303
- dar-backup --list-contents demo_FULL_$(date '+%F')
304
- ```
305
-
306
- <details>
307
-
308
- <summary>🎯 --list details</summary>
309
-
310
- ```bash
311
- (venv) $ demo --install
312
- Directories created.
313
- File generated at '/home/user/.config/dar-backup/backup.d/demo'
314
- File generated at '/home/user/.config/dar-backup/dar-backup.conf'
315
- 1. Now run `manager --create-db` to create the catalog database.
316
- 2. Then you can run `dar-backup --full-backup` to create a backup.
317
- 3. List backups with `dar-backup --list`
318
- 4. List contents of a backup with `dar-backup --list-contents <backup-name>`
319
-
320
-
321
-
322
- (venv) $ manager --create-db
323
- ========== Startup Settings ==========
324
- manager.py: 0.7.1
325
- Config file: /home/user/.config/dar-backup/dar-backup.conf
326
- Logfile: /home/user/dar-backup/dar-backup.log
327
- dar_manager: /home/user/.local/dar/bin/dar_manager
328
- dar_manager v.: 1.9.0
329
- ======================================
330
-
331
-
332
-
333
- (venv) $ dar-backup --full-backup
334
- ========== Startup Settings ==========
335
- dar-backup.py: 0.7.1
336
- dar path: /home/user/.local/dar/bin/dar
337
- dar version: 2.7.17
338
- Script directory: /home/user/git/dar-backup/v2/src/dar_backup
339
- Config file: /home/user/.config/dar-backup/dar-backup.conf
340
- .darrc location: /home/user/git/dar-backup/v2/src/dar_backup/.darrc
341
- ======================================
342
-
343
-
344
-
345
- (venv) $ dar-backup --list-contents demo_FULL_$(date '+%F')
346
- ========== Startup Settings ==========
347
- dar-backup.py: 0.7.1
348
- dar path: /home/user/.local/dar/bin/dar
349
- dar version: 2.7.17
350
- Script directory: /home/user/git/dar-backup/v2/src/dar_backup
351
- Config file: /home/user/.config/dar-backup/dar-backup.conf
352
- .darrc location: /home/user/git/dar-backup/v2/src/dar_backup/.darrc
353
- ======================================
354
- [Saved][-] [-L-][ 49%][ ] drwx------ user user 8 kio Sat May 17 13:13:59 2025 .config
355
- [Saved][-] [-L-][ 49%][ ] drwxrwxr-x user user 8 kio Tue May 6 20:55:40 2025 .config/dar-backup
356
- [Saved][-] [-L-][ 48%][ ] drwxrwxr-x user user 6 kio Sat May 17 13:26:21 2025 .config/dar-backup/backup.d
357
- [Saved][ ] [-L-][ 40%][ ] -rw-rw-r-- user user 764 o Sun Feb 23 21:23:01 2025 .config/dar-backup/backup.d/media-files
358
- [Saved][ ] [-L-][ 41%][ ] -rw-rw-r-- user user 933 o Sun Feb 23 21:23:15 2025 .config/dar-backup/backup.d/pCloudDrive
359
- [Saved][ ] [-L-][ 48%][ ] -rw-rw-r-- user user 1 kio Sun Mar 16 10:40:29 2025 .config/dar-backup/backup.d/test
360
- [Saved][ ] [-L-][ 48%][ ] -rw-rw-r-- user user 824 o Tue May 13 17:00:52 2025 .config/dar-backup/backup.d/default
361
- [Saved][ ] [-L-][ 48%][ ] -rw-rw-r-- user user 1 kio Sat May 3 10:40:33 2025 .config/dar-backup/backup.d/user-homedir
362
- [Saved][ ] [-L-][ 54%][ ] -rw-rw-r-- user user 1 kio Sat May 17 18:17:40 2025 .config/dar-backup/backup.d/demo
363
- [Saved][ ] [-L-][ 55%][ ] -rw-rw-r-- user user 1 kio Sat May 17 18:17:40 2025 .config/dar-backup/dar-backup.conf
364
- ```
365
-
366
- </details>
367
-
368
- <br>
369
-
370
- Perform a restore and show the restored files
371
-
372
- ```bash
373
- # Restore all files in the backup
374
- dar-backup --restore demo_FULL_$(date '+%F') --verbose
375
-
376
- # Prove the files have been restored to directory as configured
377
- find $HOME/dar-backup/restore
378
- ```
379
-
380
- <details>
381
-
382
- <summary>🎯 --restore details</summary>
383
-
384
- ```bash
385
- (venv) $ dar-backup --restore demo_FULL_$(date '+%F') --verbose
386
- ========== Startup Settings ==========
387
- dar-backup.py: 0.7.1
388
- dar path: /home/user/.local/dar/bin/dar
389
- dar version: 2.7.17
390
- Script directory: /home/user/git/dar-backup/v2/src/dar_backup
391
- Config file: /home/user/.config/dar-backup/dar-backup.conf
392
- .darrc location: /home/user/git/dar-backup/v2/src/dar_backup/.darrc
393
- Backup.d dir: /home/user/.config/dar-backup/backup.d
394
- Backup dir: /home/user/dar-backup/backups
395
- Restore dir: /home/user/dar-backup/restore
396
- Logfile location: /home/user/dar-backup/dar-backup.log
397
- PAR2 enabled: True
398
- --do-not-compare: False
399
- ======================================
400
-
401
-
402
-
403
- (venv) $ find ~/dar-backup/restore/
404
- /home/user/dar-backup/restore/
405
- /home/user/dar-backup/restore/.config
406
- /home/user/dar-backup/restore/.config/dar-backup
407
- /home/user/dar-backup/restore/.config/dar-backup/backup.d
408
- /home/user/dar-backup/restore/.config/dar-backup/backup.d/media-files
409
- /home/user/dar-backup/restore/.config/dar-backup/backup.d/pCloudDrive
410
- /home/user/dar-backup/restore/.config/dar-backup/backup.d/test
411
- /home/user/dar-backup/restore/.config/dar-backup/backup.d/default
412
- /home/user/dar-backup/restore/.config/dar-backup/backup.d/user-homedir
413
- /home/user/dar-backup/restore/.config/dar-backup/backup.d/demo
414
- /home/user/dar-backup/restore/.config/dar-backup/dar-backup.conf
415
- ```
416
-
417
- </details>
418
-
419
- <br>
420
-
421
- > ✅ **Next steps**
422
- >
423
- > Play with `demo's` options:
424
- >
425
- > - --root-dir (perhaps $HOME)
426
- > - --dir-to-backup (perhaps Pictures)
427
- > - --backup-dir (perhaps /media/user/big-disk)
428
- >
429
- > See log file: `cat "$HOME/dar-backup/dar-backup.log"`
430
- >
431
- > Checkout [systemd timers and services](#generate-systemd-files)
432
- >
433
- > Checkout [shell autocompletion (very nice !)](#shell-autocompletion)
434
- >
435
- > Checkout the [reference section](#reference)
436
-
437
- ## Status
438
- **1.0.0 milestone reached**
439
-
440
- October 9, 2025, I have promoted version 0.8.4 --> **1.0.0** after having added more test cases and seen no issues with 0.8.4.
441
-
442
- As of February 13, 2025, I have changed the status from alpha --> beta, as the featureset is in place and the alphas have worked well for a very long time.
443
-
444
- As of August 8, 2024 I am using the alpha versions of `dar-backup` (alpha-0.5.9 onwards) in my automated backup routine.
445
-
446
-
447
- ### GPG Signing key
448
-
449
- To increase the security and authenticity of dar-backup packages, all releases from v2-beta-0.6.18 onwards will be digitally signed using the GPG key below.
450
-
451
- <br>
452
-
453
- <details>
454
-
455
- <summary>🎯 GPG Signing Key Details</summary>
456
-
457
- ```text
458
- Name: Per Jensen (author of dar-backup)
459
- Email: dar-backup@pm.me
460
- Primary key: 4592 D739 6DBA EFFD 0845 02B8 5CCE C7E1 6814 A36E
461
- Signing key: B54F 5682 F28D BA36 22D7 8E04 58DB FADB BBAC 1BB1
462
- Created: 2025-03-29
463
- Expires: 2030-03-28
464
- Key type: ed25519 (primary, SC)
465
- Subkeys: ed25519 (S), ed25519 (A), cv25519 (E)
466
- ```
467
-
468
- <br>
469
-
470
- <details>
471
-
472
- <summary>🎯 Where to Find Release Signatures</summary>
473
-
474
- PyPI does *Not* host .asc Signature Files
475
-
476
- Although the `dar-backup` packages on PyPI are GPG-signed, PyPI itself does **not support uploading** .asc detached signature files alongside `.whl` and `.tar.gz` artifacts.
477
-
478
- Therefore, you will not find `.asc` files on PyPI.
479
-
480
- **Where to Get `.asc` Signature Files**
481
-
482
- You can always download the signed release artifacts and their `.asc` files from the official GitHub Releases page:
483
-
484
- 📁 GitHub Releases for `dar-backup`
485
-
486
- Each release includes:
487
-
488
- - `dar_backup-x.y.z.tar.gz`
489
-
490
- - `dar_backup-x.y.z.tar.gz.asc`
491
-
492
- - `dar_backup-x.y.z-py3-none-any.whl`
493
-
494
- - `dar_backup-x.y.z-py3-none-any.whl.asc`
495
-
496
- </details>
497
-
498
- <br>
499
-
500
- <details>
501
-
502
- <summary>🎯 How to Verify a Release from GitHub</summary>
503
-
504
- 1. Import the GPG public key:
505
-
506
- ```bash
507
- curl https://keys.openpgp.org/vks/v1/by-fingerprint/4592D7396DBAEFFD084502B85CCEC7E16814A36E | gpg --import
508
- ```
509
-
510
- 2. Download the wheel or tarball and its .asc signature from the GitHub.
511
-
512
- 3. Run GPG to verify it:
513
-
514
- ```bash
515
- gpg --verify dar_backup-x.y.z.tar.gz.asc dar_backup-x.y.z.tar.gz
516
- # or
517
- gpg --verify dar_backup-x.y.z-py3-none-any.whl.asc dar_backup-x.y.z-py3-none-any.whl
518
- ```
519
-
520
- 4. If the signature is valid, you'll see:
521
-
522
- ```text
523
- gpg: Good signature from "Per Jensen (author of dar-backup) <dar-backup@pm.me>"
524
- ```
525
-
526
- 🛡️ Reminder: Verify the signing subkey
527
-
528
- Only this subkey is used to sign PyPI packages:
529
-
530
- ```text
531
- B54F 5682 F28D BA36 22D7 8E04 58DB FADB BBAC 1BB1
532
- ```
533
-
534
- You can view it with:
535
-
536
- ```bash
537
- gpg --list-keys --with-subkey-fingerprints dar-backup@pm.me
538
- ```
539
-
540
- </details>
541
-
542
- </details>
543
-
544
- <br>
545
-
546
- ### Breaking change in version 0.6.0
547
-
548
- Version 0.6.0 and forwards requires the config variable *COMMAND_TIMEOUT_SECS* in the config file.
549
-
550
- ## Homepage - Github
551
-
552
- 'dar-backup' package lives here: [Github - dar-backup](https://github.com/per2jensen/dar-backup/tree/main/v2)
553
-
554
- This python version is v2 of dar-backup, v1 is made in bash.
555
-
556
- ## Community
557
-
558
- Please review the [Code of Conduct](CODE_OF_CONDUCT.md) to help keep this project welcoming and focused.
559
-
560
- ## Requirements
561
-
562
- - A linux system
563
- - dar
564
- - parchive (par2)
565
- - python3
566
- - python3-venv
567
-
568
- On Ubuntu, install the requirements this way:
569
-
570
- ```bash
571
- sudo apt install dar par2 python3 python3-venv
572
- ```
573
-
574
- ## dar-backup principles
575
-
576
- ### dar-backup overview
577
-
578
- [![dar-backup overview](v2/doc/dar-backup-overview-small.png)](v2/doc/dar-backup-overview.png)
579
-
580
- ### dar-backup
581
-
582
- `dar-backup` is built in a way that emphasizes getting backups. It loops over the [backup definitions](#backup-definition-example), and in the event of a failure while backing up a backup definition, dar-backup shall log an error and start working on the next backup definition.
583
-
584
- There are 3 levels of backups, FULL, DIFF and INCR.
585
-
586
- - The author does a FULL yearly backup once a year. This includes all files in all directories as defined in the backup definition(s) (assuming `-d` was not given).
587
- - The author makes a DIFF once a month. The DIFF backs up new and changed files **compared** to the **FULL** backup.
588
-
589
- - No DIFF backups are taken until a FULL backup has been taken for a particular backup definition.
590
-
591
- - The author takes an INCR backup every 3 days. An INCR backup includes new and changed files **compared** to the **DIFF** backup.
592
-
593
- - So, a set of INCR's will contain duplicates (this might change as I become more used to use the catalog databases)
594
-
595
- - No INCR backups are taken until a DIFF backup has been taken for a particular backup definition.
596
-
597
- After each backup of a backup definition, `dar-backup` tests the archive and then performs a few restore operations of random files from the archive (see [dar-backup.conf](#config-file)). The restored files are compared to the originals to check if the restore went well.
598
-
599
- `dar-backup` skips doing a backup of a backup definition if an archive is already in place. So, if you for some reason need to take a new backup on the same date, the first archive must be deleted (I recommend using [cleanup](#cleanup-1)).
600
-
601
- ### cleanup
602
-
603
- The `cleanup` application deletes DIFF and INCR if the archives are older than the thresholds set up in the configuration file.
604
-
605
- `cleanup` will only remove FULL archives if the option `--cleanup-specific-archives` is used. It requires the user to confirm deletion of FULL archives.
606
-
607
- Use `--dry-run` to preview which archives, PAR2 files, and catalogs would be removed without deleting anything.
608
-
609
- Examples:
610
-
611
- ```bash
612
- cleanup --dry-run -d media-files --log-stdout
613
- cleanup --dry-run --cleanup-specific-archives -d media-files media-files_INCR_2025-12-22
614
- ```
615
-
616
- ### manager
617
-
618
- `dar`has the concept of catalogs which can be exported and optionally be added to a catalog database. That database makes it much easier to restore the correct version of a backed up file if for example a target date has been set.
619
-
620
- `dar-backup` adds archive catalogs to their databases (using the `manager` script). Should the operation fail, `dar-backup` logs an error and continue with testing and restore validation tests.
621
-
622
- ## How to run
623
-
624
- 📦 All official dar-backup releases from v2-beta-0.6.18 are signed with GPG.
625
-
626
- See more [here](#gpg-signing-key).
627
-
628
- ### 1 - installation
629
-
630
- Installation is currently in a [virtual environment](https://csguide.cs.princeton.edu/software/virtualenv) (commonly called a `venv`). These commands are installed in the venv:
631
-
632
- - dar-back
633
- - cleanup
634
- - manager
635
- - clean-log
636
- - dar-backup-systemd
637
- - installer
638
- - demo
639
-
640
- Note:
641
-
642
- The modules `inputimeout`, `rich`and `argcomplete` are installed into the venv and used by `dar-backup`
643
-
644
- To install `dar-backup`, create a venv and run pip:
645
-
646
- ```bash
647
- mkdir $HOME/tmp
648
- cd $HOME/tmp
649
- python3 -m venv venv # create the virtual environment
650
- . venv/bin/activate # activate the virtual environment
651
- pip install dar-backup # run pip to install `dar-backup`
652
- ```
653
-
654
- I have an alias in ~/.bashrc pointing to my venv:
655
-
656
- ```bash
657
- alias db=". ~/tmp/venv/bin/activate; dar-backup -v"
658
- ```
659
-
660
- drop the alias into ~/.bashrc like this:
661
-
662
- ```bash
663
- grep -qxF 'alias db="' ~/.bashrc \
664
- || echo 'alias db=". ~/tmp/venv/bin/activate; dar-backup -v"' >> ~/.bashrc
665
-
666
- source ~/.bashrc
667
- ```
668
-
669
- Typing `db` at the command line gives something like this:
670
-
671
- ```bash
672
- (venv) user@machine:~$ db
673
- dar-backup 0.6.12
674
- dar-backup.py source code is here: https://github.com/per2jensen/dar-backup
675
- Licensed under GNU GENERAL PUBLIC LICENSE v3, see the supplied file "LICENSE" for details.
676
- THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW, not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
677
- See section 15 and section 16 in the supplied "LICENSE" file.
678
- ```
679
-
680
- ### 2 - configuration
681
-
682
- The dar-backup [installer](#installer-options) application can be used to setup the needed directories for `dar-backup` to work.
683
- It creates necessary directories as prescribed in the config file and optionally creates manager databases.
684
-
685
- `installer` can also add configuration of shell auto completion.
686
-
687
- Step 1:
688
-
689
- Create a config file - [see details on config file](#config-file))
690
-
691
- Step 2:
692
-
693
- Create one or more backup definitions - [see details on backup definitions](#backup-definition-example)
694
-
695
- Step 3:
696
-
697
- Run the installer:
698
-
699
- ```bash
700
- installer --config <path to dar-backup.conf> --install-autocompletion
701
- ```
702
-
703
- ### 3 - generate catalog databases
704
-
705
- Generate the archive catalog database(s).
706
-
707
- `dar-backup` expects the catalog databases to be in place, it does not automatically create them (by design)
708
-
709
- ```bash
710
- manager --create-db
711
- ```
712
-
713
- ### 4 - give dar-backup a spin
714
-
715
- You are now ready to do backups as configured in your backup definition(s).
716
-
717
- Give `dar-backup`a spin:
718
-
719
- ```bash
720
- dar-backup --full-backup --verbose
721
-
722
- # list backups
723
- dar-backup --list
724
-
725
- # list contents of a dar backup
726
- dar-backup --list-contents <TAB>... <choose a backup>
727
-
728
- # see some examples on usage
729
- dar-backup --examples
730
-
731
- # see the log file
732
- cat "$HOME/dar-backup/dar-backup.log"
733
- ```
734
-
735
- If you want to see dar-backup's log entries in the terminal, use the `--log-stdout` option.
736
-
737
- If you want more log messages, use the `--verbose` or `--log-level debug` for even more.
738
-
739
- If you want to take a backup using a single backup definition, use the `-d <backup definition>` option. The backup definition's name is the filename of the definition in the BACKUP.D_DIR (see [config file](#config-file)).
740
-
741
- ```bash
742
- dar-backup --full-backup -d <your backup definition>
743
- ```
744
-
745
- ### 5 - deactivate venv
746
-
747
- Deactivate the virtual environment (venv).
748
-
749
- ```bash
750
- deactivate
751
- ```
752
-
753
- ## Config
754
-
755
- ### Config file
756
-
757
- The configuration file's default location is: ~/.config/dar-backup/dar-backup.conf
758
-
759
- If you have your config file somewhere else, use the `--config-file` option to point to it.
760
-
761
- Tilde `~` and environment variables can be used in the paths for various file locations.
762
-
763
- ```text
764
- [MISC]
765
- LOGFILE_LOCATION=~/.dar-backup.log
766
- # optional parameters
767
- # LOGFILE_MAX_BYTES = 26214400 # 25 MB max file size is default, change as neeeded
768
- # LOGFILE_BACKUP_COUNT = 5 # 5 backup log files is default, change as needed
769
- MAX_SIZE_VERIFICATION_MB = 20
770
- MIN_SIZE_VERIFICATION_MB = 1
771
- NO_FILES_VERIFICATION = 5
772
- # timeout in seconds for backup, test, restore and par2 operations
773
- # The author has such `dar` tasks running for 10-15 hours on the yearly backups, so a value of 24 hours is used.
774
- # If a timeout is not specified when using the util.run_command(), a default timeout of 30 secs is used.
775
- COMMAND_TIMEOUT_SECS = 86400
776
-
777
- [DIRECTORIES]
778
- BACKUP_DIR = /some/where/dar-backup/backups/
779
- BACKUP.D_DIR = /some/where/dar-backup/backup.d
780
- TEST_RESTORE_DIR = /tmp/dar-backup/restore/
781
- # Optional parameter
782
- # If you want to store the catalog databases away from the BACKUP_DIR, use the MANAGER_DB_DIR variable.
783
- #MANAGER_DB_DIR = /some/where/else/
784
-
785
- [AGE]
786
- # age settings are in days
787
- # `cleanup` script removes archives and their .par redundancy files if older than configured.
788
- # `cleanup` does not remove FULL archives, unless specifically told to and a "y" is answered to "are you sure?".
789
- DIFF_AGE = 100
790
- INCR_AGE = 40
791
-
792
- [PAR2]
793
- ERROR_CORRECTION_PERCENT = 5
794
- ENABLED = True
795
- # Optional PAR2 configuration
796
- # PAR2_DIR = /path/to/par2-store
797
- # PAR2_RATIO_FULL = 10
798
- # PAR2_RATIO_DIFF = 5
799
- # PAR2_RATIO_INCR = 5
800
- # PAR2_RUN_VERIFY = false
801
-
802
- # Optional per-backup overrides (section name = backup definition)
803
- [media-files]
804
- PAR2_DIR = /mnt/par2/media-files
805
- PAR2_RATIO_FULL = 10
806
-
807
- # scripts to run before the backup to setup the environment
808
- [PREREQ]
809
- SCRIPT_1 = ls -l /tmp
810
- #SCRIPT_2 = another_script.sh
811
-
812
- [POSTREQ]
813
- SCRIPT_1 = df -h
814
- #SCRIPT_2 = another_script.sh
815
- ```
816
-
817
- PAR2 notes:
818
-
819
- - If `PAR2_DIR` is unset, par2 files are created next to the archive slices (legacy behavior) and no manifest is written
820
- - When `PAR2_DIR` is set, dar-backup writes a manifest next to the par2 set:
821
- `archive_base.par2.manifest.ini`
822
- - When generating a par2 set, par2 reads all archive slices before writing any output files; for large backups, this initial read can take hours
823
- - Verify or repair using:
824
- `par2 verify -B <archive_dir> <par2_set.par2>`
825
- `par2 repair -B <archive_dir> <par2_set.par2>`
826
-
827
- ### .darrc
828
-
829
- The package includes a default `darrc` file which configures `dar`.
830
-
831
- You can override the default `.darrc` using the `--darrc` option.
832
-
833
- The default `.darrc` contents are as follows:
834
-
835
- ```text
836
- # .darrc configuration file for `dar` as used by the `dar-backup` script.
837
- # `dar-backup` lives here: https://github.com/per2jensen/dar-backup
838
-
839
-
840
- ##############################################################
841
-
842
- # target: verbose
843
-
844
- # remove comments belov for dar being more verbose
845
-
846
- verbose:
847
-
848
- # shows files teated due to filtering inclusion or no filtering at all
849
-
850
- # -vt
851
-
852
- # shows skipped files du to exclusion
853
-
854
- # -vs
855
-
856
- # shows diretory currently being processed
857
- # dar-backup logs `dar` stdout in real time, so directories being processed are now shown in the log file.
858
- # this is quite useful in long running jobs
859
- -vd
860
-
861
- # shows detailed messages, not related to files and directories
862
- # -vm
863
-
864
- # shows summary of each treated directory, including average compression
865
- # dar-backup logs `dar` stdout in real time, so directories being processed are now shown in the log file.
866
- # this is quite useful in long running jobs
867
- -vf
868
-
869
- # equivalent to "-vm -vs -vt"
870
- # -va
871
-
872
-
873
- restore-options:
874
- # don't restore File Specific Attributes
875
- #--fsa-scope none
876
-
877
- # ignore owner, useful when used by a non-privileged user
878
- --comparison-field=ignore-owner
879
-
880
-
881
- # Exclude specific file types from compression
882
- compress-exclusion:
883
-
884
- # First setting case insensitive mode on:
885
- -an
886
- -ag
887
-
888
- -Z "*.gz"
889
- -Z "*.bz2"
890
- -Z "*.xz"
891
- -Z "*.zip"
892
- -Z "*.rar"
893
- -Z "*.7z"
894
- -Z "*.tar"
895
- -Z "*.tgz"
896
- -Z "*.tbz2"
897
- -Z "*.txz"
898
- # Exclude common image file types from compression
899
- -Z "*.jpg"
900
- -Z "*.jpeg"
901
- -Z "*.png"
902
- -Z "*.gif"
903
- -Z "*.bmp"
904
- -Z "*.tiff"
905
- -Z "*.svg"
906
- -Z "*.ico"
907
- -Z "*.webp"
908
- # The author uses Nikon compressed NEFs raw files
909
- -Z "*.NEF"
910
- # Exclude common movie file types from compression
911
- -Z "*.mp4"
912
- -Z "*.avi"
913
- -Z "*.mkv"
914
- -Z "*.mov"
915
- -Z "*.wmv"
916
- -Z "*.flv"
917
- -Z "*.mpeg"
918
- -Z "*.mpg"
919
-
920
- # These are zip files. Not all are compressed, but considering that they can
921
- # get quite large it is probably more prudent to leave this uncommented.
922
- -Z "*.pk3"
923
- -Z "*.zip"
924
-
925
- -Z "*.lz4"
926
- -Z "*.zoo"
927
-
928
- -Z "*.Po"
929
- -Z "*.aar"
930
- -Z "*.bx"
931
- -Z "*.chm"
932
- -Z "*.doc"
933
- -Z "*.epub"
934
- -Z "*.f3d"
935
- -Z "*.gpg"
936
- -Z "*.htmlz"
937
- -Z "*.iix"
938
- -Z "*.iso"
939
- -Z "*.jin"
940
- -Z "*.ods"
941
- -Z "*.odt"
942
- -Z "*.ser"
943
- -Z "*.svgz"
944
- -Z "*.swx"
945
- -Z "*.sxi"
946
- -Z "*.whl"
947
- -Z "*.wings"
948
-
949
-
950
- # Dar archives (may be compressed).
951
- -Z "*.dar"
952
-
953
- # Now we swap back to case sensitive mode for masks which is the default
954
- #mode:
955
- -acase
956
- ```
957
-
958
- ### Backup definition example
959
-
960
- This piece of configuration is a [backup definition](#backup-definition-example). It is placed in the BACKUP.D_DIR (see config file description).
961
- The name of the file is the name of the backup definition.
962
-
963
- You can use as many backup definitions as you need.
964
-
965
- > Note 👉
966
- >
967
- > Environment variables and tilde (~) not allowed here. `dar` does not expand them.
968
- >
969
- > See [TODO](#todo)
970
-
971
- ```text
972
- # Switch to ordered selection mode, which means that the following
973
- # options will be considered top to bottom
974
- -am
975
-
976
- # Backup Root Dir
977
- # This is the top directory, where the backups start.
978
- #Directories mentioned below, are relative to the Root Dir.
979
- -R /home/user/
980
-
981
- # Directories to backup below the Root dir
982
- # uncomment the next line to backup only the Documents directory
983
- # -g Documents
984
-
985
- # Directories to exclude below the Root dir
986
- -P mnt
987
- -P tmp
988
- -P .cache
989
- -P .config/Code/CachedData
990
-
991
- # compression level
992
- -z5
993
-
994
- # no overwrite, if you rerun a backup, 'dar' halts and asks what to do
995
- # due to the -Q option given to `dar`, the program will terminate and give en error.
996
- -n
997
-
998
- # size of each slice in the archive
999
- --slice 7G
1000
-
1001
- # bypass directores marked as cache directories
1002
- # http://dar.linux.free.fr/doc/Features.html
1003
- # https://bford.info/cachedir/
1004
- --cache-directory-tagging
1005
- ```
1006
-
1007
- ## Generate systemd files
1008
-
1009
- The command `dar-backup-systemd` can generate and optionally install systemd units and timers.
1010
-
1011
- The timers are set as the author uses them, modify to your taste and needs.
1012
-
1013
- Example run:
1014
-
1015
- ```bash
1016
- dar-backup-systemd --venv /home/user/tmp/venv --dar-path /home/user/.local/dar/bin
1017
- Generated dar-full-backup.service and dar-full-backup.timer
1018
- → Fires on: *-12-30 10:03:00
1019
- Generated dar-diff-backup.service and dar-diff-backup.timer
1020
- → Fires on: *-*-01 19:03:00
1021
- Generated dar-incr-backup.service and dar-incr-backup.timer
1022
- → Fires on: *-*-04/3 19:03:00
1023
- Generated dar-clean.service and dar-clean.timer
1024
- → Fires on: *-*-* 21:07:00
1025
- ```
1026
-
1027
- ## Systemctl examples
1028
-
1029
- I have dar-backup scheduled to run via systemd --user settings.
1030
-
1031
- The files are located in: ~/.config/systemd/user
1032
-
1033
- Once the .service and .timer files are in place, timers must be enabled and started.
1034
-
1035
- ```` bash
1036
- systemctl --user enable dar-inc-backup.timer
1037
- systemctl --user start dar-inc-backup.timer
1038
- systemctl --user daemon-reload
1039
- ````
1040
-
1041
- Verify your timers are set up as you want:
1042
-
1043
- ```bash
1044
- systemctl --user list-timers
1045
- ```
1046
-
1047
- ## Service: dar-backup --incremental-backup
1048
-
1049
- This is an example of a systemd user service unit.
1050
-
1051
- File: dar-incr-backup.service
1052
-
1053
- ```bash
1054
- /tmp/test$ dar-backup-systemd --venv '$HOME/programmer/dar-backup.py/venv' --dar-path '$HOME/.local/dar/bin'
1055
-
1056
- Generated dar-full-backup.service and dar-full-backup.timer
1057
- → Fires on: *-12-30 10:03:00
1058
- Generated dar-diff-backup.service and dar-diff-backup.timer
1059
- → Fires on: *-*-01 19:03:00
1060
- Generated dar-incr-backup.service and dar-incr-backup.timer
1061
- → Fires on: *-*-04/3 19:03:00
1062
- Generated dar-cleanup.service and dar-cleanup.timer
1063
- → Fires on: *-*-* 21:07:00
1064
- /tmp/test$
1065
- (venv) /tmp/test$
1066
- (venv) /tmp/test$ cat dar-incr-backup.service
1067
- [Unit]
1068
- Description=dar-backup INCR
1069
- StartLimitIntervalSec=120
1070
- StartLimitBurst=1
1071
-
1072
- [Service]
1073
- Type=oneshot
1074
- TimeoutSec=infinity
1075
- RemainAfterExit=no
1076
-
1077
-
1078
- ExecStart=/bin/bash -c 'PATH=$HOME/.local/dar/bin:$PATH && . $HOME/programmer/dar-backup.py/venv/bin/activate && dar-backup -I --verbose --log-stdout'
1079
- ```
1080
-
1081
- ## Timer: dar-backup --incremental-backup
1082
-
1083
- This is an example of a systemd user timer
1084
-
1085
- File: dar-incr-backup.timer
1086
-
1087
- ```text
1088
- [Unit]
1089
- Description=dar-backup INCR timer
1090
-
1091
- [Timer]
1092
- OnCalendar=*-*-04/3 19:03:00
1093
- Persistent=true
1094
-
1095
- [Install]
1096
- WantedBy=timers.target
1097
- ```
1098
-
1099
- ## systemd timer note
1100
-
1101
- 📅 OnCalendar syntax is flexible — you can tweak backup schedules easily. Run systemd-analyze calendar to preview timers.
1102
-
1103
- ## list contents of an archive
1104
-
1105
- ```bash
1106
- # Activate your virtual environment
1107
- source <the virtual evn>/bin/activate
1108
- dar-backup --list-contents media-files_INCR_2025-05-10
1109
- # Deactivate when done
1110
- deactivate
1111
- ```
1112
-
1113
- gives something like
1114
-
1115
- ```text
1116
- [Saved][-] [-L-][ 0%][ ] drwxrwxr-x user user 2 Gio Sat May 10 14:15:07 2025 home/user
1117
- [Saved][ ] [-L-][ 93%][ ] -rw-rw-r-- user user 29 kio Fri May 9 16:45:38 2025 home/user/data/2023/2023-02-11-Udstilling-Fredericia/DSC_0568.NEF.xmp
1118
- [Saved][-] [-L-][ 0%][ ] drwxrwxr-x user user 2 Gio Fri May 9 12:49:04 2025 home/user/data/2025
1119
- [Saved][-] [-L-][ 1%][ ] drwxrwxr-x user user 193 Mio Thu May 8 15:59:17 2025 home/user/data/2025/2025-05-09-Viltrox-25mm-AIR
1120
- [Saved][ ] [-L-][ 1%][X] -rw-rw-r-- user user 15 Mio Thu May 8 15:52:27 2025 home/user/data/2025/2025-05-09-Viltrox-25mm-AIR/DSC_0563.NEF
1121
- [Saved][ ] [-L-][ 1%][X] -rw-rw-r-- user user 10 Mio Thu May 8 15:52:27 2025 home/user/data/2025/2025-05-09-Viltrox-25mm-AIR/DSC_0563.JPG
1122
- [Saved][ ] [-L-][ 1%][X] -rw-rw-r-- user user 9 Mio Thu May 8 15:51:53 2025 home/user/data/2025/2025-05-09-Viltrox-25mm-AIR/DSC_0559.JPG
1123
- [Saved][ ] [-L-][ 1%][X] -rw-rw-r-- user user 16 Mio Thu May 8 15:51:45 2025 home/user/data/2025/2025-05-09-Viltrox-25mm-AIR/DSC_0558.NEF
1124
- [Saved][ ] [-L-][ 1%][X] -rw-rw-r-- user user 12 Mio Thu May 8 15:51:45 2025 home/user/data/2025/2025-05-09-Viltrox-25mm-AIR/DSC_0558.JPG
1125
- [Saved][ ] [-L-][ 1%][X] -rw-rw-r-- user user 16 Mio Thu May 8 15:51:24 2025 home/user/data/2025/2025-05-09-Viltrox-25mm-AIR/DSC_0557.NEF
1126
- [Saved][ ] [-L-][ 1%][X] -rw-rw-r-- user user 12 Mio Thu May 8 15:51:23 2025 home/user/data/2025/2025-05-09-Viltrox-25mm-AIR/DSC_0557.JPG
1127
- [Saved][ ] [-L-][ 91%][ ] -rw-rw-r-- user user 22 kio Thu May 8 15:59:58 2025 home/user/data/2025/2025-05-09-Viltrox-25mm-AIR/DSC_0557.JPG.xmp
1128
- [Saved][ ] [-L-][ 92%][ ] -rw-rw-r-- user user 30 kio Thu May 8 16:00:36 2025 home/user/data/2025/2025-05-09-Viltrox-25mm-AIR/DSC_0557.NEF.xmp
1129
- [Saved][ ] [-L-][ 91%][ ] -rw-rw-r-- user user 22 kio Thu May 8 16:00:29 2025 home/user/data/2025/2025-05-09-Viltrox-25mm-AIR/DSC_0558.JPG.xmp
1130
- ```
1131
-
1132
- ## dar file selection examples
1133
-
1134
- > ⚠️ **Quoting matters**
1135
- >
1136
- > Always pass `--selection` as `--selection="-I '*.NEF'"` to ensure it’s treated as a single argument.
1137
- >
1138
- > Avoid splitting `--selection` and the string into separate tokens.
1139
-
1140
- **Why does --selection give “expected one argument” error?**
1141
-
1142
- This happens when the shell splits the quoted string or interprets globs before `dar-backup` sees them.
1143
- ✅ Use: `--selection="-I '*.NEF'"`
1144
- ❌ Avoid: `--selection "-I '*.NEF'"`
1145
-
1146
- > 💡 **Tip:** See [dar's documentation](http://dar.linux.free.fr/doc/man/dar.html#COMMANDS%20AND%20OPTIONS)
1147
-
1148
- >
1149
- > 💡💡 **Tip:** To filter all the empty directories away that `dar` emits when listing contents, append this grep:
1150
- >
1151
- > ```bash
1152
- > |grep -vE '\s+d[rwx-]{9}\s'
1153
- >```
1154
- >
1155
- >Example using the grep to discard directory noise from `dar's` output:
1156
- >
1157
- > ```bash
1158
- > dar-backup --list-contents media-files_INCR_2025-05-10 --selection="-I '*Z50*' -X '*.xmp'" | grep -vE '\s+d[rwx-]{9}\s'
1159
- >[Saved][ ] [-L-][ 0%][X] -rw-rw-r-- user user 26 Mio Fri May 9 11:26:16 2025 home/user/data/2025/2025-05-09-Roskilde-Nordisk-udstilling/Z50_0633.NEF
1160
- >[Saved][ ] [-L-][ 0%][X] -rw-rw-r-- user user 26 Mio Fri May 9 11:26:16 2025 home/user/data/2025/2025-05-09-Roskilde-Nordisk-udstilling/Z50_0632.NEF
1161
- >[Saved][ ] [-L-][ 0%][X] -rw-rw-r-- user user 28 Mio Fri May 9 11:09:04 2025 home/user/data/2025/2025-05-09-Roskilde-Nordisk-udstilling/Z50_0631.NEF
1162
- >[Saved][ ] [-L-][ 0%][X] -rw-rw-r-- user user 29 Mio Fri May 9 11:09:03 2025 home/user/data/2025/2025-05-09-Roskilde-Nordisk-udstilling/Z50_0630.NEF
1163
- >[Saved][ ] [-L-][ 0%][X] -rw-rw-r-- user user 29 Mio Fri May 9 11:09:03 2025 home/user/data/2025/2025-05-09-Roskilde-Nordisk-udstilling/Z50_0629.NEF
1164
- >...
1165
- >```
1166
-
1167
- ### select a directory
1168
-
1169
- Select files and sub directories in `home/user/data/2025/2025-05-09-Roskilde-Nordisk-udstilling`
1170
-
1171
- ```bash
1172
- dar-backup --list-contents media-files_INCR_2025-05-10 --selection="-g 'home/user/data/2025/2025-05-09-Roskilde-Nordisk-udstilling'"
1173
- ```
1174
-
1175
- gives
1176
-
1177
- ```text
1178
- ...
1179
- [Saved][ ] [-L-][ 0%][X] -rw-rw-r-- user user 29 Mio Fri May 9 10:33:42 2025 home/user/data/2025/2025-05-09-Roskilde-Nordisk-udstilling/Z50_0572.NEF
1180
- [Saved][ ] [-L-][ 0%][X] -rw-rw-r-- user user 28 Mio Fri May 9 10:33:12 2025 home/user/data/2025/2025-05-09-Roskilde-Nordisk-udstilling/Z50_0571.NEF
1181
- [Saved][ ] [-L-][ 0%][X] -rw-rw-r-- user user 25 Mio Fri May 9 10:33:08 2025 home/user/data/2025/2025-05-09-Roskilde-Nordisk-udstilling/Z50_0570.NEF
1182
- [Saved][ ] [-L-][ 0%][X] -rw-rw-r-- user user 27 Mio Fri May 9 10:32:46 2025 home/user/data/2025/2025-05-09-Roskilde-Nordisk-udstilling/Z50_0569.NEF
1183
- [Saved][ ] [-L-][ 0%][X] -rw-rw-r-- user user 27 Mio Fri May 9 10:32:46 2025 home/user/data/2025/2025-05-09-Roskilde-Nordisk-udstilling/Z50_0568.NEF
1184
- [Saved][-] [-L-][ 1%][ ] drwxrwxr-x user user 833 Mio Fri May 9 12:49:57 2025 home/user/data/2025/2025-05-09-Roskilde-Nordisk-udstilling/jpeg
1185
- [Saved][ ] [-L-][ 1%][X] -rw-rw-r-- user user 11 Mio Fri May 9 10:32:45 2025 home/user/data/2025/2025-05-09-Roskilde-Nordisk-udstilling/jpeg/Z50_0568.JPG
1186
- [Saved][ ] [-L-][ 1%][X] -rw-rw-r-- user user 11 Mio Fri May 9 10:32:46 2025 home/user/data/2025/2025-05-09-Roskilde-Nordisk-udstilling/jpeg/Z50_0569.JPG
1187
- [Saved][ ] [-L-][ 1%][X] -rw-rw-r-- user user 9 Mio Fri May 9 10:33:08 2025 home/user/data/2025/2025-05-09-Roskilde-Nordisk-udstilling/jpeg/Z50_0570.JPG
1188
- [Saved][ ] [-L-][ 1%][X] -rw-rw-r-- user user 13 Mio Fri May 9 10:33:12 2025 home/user/data/2025/2025-05-09-Roskilde-Nordisk-udstilling/jpeg/Z50_0571.JPG
1189
- ...
1190
- ```
1191
-
1192
- ### select files with "Z50" in the file name and exclude .xmp files
1193
-
1194
- ```bash
1195
- dar-backup --list-contents media-files_INCR_2025-05-10 --selection="-I '*Z50*' -X '*.xmp'"
1196
- ```
1197
-
1198
- gives something like
1199
-
1200
- ```text
1201
- [Saved][-] [-L-][ 0%][ ] drwxrwxr-x user user 2 Gio Sat May 10 14:15:07 2025 home/user
1202
- [Saved][-] [-L-][ 0%][ ] drwxrwxr-x user user 2 Gio Fri May 9 12:49:04 2025 home/user/data/2025
1203
- [Saved][-] [-L-][ 1%][ ] drwxrwxr-x user user 193 Mio Thu May 8 15:59:17 2025 home/user/data/2025/2025-05-09-Viltrox-25mm-AIR
1204
- [Saved][-] [-L-][ 0%][ ] drwxrwxr-x user user 2 Gio Fri May 9 16:47:37 2025 home/user/data/2025/2025-05-09-Roskilde-Nordisk-udstilling
1205
- [Saved][ ] [-L-][ 0%][X] -rw-rw-r-- user user 26 Mio Fri May 9 11:26:16 2025 home/user/data/2025/2025-05-09-Roskilde-Nordisk-udstilling/Z50_0633.NEF
1206
- [Saved][ ] [-L-][ 0%][X] -rw-rw-r-- user user 26 Mio Fri May 9 11:26:16 2025 home/user/data/2025/2025-05-09-Roskilde-Nordisk-udstilling/Z50_0632.NEF
1207
- [Saved][ ] [-L-][ 0%][X] -rw-rw-r-- user user 28 Mio Fri May 9 11:09:04 2025 home/user/data/2025/2025-05-09-Roskilde-Nordisk-udstilling/Z50_0631.NEF
1208
- [Saved][ ] [-L-][ 0%][X] -rw-rw-r-- user user 29 Mio Fri May 9 11:09:03 2025 home/user/data/2025/2025-05-09-Roskilde-Nordisk-udstilling/Z50_0630.NEF
1209
- [Saved][ ] [-L-][ 0%][X] -rw-rw-r-- user user 29 Mio Fri May 9 11:09:03 2025 home/user/data/2025/2025-05-09-Roskilde-Nordisk-udstilling/Z50_0629.NEF
1210
- ...
1211
- ```
1212
-
1213
- ## Restoring
1214
-
1215
- ### default location for restores
1216
-
1217
- dar-backup will use the TEST_RESTORE_DIR location as the Root for restores, if the --restore-dir option has not been supplied.
1218
-
1219
- See example below to see where files are restored to.
1220
-
1221
- ### --restore-dir option
1222
-
1223
- When the --restore-dir option is used for restoring, a directory must be supplied.
1224
-
1225
- The directory supplied functions as the Root of the restore operation.
1226
-
1227
- **Example**:
1228
-
1229
- A backup has been taken using this backup definition:
1230
-
1231
- ```text
1232
- -R /
1233
- -g home/user/Documents
1234
- ```
1235
-
1236
- When restoring and using `/tmp` for --restore-dir, the restored files can be found in `/tmp/home/user/Documents`
1237
-
1238
- ### a single file
1239
-
1240
- ```bash
1241
- . <the virtual env>/bin/activate
1242
- dar-backup --restore <archive_name> --selection="-g path/to/file"
1243
- deactivate
1244
- ```
1245
-
1246
- ### a directory
1247
-
1248
- ```bash
1249
- . <the virtual env>/bin/activate
1250
- dar-backup --restore <archive_name> --selection="-g path/to/directory"
1251
- deactivate
1252
- ```
1253
-
1254
- ### .NEF from a specific date
1255
-
1256
- The backed up directory contains \*.NEF and \*.xmp files.
1257
-
1258
- Filtering:
1259
-
1260
- - Include files with "2024-06-16" in file name
1261
- - Exclude files with file names ending in ".xmp"
1262
- - Files must be in directory "home/user/tmp/LUT-play", compared to the file root (`-R`option) in the backup.
1263
-
1264
- ```bash
1265
- . <the virtual env>/bin/activate
1266
- dar-backup --restore <archive_name> --selection="-I '*2024-06-16*' -X '*.xmp' -g home/user/tmp/LUT-play"
1267
- deactivate
1268
- ```
1269
-
1270
- ### restore test fails with exit code 4
1271
-
1272
- `dar` in newer versions emits a question about file ownership, which is "answered" with a "no" via the "-Q" option. That in turn leads to an error code 4.
1273
-
1274
- Thus the dar option `--comparison-field=ignore-owner` has been placed in the supplied [.darrc](#darrc) file (located in the virtual environment where dar-backup is installed).
1275
-
1276
- This causes dar to restore without an error.
1277
-
1278
- It is a good option when using dar as a non-privileged user.
1279
-
1280
- ### restore test fails with exit code 5
1281
-
1282
- If exit code 5 is emitted on the restore test, FSA (File System specific Attributes) could be the cause.
1283
-
1284
- That (might) occur if you backup a file stored on one type of filesystem, and restore it on another type.
1285
- My home directory is on a btrfs filesystem, while /tmp (for the restore test) is on zfs.
1286
-
1287
- The restore test can result in an exit code 5, due to the different filesystems used. In order to avoid the errors, the option `--fsa-scope none` can be used. That will restult in FSA's not being restored.
1288
-
1289
- If you need to use this option, un-comment it in the [.darrc](#darrc) file (located in the virtual environment where dar-backup is installed)
1290
-
1291
- ## Par2
1292
-
1293
- Why keep PAR2 on a different storage device:
1294
-
1295
- - Reduces single-disk failure impact: bitrot on the archive disk does not affect the parity.
1296
- - Easier offsite rotation: you can sync only the PAR2 sets to a different failure domain.
1297
-
1298
- Redundancy guidance:
1299
-
1300
- - FULL backups: 10% is a practical default for larger data sets and longer retention.
1301
- - DIFF/INCR: 5% is often enough because the delta is smaller and easier to re-create.
1302
- - Increase the ratio if the storage is flaky or the backup is hard to re-run.
1303
-
1304
- Rule of thumb table:
1305
-
1306
- | Backup type | Suggested PAR2 ratio | Notes |
1307
- |-------------|----------------------|-------|
1308
- | FULL | 10% | Longer retention, larger data set |
1309
- | DIFF | 5% | Smaller delta |
1310
- | INCR | 5% | Smaller delta |
1311
-
1312
- >
1313
- >For large, contiguous archives on reliable local storage, 7–8% has proven sufficient in practice; 10% remains a conservative default.
1314
- >
1315
-
1316
- Cloud sync / air-gap note:
1317
-
1318
- - Syncing PAR2 sets to a different device or remote store protects against bitrot and small corruption, but it cannot recover a completely lost archive.
1319
- - An air-gapped PAR2 store is useful when the archive disk is exposed to ransomware or accidental deletion.
1320
-
1321
- ### Par2 to verify/repair
1322
-
1323
- #### Par2 files kept with archives
1324
-
1325
- If PAR2 files are stored next to the archives (legacy per-slice behavior), you can verify like this:
1326
-
1327
- ```bash
1328
- for file in <archive>*.dar.par2; do
1329
- par2 verify "$file"
1330
- done
1331
- ```
1332
-
1333
- if there are problems with a slice, try to repair it like this:
1334
-
1335
- ```bash
1336
- par2 repair <archive>.<slice number>.dar.par2
1337
- ```
1338
-
1339
- #### Par2 files in separate directory
1340
-
1341
- See [docs on disk layout matters](v2/doc/portable-par2-layout.md)
1342
-
1343
- >Test case proving this flow:
1344
- >
1345
- >[tests/test_par2_manifest.py](v2/tests/test_par2_manifest.py)
1346
-
1347
- ### Par2 create redundancy files
1348
-
1349
- If you have merged archives, you will need to create the .par2 redundency files manually.
1350
- Here is an example
1351
-
1352
- ```bash
1353
- for file in <some-archive>_FULL_yyyy-mm-dd.*; do
1354
- par2 c -r5 -n1 "$file"
1355
- done
1356
- ```
1357
-
1358
- where "c" is create, -r5 is 5% redundency and -n1 is 1 redundency file
1359
-
1360
- If you want to create a single parity set for all slices in an archive:
1361
-
1362
- ```bash
1363
- par2 create -B <archive_dir> -r5 <par2_dir>/<archive_base>.par2 <archive_dir>/<archive_base>.*.dar
1364
- ```
1365
-
1366
- **OBSERVE** [docs on disk layout matters](v2/doc/portable-par2-layout.md)
1367
-
1368
-
1369
- ## Points of interest
1370
-
1371
- ### Limitations on File Names with Special Characters
1372
-
1373
- `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:
1374
-
1375
- Disallowed characters include:
1376
-
1377
- ```text
1378
- \$ & ; | > < ` \n
1379
- ```
1380
-
1381
- #### Why this matters
1382
-
1383
- 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.
1384
-
1385
- ✅ Backups and Restores Still Work
1386
-
1387
- ✅ These files are still backed up and restored automatically as part of normal FULL, DIFF, or INCR operations.
1388
-
1389
- ❌ They cannot be explicitly specified for restore using CLI options like --selection="-g path/to/file_with_currency$.txt".
1390
-
1391
- #### Workarounds
1392
-
1393
- If you need to restore such a file:
1394
-
1395
- Perform a restore of the entire directory using a more general selection (e.g., --selection="-g path/to/parent-directory").
1396
-
1397
- Manually retrieve the restored file afterward.
1398
-
1399
- ##### Restoring Files with Forbidden Characters in Their Names
1400
-
1401
- 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:
1402
-
1403
- | Character | Reason Blocked |
1404
- |----------:|---------------------------------|
1405
- | `;` | Shell command separator |
1406
- | `&` | Background execution operator |
1407
- | `\|` | Pipe operator |
1408
- | `<` / `>` | Redirection operators |
1409
- | `#` | Shell comment |
1410
- | `` ` `` | Command substitution |
1411
- | `"` / `'` | Quoting that may be unbalanced |
1412
-
1413
- 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.
1414
-
1415
- ##### Backups: Safe and Fully Functional
1416
-
1417
- 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.)
1418
-
1419
- ##### Restores via CLI: Limited by Sanitizer
1420
-
1421
- Attempting to restore such files via:
1422
-
1423
- ```bash
1424
- dar-backup restore --file "weird#name.txt"
1425
- ```
1426
-
1427
- ...will fail with an error like:
1428
-
1429
- ```bash
1430
- Unsafe argument detected: weird#name.txt
1431
- ```
1432
-
1433
- ---
1434
-
1435
- ##### Workaround: Use `dar` Directly
1436
-
1437
- You can always restore the file manually using the `dar` command-line utility itself, bypassing any CLI restrictions imposed by the backup tool.
1438
-
1439
- ##### Example: Manual Restore Using `dar`
1440
-
1441
- ```bash
1442
- dar -x /path/to/backup/example -g "weird#name.txt"
1443
- ```
1444
-
1445
- Where:
1446
-
1447
- - `/path/to/backup/example` is the base name of the archive (without `.dar`, `.1.dar`, etc.).
1448
- - `"weird#name.txt"` is the exact filename with the special character(s).
1449
-
1450
- You may need to quote the argument or escape characters depending on your shell.
1451
-
1452
- ---
1453
-
1454
- ##### 🧪 How to Locate Files with Forbidden Characters
1455
-
1456
- To search for such files inside the archive:
1457
-
1458
- ```bash
1459
- dar -l /path/to/backup/example | grep '[#;<>|&]'
1460
- ```
1461
-
1462
- This will help you identify files that require manual restoration.
1463
-
1464
- ---
1465
-
1466
- #### Summary
1467
-
1468
- - 🚫 Forbidden characters are blocked **only** in CLI arguments to maintain safety.
1469
- - ✅ Files containing these characters are **still archived and restorable**.
1470
- - 🛠 Use `dar` directly for full manual control when restoring such files.
1471
-
1472
-
1473
-
1474
- ### Merge FULL with DIFF, creating new FULL
1475
-
1476
- 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.
1477
- One way to do that, is to let dar create a FULL archive from scratch, another is to merge a FULL archive with a DIFF, and from there do DIFF's until they once again gets too large for your taste.
1478
-
1479
- I do backups of my homedir. Here it is shown how a FULL archive is merged with a DIFF, creating a new FULL archive.
1480
-
1481
- ```bash
1482
- dar --merge user-homedir_FULL_2021-09-12 -A user-homedir_FULL_2021-06-06 -@user-homedir_DIFF_2021-08-29 -s 12G
1483
-
1484
- # test the new FULL archive
1485
- dar -t user-homedir_FULL_2021-09-12
1486
-
1487
- # create Par2 redundancy files
1488
- for file in user-homedir_FULL_yyyy-mm-dd.*.dar; do
1489
- par2 c -r5 -n1 "$file"
1490
- done
1491
- ```
1492
-
1493
- ### dar manager databases
1494
-
1495
- `dar-backup` now saves archive catalogs in dar catalog databases.
1496
-
1497
- This makes it easier to restore to a given date when having many FULL, DIFF and INCR archives.
1498
-
1499
- If the manager does not add an archive to it's catalog database, `dar-backup` will log an error and continue. The important part is verify the archive is usable and continue to other backup definitions.
1500
-
1501
- ### Performance tip due to par2
1502
-
1503
- This [dar benchmark page](https://dar.sourceforge.io/doc/benchmark.html) has an interesting note on the slice size.
1504
-
1505
- Slice size should be smaller than available RAM, apparently a large performance hit can be avoided keeping the par2 data in memory.
1506
-
1507
- ### .darrc sets -vd -vf (since v0.6.4)
1508
-
1509
- These [.darrc](#darrc) settings make `dar` print the current directory being processed (-vd) and some stats after (-vf)
1510
-
1511
- This is very useful in very long running jobs to get an indication that the backup is proceeding normally.
1512
-
1513
- The `dar` output is streamed to the `dar-backup-commands.log` file.
1514
-
1515
- ### Separate log file for command output
1516
-
1517
- Dar-backup's log file is called `dar-backup.log`.
1518
-
1519
- In order to not clutter that log file with the output of commands being run, a new secondary log file has been introduced `dar-backup-commands.log`.
1520
-
1521
- The secondary log file can get quite cluttered, if you want to remove the clutter, run the `clean-log`script with the `--file` option, or simply delete it.
1522
-
1523
- ### Trace Logging (Debug details)
1524
-
1525
- To keep the main log file clean while preserving essential debugging information, `dar-backup` creates a separate trace log file (e.g., `dar-backup.trace.log`) alongside the main log.
1526
-
1527
- - **Main Log (`dar-backup.log`)**: Contains clean, human-readable INFO/ERROR messages. Stack traces are suppressed here.
1528
- - **Trace Log (`dar-backup.trace.log`)**: Captures ALL messages at `DEBUG` level, including full exception stack traces. Use this file for debugging crashes or unexpected behavior.
1529
-
1530
- You can configure the rotation of this file in `[MISC]`:
1531
-
1532
- ```ini
1533
- [MISC]
1534
- # ... other settings ...
1535
- TRACE_LOG_MAX_BYTES = 10485760 # 10 MB default
1536
- TRACE_LOG_BACKUP_COUNT = 1 # Keep 1 old trace file (default)
1537
- ```
1538
-
1539
- ### Skipping cache directories
1540
-
1541
- The author uses the `--cache-directory-tagging` option in his [backup definitions](#backup-definition-example).
1542
-
1543
- The effect is that directories with the [CACHEDIR.TAG](https://bford.info/cachedir/) file are not backed up. Those directories contain content fetched from the net, which is of an ephemeral nature and probably not what you want to back up.
1544
-
1545
- If the option is not in the backup definition, the cache directories are backed up as any other.
1546
-
1547
- ### Shell autocompletion
1548
-
1549
- The `dar-backup`, `manager`, and `cleanup` scripts now support dynamic Bash tab-completion, making them easier and faster to use.
1550
-
1551
- ✅ Features
1552
-
1553
- - Autocomplete for all long options (--config-file, --restore, etc.)
1554
-
1555
- - Dynamic suggestions based on your config:
1556
-
1557
- - --backup-definition shows available definitions from backup.d/
1558
-
1559
- - show relevant archives when a backup definition has been chosen:
1560
-
1561
- dar-backup: --restore, --list-contents, and --alternate-reference-archive
1562
-
1563
- cleanup: --cleanup-specific-archives
1564
-
1565
- manager: --list-archive-contents, --add-specific-archive (autocomplete those **not* in the catalog database), --remove-specific-archive
1566
-
1567
- - Supports paths like ~ and $HOME correctly
1568
-
1569
- #### Use it
1570
-
1571
- Try typing:
1572
-
1573
- ```bash
1574
- dar-backup --<TAB>
1575
- ```
1576
-
1577
- You should see all available flags like --full-backup, --restore, etc.
1578
-
1579
- Try completion of backup definition and then list contents:
1580
-
1581
- ```bash
1582
- dar-backup --backup-definition <TAB>
1583
- dar-backup -d <the chosen backup-definition> --list-contents <TAB>
1584
- ```
1585
-
1586
- #### Archive name completion (smart, context-aware)
1587
-
1588
- When using `manager--list-archive-contents`, the tab-completer suggests valid archive names.
1589
-
1590
- The behavior is smart and context-aware:
1591
-
1592
- - If a --backup-definition (-d) is provided, archive suggestions are restricted to that .db catalog.
1593
-
1594
- - If no backup definition is given, the completer will:
1595
-
1596
- - Scan all .db files in the backup_dir
1597
-
1598
- - Aggregate archive names across all catalogs
1599
-
1600
- - Sort results by:
1601
-
1602
- - Backup name (e.g. pCloudDrive, media-files)
1603
-
1604
- - Date inside the archive name (e.g. 2025-04-19)
1605
-
1606
- It’s blazing fast and designed for large backup sets.
1607
-
1608
- ```bash
1609
- # With a backup definition
1610
- manager -d pCloudDrive --list-archive-contents <TAB>
1611
- # ⤷ Suggests: pCloudDrive_FULL_2025-03-04, pCloudDrive_INCR_2025-04-19, ...
1612
-
1613
- # Without a backup definition
1614
- manager --list-archive-contents <TAB>
1615
- # ⤷ Suggests: all archives across all known backup definitions
1616
- # ⤷ Example: media-files_FULL_2025-01-04, pCloudDrive_INCR_2025-04-19, ...
1617
-
1618
- # Filter by prefix
1619
- manager --list-archive-contents media-<TAB>
1620
- # ⤷ Suggests: media-files_FULL_2025-01-04, media-files_INCR_2025-02-20, ...
1621
- ```
1622
-
1623
- #### Enabling Bash completion
1624
-
1625
- Try auto completion in your session:
1626
-
1627
- ```bash
1628
- eval "$(register-python-argcomplete dar-backup)"
1629
- eval "$(register-python-argcomplete cleanup)"
1630
- eval "$(register-python-argcomplete manager)"
1631
- #complete -o nosort -C 'python -m argcomplete cleanup' cleanup
1632
- #complete -o nosort -C 'python -m argcomplete manager' manager
1633
- ```
1634
-
1635
- To make it persistent across sessions, add this to your ~/.bashrc:
1636
-
1637
- ```bash
1638
- # Enable autocompletion for dar-backup
1639
- eval "$(register-python-argcomplete dar-backup)"
1640
- eval "$(register-python-argcomplete cleanup)"
1641
- eval "$(register-python-argcomplete manager)"
1642
- # This disables bash sorting, so sorting is by <backup definition> and <date>
1643
- #complete -o nosort -C 'python -m argcomplete cleanup' cleanup
1644
- #complete -o nosort -C 'python -m argcomplete manager' manager
1645
- ```
1646
-
1647
- If you're using a virtual environment and register-python-argcomplete isn't in your global PATH, use:
1648
-
1649
- ```bash
1650
- # Enable autocompletion for dar-backup
1651
- eval "$($(which register-python-argcomplete) dar-backup)"
1652
- eval "$($(which register-python-argcomplete) cleanup)"
1653
- eval "$($(which register-python-argcomplete) manager)"
1654
-
1655
- # If it's not working, try reactivating your virtualenv and restarting your terminal.
1656
- ```
1657
-
1658
- Then reload your shell:
1659
-
1660
- ```bash
1661
- source ~/.bashrc
1662
- ```
1663
-
1664
- #### Enable Zsh Completion
1665
-
1666
- If you're using Zsh, add this to your .zshrc:
1667
-
1668
- ```zsh
1669
- autoload -U bashcompinit
1670
- bashcompinit
1671
- eval "$(register-python-argcomplete dar-backup)"
1672
- eval "$(register-python-argcomplete cleanup)"
1673
- eval "$(register-python-argcomplete manager)"
1674
- ```
1675
-
1676
- Then reload Zsh:
1677
-
1678
- ```zsh
1679
- source ~/.zshrc
1680
- ```
1681
-
1682
- ## Easy development setup
1683
-
1684
- It is very easy to have your own development environment.
1685
-
1686
- ```bash
1687
- git clone https://github.com/per2jensen/dar-backup.git
1688
- cd dar-backup/v2
1689
- ./build.py
1690
- ```
1691
-
1692
- This script:
1693
-
1694
- - Creates a Python virtual environment called `venv`
1695
- - pip install `hatch`
1696
- - pip install the development environment as setup in pyproject.toml
1697
-
1698
- --
1699
-
1700
- ```text
1701
- dev = [
1702
- "pytest",
1703
- "wheel>=0.45.1",
1704
- "requests>=2.32.2",
1705
- "coverage>=7.8.2",
1706
- "pytest>=8.4.0",
1707
- "pytest-cov>=6.1.1",
1708
- "psutil>=7.0.0",
1709
- "pytest-timeout>=2.4.0",
1710
- "httpcore>=0.17.3",
1711
- "h11>=0.16.0",
1712
- "zipp>=3.19.1",
1713
- "anyio>=4.4.0",
1714
- "black>=25.1.0"]
1715
- ```
1716
-
1717
- ✅ Your environment is now ready to activate and test!
1718
-
1719
- Activate and run the test suite:
1720
-
1721
- ```bash
1722
- source venv/bin/activate # activate the virtual env
1723
- pytest # run the test suite
1724
- ```
1725
-
1726
- ## Todo
1727
-
1728
- - Perhaps look into pre-processing backup definitions. As `dar` does not expand env vars
1729
- `dar-backup` could do so and feed the result to `dar`.
1730
- - Look into a way to move the .par2 files away from the `dar` slices, to maximize chance of good redundancy.
1731
- - Add option to dar-backup to use the `dar` option `--fsa-scope none`
1732
-
1733
- ## Known Limitations / Edge Cases
1734
-
1735
- Does not currently encrypt data (by design — relies on encrypted storage)
1736
-
1737
- One backup definition per file
1738
-
1739
- .par2 files created for each slice (may be moved in future)
1740
-
1741
- ## Projects these scripts benefit from
1742
-
1743
- 1. [The wonderful dar achiver](https://github.com/Edrusb/DAR)
1744
- 2. [The Parchive suite](https://github.com/Parchive)
1745
- 3. [shellcheck - a bash linter](https://github.com/koalaman/shellcheck)
1746
- 4. [Ubuntu of course :-)](https://ubuntu.com/)
1747
- 5. [PyPI](https://pypi.org/)
1748
- 6. Tracking PyPI downloads with [pypi-total-downloads-tracker](https://github.com/per2jensen/pypi-total-downloads-tracker)
1749
-
1750
- ## Reference
1751
-
1752
- ### CLI Tools Overview
1753
-
1754
- | Command | Description |
1755
- | --- | --- |
1756
- | [dar-backup](#dar-backup-options) | Perform full, differential, or incremental backups with verification and restore testing |
1757
- | [manager](#manager-options) | Maintain and query catalog databases for archives |
1758
- | [cleanup](#cleanup-options) | Remove outdated DIFF/INCR archives (and optionally FULLs) |
1759
- | [clean-log](#clean-log-options) | Clean up excessive log output from dar command logs |
1760
- | [dar-backup-systemd](#dar-backup-systemd-options) | Generate (and optionally install) systemd timers and services for automated backups |
1761
- | [installer](#installer-options) | Set up directories and optionally create catalog databases according to a config file |
1762
- | [demo](#demo-options) | Set up required directories and config files for a demo|
1763
-
1764
- ### test coverage
1765
-
1766
- Running
1767
-
1768
- ```bash
1769
- pytest --cov=dar_backup tests/
1770
- ```
1771
-
1772
- Results for version 1.0.0 in this report:
1773
-
1774
- ```text
1775
- ====================================== tests coverage ======================================
1776
- _____________________ coverage: platform linux, python 3.12.3-final-0 ______________________
1777
-
1778
- Name Stmts Miss Branch BrPart Cover
1779
- ------------------------------------------------------------------------
1780
- src/dar_backup/__about__.py 2 0 0 0 100%
1781
- src/dar_backup/__init__.py 0 0 0 0 100%
1782
- src/dar_backup/clean_log.py 76 15 40 7 81%
1783
- src/dar_backup/cleanup.py 203 16 66 7 91%
1784
- src/dar_backup/command_runner.py 129 16 26 5 86%
1785
- src/dar_backup/config_settings.py 73 3 18 1 96%
1786
- src/dar_backup/dar_backup.py 551 28 180 21 93%
1787
- src/dar_backup/dar_backup_systemd.py 56 7 10 2 86%
1788
- src/dar_backup/demo.py 92 20 26 6 75%
1789
- src/dar_backup/exceptions.py 2 0 0 0 100%
1790
- src/dar_backup/installer.py 107 14 46 9 82%
1791
- src/dar_backup/manager.py 427 42 152 15 90%
1792
- src/dar_backup/rich_progress.py 70 7 30 4 89%
1793
- src/dar_backup/util.py 339 41 88 21 85%
1794
- ------------------------------------------------------------------------
1795
- TOTAL 2127 209 682 98 89%
1796
- Coverage XML written to file coverage.xml
1797
- ======================== 257 passed, 1 skipped in 223.21s (0:03:43) ========================
1798
- ```
1799
-
1800
- ### Dar-backup options
1801
-
1802
- This script does backups including par2 redundancy, validation and restoring.
1803
-
1804
- Available options:
1805
-
1806
- ```bash
1807
- -F, --full-backup Perform a full backup.
1808
- -D, --differential-backup Perform a differential backup.
1809
- -I, --incremental-backup Perform an incremental backup.
1810
- -d, --backup-definition <name> Specify the backup definition file.
1811
- --alternate-reference-archive <file> Use a different archive for DIFF/INCR backups.
1812
- -c, --config-file <path> Specify the path to the configuration file.
1813
- --darrc <path> Specify an optional path to .darrc.
1814
- --examples Show examples of using dar-backup.py.
1815
- -l, --list List available backups.
1816
- --list-contents <archive> List the contents of a specified archive.
1817
- --list-definitions List backup definitions from BACKUP.D_DIR.
1818
- --selection <params> Define file selection for listing/restoring.
1819
- --restore <archive> Restore a specified archive.
1820
- -r, --restore <archive> Restore archive.
1821
- --restore-dir Directory on which to restore
1822
- --verbose Enable verbose output.
1823
- --suppress-dar-msg Filter out this from the darrc: "-vt", "-vs", "-vd", "-vf", "-va"
1824
- --log-level <level> `debug` or `trace`, default is `info`.
1825
- --log-stdout Also print log messages to stdout.
1826
- --do-not-compare Do not compare restores to file system.
1827
- --preflight-check Run preflight checks and exit (runs automatically; this flag just exits after checks).
1828
- --examples Show examples of using dar-backup.
1829
- --readme Print README.md and exit
1830
- --readme-pretty Print README.md with Markdown styling and exit
1831
- --changelog Print Changelog and exit
1832
- --changelog-pretty Print Changelog with Markdown styling and exit
1833
- -v, --version Show version and license information.
1834
- ```
1835
-
1836
- #### Dar-backup exit codes
1837
-
1838
- - 0: Success.
1839
- - 1: Error (backup/restore/preflight failure).
1840
- - 2: Warning (restore test failed or backup already exists and is skipped).
1841
- - 127: Typically an error during startup, file or config value missing
1842
- - if the `dar -t` test fails, exit code 1 is emitted
1843
- - restore tests could fail if the source file has changed after the backup
1844
-
1845
- #### Dar-backup env vars
1846
-
1847
- | Env var | Value | Description |
1848
- | --- | --- | --- |
1849
- | DAR_BACKUP_CONFIG_FILE | Full path to config file | Overrides built-in default, overridden by --config-file |
1850
- | DAR_BACKUP_DISCORD_WEBHOOK_URL | https://discord.com/api/webhooks/\<userID\>/\<webhook UUID\> | The full url |
1851
-
1852
- ### Manager Options
1853
-
1854
- This script manages `dar` databases and catalogs.
1855
-
1856
- Available options:
1857
-
1858
- ```bash
1859
- -c, --config-file <path> Path to dar-backup.conf.
1860
- --create-db Create missing databases for all backup definitions.
1861
- --alternate-archive-dir <path> Use this directory instead of BACKUP_DIR in the config file.
1862
- --add-dir <path> Add all archive catalogs in this directory to databases.
1863
- -d, --backup-def <name> Restrict operations to this backup definition.
1864
- --add-specific-archive <archive> Add a specific archive to the catalog database.
1865
- --remove-specific-archive <archive> Remove a specific archive from the catalog database.
1866
- -l, --list-catalogs List catalogs in databases for all backup definitions.
1867
- --list-archive-contents <archive> List the contents of an archive’s catalog by archive name.
1868
- --find-file <file> Search catalogs for a specific file.
1869
- --verbose Enable verbose output.
1870
- --log-level <level> Set log level (`debug` or `trace`, default is `info`).
1871
-
1872
- #### Manager env vars
1873
-
1874
- | Env var | Value | Description |
1875
- | --- | --- | --- |
1876
- | DAR_BACKUP_CONFIG_FILE | path to the config file | Default is $HOME/.config/dar-backup/dar-backup.conf |```
1877
-
1878
- ### Cleanup options
1879
-
1880
- This script removes old backups and par2 files according to `[AGE]` settings in config file.
1881
-
1882
- Catalogs in catalog databases are also removed.
1883
-
1884
- Supported options:
1885
-
1886
- ```bash
1887
- -d, --backup-definition Backup definition to cleanup.
1888
- -c, --config-file Path to 'dar-backup.conf'
1889
- -v, --version Show version & license information.
1890
- --alternate-archive-dir Clean up in this directory instead of the default one.
1891
- --cleanup-specific-archives "<archive>, <>, ..." Comma separated list of archives to cleanup.
1892
- -l, --list List available archives (filter using the -d option).
1893
- --dry-run Show what would be deleted without removing files.
1894
- --verbose Print various status messages to screen.
1895
- --log-level <level> `debug` or `trace`, default is `info`", default="info".
1896
- --log-stdout Print log messages to stdout.
1897
- --test-mode This is used when running pytest test cases
1898
- ```
1899
-
1900
- #### Cleanup env vars
1901
-
1902
- | Env var | Value | Description |
1903
- | --- | --- | --- |
1904
- | DAR_BACKUP_CONFIG_FILE | path to the config file | Default is $HOME/.config/dar-backup/dar-backup.conf |
1905
-
1906
- ### Clean-log options
1907
-
1908
- This script removes excessive logging output from `dar` logs, improving readability and efficiency. Available options:
1909
-
1910
- ```bash
1911
- -f, --file <path> Specify the log file(s) to be cleaned.
1912
- -c, --config-file <path> Path to dar-backup.conf.
1913
- --dry-run Show which lines would be removed without modifying the file.
1914
- -v, --version Display version and licensing information.
1915
- -h, --help Displays usage info
1916
- ```
1917
-
1918
- ### Dar-backup-systemd options
1919
-
1920
- Generates and optionally install systemd user service units and timers.
1921
-
1922
- ```bash
1923
- -h, --help Show this help message and exit
1924
- --venv VENV Path to the Python venv with dar-backup
1925
- --dar-path DAR_PATH Optional path to dar binary's directory
1926
- --install Install the units to ~/.config/systemd/user
1927
- ```
1928
-
1929
- ### Installer options
1930
-
1931
- Sets up `dar-backup` according to provided config file.
1932
-
1933
- The installer creates the necessary backup catalog databases if `--create-db` is given.
1934
-
1935
- ```bash
1936
- --config Path to a config file. The configured directories will be created.
1937
- --create-db Create backup catalog databases. Use this option with `--config`.
1938
- --install-autocompletion Add bash or zsh auto completion - idempotent.
1939
- --remove-autocompletion Remove the auto completion from bash or zsh.
1940
- -v, --version Display version and licensing information.
1941
- -h, --help Displays usage info.
1942
- ```
1943
-
1944
- ### Demo options
1945
-
1946
- Sets up `dar-backup` in a demo configuration.
1947
-
1948
- It is non-destructive and stops if directories are already in place.
1949
-
1950
- Create directories:
1951
-
1952
- - ~/.config/dar-backup/
1953
- - ~/.config/dar-backup/backup.d/
1954
- - ~/dar-backup/
1955
- - ~/dar-backup/backups/
1956
- - ~/dar-backup/restore/
1957
-
1958
- Sets up demo config files:
1959
-
1960
- - ~/.config/dar-backup/dar-backup.conf
1961
- - ~/.config/dar-backup/backup.d/demo
1962
-
1963
- ```bash
1964
- -i, --install Sets up `dar-backup`.
1965
- --root-dir Specify the root directory for the backup.
1966
- --dir-to-backup Directory to backup, relative to the root directory.
1967
- --backup-dir Directory where backups and redundancy files are put.
1968
- --override By default, the script will not overwrite existing files or directories.
1969
- Use this option to override this behavior.
1970
- --generate Generate config files and put them in /tmp/ for inspection
1971
- without writing to $HOME.
1972
- -v, --version Display version and licensing information.
1973
- -h, --help Displays usage info
1974
- ```
1975
-
1976
- ### Config changes
1977
-
1978
- #### 1.0.1
1979
-
1980
- ##### DISCORD WEBHOOK
1981
-
1982
- For Discord notifications use the `DAR_BACKUP_DISCORD_WEBHOOK_URL` environment variable. It should not be placed in the config file.
1983
-
1984
- DAR_BACKUP_DISCORD_WEBHOOK_URL is the entire endpoint like this:
1985
-
1986
- ```bash
1987
- export DAR_BACKUP_DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/\<userId\>/\<uuid\>
1988
- ```
1989
-
1990
- ##### Restore test config
1991
-
1992
- Restore tests choose random files from the archive and compare them with the live filesystem.
1993
- To avoid noisy paths (caches, temp files, logs), you can exclude candidates before the random
1994
- selection happens. All matching is case-insensitive.
1995
-
1996
- Config keys (in [MISC]):
1997
-
1998
- - RESTORETEST_EXCLUDE_PREFIXES: comma-separated path prefixes to skip. Matches from the start of
1999
- the path (after trimming a leading "/"). Use trailing "/" for directories.
2000
- - RESTORETEST_EXCLUDE_SUFFIXES: comma-separated filename suffixes to skip.
2001
- - RESTORETEST_EXCLUDE_REGEX: optional regex to skip anything matching the path.
2002
-
2003
- Example:
2004
-
2005
- ```ini
2006
- [MISC]
2007
- RESTORETEST_EXCLUDE_PREFIXES = .cache/, .local/share/Trash/, .mozilla/, snap/firefox/common/.mozilla/
2008
- RESTORETEST_EXCLUDE_SUFFIXES = .sqlite-wal, .sqlite-shm, .log, .tmp, .lock, .journal
2009
- RESTORETEST_EXCLUDE_REGEX = (^|/)(Cache|cache|Logs|log)/
2010
- ```
2011
-
2012
- Regex tips (case-insensitive):
2013
-
2014
- - Match common cache/log directories anywhere:
2015
- `(^|/)(cache|logs)/`
2016
- - Skip thumbnails and temp dirs:
2017
- `(^|/)(thumbnails|tmp|temp)/`
2018
- - Exclude browser profile noise while keeping other files:
2019
- `(^|/)\.mozilla/|/snap/firefox/common/\.mozilla/`
2020
-
2021
- ##### Par2
2022
-
2023
- New optional PAR2 settings were added to the config file. If none of these keys are added, dar-backup behaves exactly as before (PAR2 files next to archives, per-slice parity).
2024
-
2025
- | Name | Description | When it is in effect | Suggested value |
2026
- |------|-------------|----------------------|-----------------|
2027
- | PAR2_DIR | Directory to store .par2 and .vol*.par2 files | When set | A different device or mount from BACKUP_DIR |
2028
- | PAR2_RATIO_FULL | Redundancy percent for FULL | When set | 10 (%) |
2029
- | PAR2_RATIO_DIFF | Redundancy percent for DIFF | When set | 5 (%)|
2030
- | PAR2_RATIO_INCR | Redundancy percent for INCR | When set | 5 (%)|
2031
- | PAR2_RUN_VERIFY | Verify after create | When set | false |
2032
-
2033
- Notes:
2034
-
2035
- - PAR2_RATIO_*, and PAR2_RUN_VERIFY apply even if PAR2_DIR is not set (i.e. par2 output stays next to the archives).
2036
-
2037
- Per-backup overrides use a section named after the backup definition with the same PAR2_* keys:
2038
-
2039
- ```text
2040
-
2041
- ######################################################################
2042
- # Per-backup configuration example overrides
2043
- ######################################################################
2044
-
2045
- # --------------------------------------------------------------------
2046
- # Per-backup overrides (section name must match backup.d filename stem)
2047
- # Example: backup.d/home.conf -> [home]
2048
- # --------------------------------------------------------------------
2049
-
2050
- #[home]
2051
- # Disable PAR2 entirely for this backup definition
2052
- PAR2_ENABLED = false
2053
- #
2054
- #[media]
2055
- # Store PAR2 files in a separate location for this backup definition
2056
- #PAR2_DIR = /samba/par2/media
2057
- # Raise redundancy only for FULL
2058
- #
2059
- [documents]
2060
- # Run verify par2 sets after creation
2061
- PAR2_RUN_VERIFY = true
2062
- #
2063
- #[etc]
2064
- # Keep global PAR2 settings but tweak ratios for this backup definition
2065
- # RATIO is given in percent (%)
2066
- #PAR2_RATIO_FULL = 15
2067
- #PAR2_RATIO_DIFF = 8
2068
- #PAR2_RATIO_INCR = 8
2069
- ```
2070
-
2071
- [Per-backup override test case: `tests/test_par2_overrides.py`](v2/tests/test_par2_overrides.py)
2072
-
2073
- #### 1.0.2
2074
-
2075
- ##### Trace Logging
2076
-
2077
- To support debugging without cluttering the main log file, a secondary trace log is now created (e.g., `dar-backup.trace.log`).
2078
- This file captures all `DEBUG` level messages and full exception stack traces.
2079
-
2080
- You can configure its rotation in the `[MISC]` section:
2081
-
2082
- - `TRACE_LOG_MAX_BYTES`: Max size of the trace log file in bytes. Default is `10485760` (10 MB).
2083
- - `TRACE_LOG_BACKUP_COUNT`: Number of rotated trace log files to keep. Default is `1`.
2084
-
2085
- Example:
2086
-
2087
- ```ini
2088
- [MISC]
2089
- TRACE_LOG_MAX_BYTES = 10485760
2090
- TRACE_LOG_BACKUP_COUNT = 1
2091
- ```
2092
-
2093
- ##### Command output Capture
2094
-
2095
- - New optional `[MISC]` setting: `COMMAND_CAPTURE_MAX_BYTES` (default 102400).
2096
- - Limits how much stdout/stderr is kept in memory per command while still logging full output.
2097
- - Set to `0` to disable buffering entirely. Command output is still streamed to dar-backup-commands.log
2098
- - If set to `0`, the calling function cannot rely on output from the executed command. The exit value is the only result provided.
2099
-
2100
- Example:
2101
-
2102
- ```ini
2103
- [MISC]
2104
- COMMAND_CAPTURE_MAX_BYTES = 102400
2105
- ```