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