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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dar-backup
3
- Version: 1.0.1
3
+ Version: 1.1.0
4
4
  Summary: A script to do full, differential and incremental backups using dar. Some files are restored from the backups during verification, after which par2 redundancy files are created. The script also has a cleanup feature to remove old backups and par2 files.
5
5
  Project-URL: GPG Public Key, https://keys.openpgp.org/search?q=dar-backup@pm.me
6
6
  Project-URL: Homepage, https://github.com/per2jensen/dar-backup/tree/main/v2
@@ -686,27 +686,30 @@ Classifier: Development Status :: 5 - Production/Stable
686
686
  Classifier: Intended Audience :: End Users/Desktop
687
687
  Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
688
688
  Classifier: Operating System :: POSIX :: Linux
689
- Classifier: Programming Language :: Python :: 3.9
689
+ Classifier: Programming Language :: Python :: 3.11
690
690
  Classifier: Topic :: System :: Archiving :: Backup
691
- Requires-Python: >=3.9
691
+ Requires-Python: >=3.11
692
692
  Requires-Dist: argcomplete>=3.6.2
693
+ Requires-Dist: dateparser>=1.2.0
693
694
  Requires-Dist: inputimeout>=1.0.4
694
695
  Requires-Dist: jinja2>=3.1.6
695
696
  Requires-Dist: rich>=13.0.0
696
697
  Provides-Extra: dev
697
698
  Requires-Dist: anyio>=4.4.0; extra == 'dev'
698
- Requires-Dist: black>=25.1.0; extra == 'dev'
699
699
  Requires-Dist: coverage>=7.8.2; extra == 'dev'
700
700
  Requires-Dist: h11>=0.16.0; extra == 'dev'
701
701
  Requires-Dist: httpcore>=0.17.3; extra == 'dev'
702
702
  Requires-Dist: matplotlib>=3.10.3; extra == 'dev'
703
+ Requires-Dist: mypy; extra == 'dev'
703
704
  Requires-Dist: pandas>=2.3.0; extra == 'dev'
704
705
  Requires-Dist: psutil>=7.0.0; extra == 'dev'
705
- Requires-Dist: pytest; extra == 'dev'
706
706
  Requires-Dist: pytest-cov>=6.1.1; extra == 'dev'
707
+ Requires-Dist: pytest-json-report; extra == 'dev'
708
+ Requires-Dist: pytest-mock; extra == 'dev'
707
709
  Requires-Dist: pytest-timeout>=2.4.0; extra == 'dev'
708
710
  Requires-Dist: pytest>=8.4.0; extra == 'dev'
709
711
  Requires-Dist: requests>=2.32.2; extra == 'dev'
712
+ Requires-Dist: ruff; extra == 'dev'
710
713
  Requires-Dist: wheel>=0.45.1; extra == 'dev'
711
714
  Requires-Dist: zipp>=3.19.1; extra == 'dev'
712
715
  Provides-Extra: packaging
@@ -742,6 +745,18 @@ You can see the [v2 Changelog](v2/Changelog.md) for details on features and prog
742
745
 
743
746
  Version **1.0.0** was reached on October 9, 2025.
744
747
 
748
+ **High-level flow**
749
+
750
+ [![dar-backup overview](v2/doc/dar-backup-overview-small.png)](#dar-backup-principles)
751
+
752
+ **Quick links**
753
+
754
+ - [Quick Guide](#quick-guide)
755
+ - [Redundancy to fix bitrot](#par2)
756
+ - [Point In Time Recovery](#point-in-time-recovery-pitr)
757
+ - [550+ unit tests & integration tests](#test-coverage)
758
+ - par2 bitrot repair proof, full/diff/incr with restore, PITR verifications, ...
759
+
745
760
  ## Table of Contents
746
761
 
747
762
  - [`dar-backup`](#dar-backup)
@@ -785,6 +800,7 @@ Version **1.0.0** was reached on October 9, 2025.
785
800
  - [select a directory](#select-a-directory)
786
801
  - [select files with "Z50" in the file name and exclude .xmp files](#select-files-with-z50-in-the-file-name-and-exclude-xmp-files)
787
802
  - [Restoring](#restoring)
803
+ - [Point-in-Time Recovery (PITR)](#point-in-time-recovery-pitr)
788
804
  - [default location for restores](#default-location-for-restores)
789
805
  - [--restore-dir option](#--restore-dir-option)
790
806
  - [a single file](#a-single-file)
@@ -813,8 +829,8 @@ Version **1.0.0** was reached on October 9, 2025.
813
829
  - [Performance tip due to par2](#performance-tip-due-to-par2)
814
830
  - [.darrc sets -vd -vf (since v0.6.4)](#darrc-sets--vd--vf-since-v064)
815
831
  - [Separate log file for command output](#separate-log-file-for-command-output)
832
+ - [Trace Logging (Debug details)](#trace-logging-debug-details)
816
833
  - [Skipping cache directories](#skipping-cache-directories)
817
- - [Progress bar and current directory](#progress-bar-and-current-directory)
818
834
  - [Shell autocompletion](#shell-autocompletion)
819
835
  - [Use it](#use-it)
820
836
  - [Archive name completion (smart, context-aware)](#archive-name-completion-smart-context-aware)
@@ -826,7 +842,10 @@ Version **1.0.0** was reached on October 9, 2025.
826
842
  - [Projects these scripts benefit from](#projects-these-scripts-benefit-from)
827
843
  - [Reference](#reference)
828
844
  - [CLI Tools Overview](#cli-tools-overview)
829
- - [test coverage](#test-coverage)
845
+ - [Test coverage](#test-coverage)
846
+ - [Test selection with markers](#test-selection-with-markers)
847
+ - [Common runs](#common-runs)
848
+ - [Run all tests](#run-all-tests)
830
849
  - [Dar-backup options](#dar-backup-options)
831
850
  - [Dar-backup exit codes](#dar-backup-exit-codes)
832
851
  - [Dar-backup env vars](#dar-backup-env-vars)
@@ -841,6 +860,10 @@ Version **1.0.0** was reached on October 9, 2025.
841
860
  - [DISCORD WEBHOOK](#discord-webhook)
842
861
  - [Restore test config](#restore-test-config)
843
862
  - [Par2](#par2-1)
863
+ - [1.0.2](#102)
864
+ - [Trace Logging](#trace-logging)
865
+ - [Command output Capture](#command-output-capture)
866
+ - [1.1.0](#110)
844
867
 
845
868
  ## My use case
846
869
 
@@ -1487,6 +1510,7 @@ NO_FILES_VERIFICATION = 5
1487
1510
  # timeout in seconds for backup, test, restore and par2 operations
1488
1511
  # The author has such `dar` tasks running for 10-15 hours on the yearly backups, so a value of 24 hours is used.
1489
1512
  # If a timeout is not specified when using the util.run_command(), a default timeout of 30 secs is used.
1513
+ # Use -1 to disable timeouts.
1490
1514
  COMMAND_TIMEOUT_SECS = 86400
1491
1515
 
1492
1516
  [DIRECTORIES]
@@ -1509,7 +1533,6 @@ ERROR_CORRECTION_PERCENT = 5
1509
1533
  ENABLED = True
1510
1534
  # Optional PAR2 configuration
1511
1535
  # PAR2_DIR = /path/to/par2-store
1512
- # PAR2_MODE = per-slice
1513
1536
  # PAR2_RATIO_FULL = 10
1514
1537
  # PAR2_RATIO_DIFF = 5
1515
1538
  # PAR2_RATIO_INCR = 5
@@ -1518,7 +1541,6 @@ ENABLED = True
1518
1541
  # Optional per-backup overrides (section name = backup definition)
1519
1542
  [media-files]
1520
1543
  PAR2_DIR = /mnt/par2/media-files
1521
- PAR2_MODE = per-archive
1522
1544
  PAR2_RATIO_FULL = 10
1523
1545
 
1524
1546
  # scripts to run before the backup to setup the environment
@@ -1536,6 +1558,7 @@ PAR2 notes:
1536
1558
  - If `PAR2_DIR` is unset, par2 files are created next to the archive slices (legacy behavior) and no manifest is written
1537
1559
  - When `PAR2_DIR` is set, dar-backup writes a manifest next to the par2 set:
1538
1560
  `archive_base.par2.manifest.ini`
1561
+ - When generating a par2 set, par2 reads all archive slices before writing any output files; for large backups, this initial read can take hours
1539
1562
  - Verify or repair using:
1540
1563
  `par2 verify -B <archive_dir> <par2_set.par2>`
1541
1564
  `par2 repair -B <archive_dir> <par2_set.par2>`
@@ -1861,6 +1884,25 @@ This happens when the shell splits the quoted string or interprets globs before
1861
1884
 
1862
1885
  > 💡 **Tip:** See [dar's documentation](http://dar.linux.free.fr/doc/man/dar.html#COMMANDS%20AND%20OPTIONS)
1863
1886
 
1887
+ >
1888
+ > 💡💡 **Tip:** To filter all the empty directories away that `dar` emits when listing contents, append this grep:
1889
+ >
1890
+ > ```bash
1891
+ > |grep -vE '\s+d[rwx-]{9}\s'
1892
+ >```
1893
+ >
1894
+ >Example using the grep to discard directory noise from `dar's` output:
1895
+ >
1896
+ > ```bash
1897
+ > dar-backup --list-contents media-files_INCR_2025-05-10 --selection="-I '*Z50*' -X '*.xmp'" | grep -vE '\s+d[rwx-]{9}\s'
1898
+ >[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
1899
+ >[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
1900
+ >[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
1901
+ >[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
1902
+ >[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
1903
+ >...
1904
+ >```
1905
+
1864
1906
  ### select a directory
1865
1907
 
1866
1908
  Select files and sub directories in `home/user/data/2025/2025-05-09-Roskilde-Nordisk-udstilling`
@@ -1909,6 +1951,97 @@ gives something like
1909
1951
 
1910
1952
  ## Restoring
1911
1953
 
1954
+ ### Point-in-Time Recovery (PITR)
1955
+
1956
+ Use the `manager` CLI to restore files as they existed at a specific time:
1957
+
1958
+ ```bash
1959
+ . <the virtual env>/bin/activate
1960
+ manager --config-file <dar-backup.conf> \
1961
+ --backup-def <definition> \
1962
+ --restore-path tmp/path/to/file.txt \
1963
+ --when "2026-01-29 15:00:39" \
1964
+ --target /tmp/restore_pitr \
1965
+ --log-stdout --verbose
1966
+ deactivate
1967
+ ```
1968
+
1969
+ Restore a directory (same idea, but the path is a directory):
1970
+
1971
+ ```bash
1972
+ . <the virtual env>/bin/activate
1973
+ manager --config-file <dar-backup.conf> \
1974
+ --backup-def <definition> \
1975
+ --restore-path tmp/path/to/directory/ \
1976
+ --when "2026-01-29 15:00:39" \
1977
+ --target /tmp/restore_pitr \
1978
+ --log-stdout --verbose
1979
+ deactivate
1980
+ ```
1981
+
1982
+ Dry-run the archive chain selection before restoring:
1983
+
1984
+ ```bash
1985
+ . <the virtual env>/bin/activate
1986
+ manager --config-file <dar-backup.conf> \
1987
+ --backup-def <definition> \
1988
+ --restore-path tmp/path/to/directory \
1989
+ --when "2026-01-29 15:00:39" \
1990
+ --pitr-report \
1991
+ --log-stdout --verbose
1992
+ deactivate
1993
+ ```
1994
+
1995
+ **Notes**:
1996
+ - `--restore-path` must be a relative path as stored in the catalog (no leading slash).
1997
+ - If a restore path is a **directory** and its name has no file extension, add a trailing `/` to make the intent explicit (e.g., `photos/2026/01/`). This avoids ambiguity with file paths that also lack extensions.
1998
+ - Example (directory name has no extension):
1999
+ - `manager --backup-def <definition> --restore-path "Automatic Upload/Per - iPhone/2026/01/" --when "now" --target /tmp/restore_pitr`
2000
+ - `--target` is required to avoid accidental restores into the current working directory.
2001
+ - Protected targets are blocked (e.g., `/etc`, `/usr`, `/bin`, `/var`, `/root`, `/boot`, `/lib`, `/proc`, `/sys`, `/dev`).
2002
+ - `--pitr-report` does a **dry-run** chain selection; if it reports missing archives, a restore will fail until the catalog is rebuilt or missing archives are restored.
2003
+ - `--pitr-report-first` runs the same chain report before a restore and aborts if any archive is missing (useful as a safety preflight).
2004
+ - `--when` accepts natural-language date expressions via `dateparser`. Examples:
2005
+ - `"now"`
2006
+ - `"2 weeks ago"`
2007
+ - `"2025-10-05 14:30"`
2008
+ - `yesterday 23:00`
2009
+ - PITR restores use the catalog to select the correct archive chain (FULL → DIFF → INCR) and then restore **directly with `dar`** in that order.
2010
+ - This avoids interactive `dar_manager` prompts (e.g., non‑monotonic mtimes often seen on pCloud/FUSE).
2011
+ - Directories can get a **new mtime** when files inside them are added/removed; the chain restore ensures the correct tree is rebuilt even if mtimes look “too new”.
2012
+ - Missing archives:
2013
+ - PITR uses the latest FULL, the latest DIFF after that FULL, and the latest INCR after that DIFF.
2014
+ - If any archive slice in that chain is missing on disk, PITR restore **fails** and logs which archive slices are missing.
2015
+ - A short Discord notice is sent (if configured) so missing archives are visible immediately.
2016
+ - Relocating archive paths in the catalog:
2017
+ - The catalog stores **absolute archive paths**. If archives move (or a mountpoint changes), the catalog will still point to the old path.
2018
+ - This can happen when manager DBs are moved to another disk and the archives are re-added from a different mountpoint.
2019
+ - Use the built-in relocate command to rewrite a path prefix in-place:
2020
+ - Dry run:
2021
+ - `manager --relocate-archive-path /old/path /new/path --relocate-archive-path-dry-run --backup-def <definition>`
2022
+ - Apply:
2023
+ - `manager --relocate-archive-path /old/path /new/path --backup-def <definition>`
2024
+ - Example (move `/home/pj/mnt/dar` to `/mnt/dar`):
2025
+ - `manager --relocate-archive-path /home/pj/mnt/dar /mnt/dar --backup-def pCloudDrive`
2026
+ - Alternative quick fix: create a symlink from the old path to the new path.
2027
+ - Rebuilding a catalog after archive loss:
2028
+ - If PITR fails due to missing archives, the catalog may no longer match what is actually on disk.
2029
+ - You can rebuild the catalog from the remaining archives and then retry PITR (with the understanding that older restore points may no longer be possible).
2030
+ - Example:
2031
+ - `manager --create-db --config-file <dar-backup.conf>`
2032
+ - `manager --add-dir <backup_dir> --backup-def <definition> --config-file <dar-backup.conf>`
2033
+ - Or add individual archives:
2034
+ - `manager --add-specific-archive <path/to/archive> --config-file <dar-backup.conf>`
2035
+
2036
+ Example of the issue:
2037
+ 1) FULL backup at 10:00 with `/data/photos/`
2038
+ 2) You add files at 11:00 (directory mtime updates)
2039
+ 3) DIFF backup at 11:05
2040
+ 4) You request PITR restore of `/data/photos/` at 10:30
2041
+
2042
+ `dar_manager -w` may say “directory did not exist before that time” because the directory mtime is now 11:00+.
2043
+ The fallback still restores the correct tree as of 10:30 by applying the archive chain.
2044
+
1912
2045
  ### default location for restores
1913
2046
 
1914
2047
  dar-backup will use the TEST_RESTORE_DIR location as the Root for restores, if the --restore-dir option has not been supplied.
@@ -2217,23 +2350,29 @@ In order to not clutter that log file with the output of commands being run, a n
2217
2350
 
2218
2351
  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.
2219
2352
 
2220
- ### Skipping cache directories
2353
+ ### Trace Logging (Debug details)
2221
2354
 
2222
- The author uses the `--cache-directory-tagging` option in his [backup definitions](#backup-definition-example).
2355
+ 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.
2223
2356
 
2224
- 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.
2357
+ - **Main Log (`dar-backup.log`)**: Contains clean, human-readable INFO/ERROR messages. Stack traces are suppressed here.
2358
+ - **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.
2225
2359
 
2226
- If the option is not in the backup definition, the cache directories are backed up as any other.
2360
+ You can configure the rotation of this file in `[MISC]`:
2227
2361
 
2228
- ### Progress bar and current directory
2362
+ ```ini
2363
+ [MISC]
2364
+ # ... other settings ...
2365
+ TRACE_LOG_MAX_BYTES = 10485760 # 10 MB default
2366
+ TRACE_LOG_BACKUP_COUNT = 1 # Keep 1 old trace file (default)
2367
+ ```
2229
2368
 
2230
- If you run dar-backup interactively in a "normal" console on your computer,
2231
- dar-backup displays 2 visual artifacts to show progress.
2369
+ ### Skipping cache directories
2232
2370
 
2233
- 1. a progress bar that fills up and starts over
2234
- 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.
2371
+ The author uses the `--cache-directory-tagging` option in his [backup definitions](#backup-definition-example).
2235
2372
 
2236
- 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.
2373
+ 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.
2374
+
2375
+ If the option is not in the backup definition, the cache directories are backed up as any other.
2237
2376
 
2238
2377
  ### Shell autocompletion
2239
2378
 
@@ -2418,7 +2557,6 @@ pytest # run the test suite
2418
2557
 
2419
2558
  - Perhaps look into pre-processing backup definitions. As `dar` does not expand env vars
2420
2559
  `dar-backup` could do so and feed the result to `dar`.
2421
- - When run interactively, a progress bar during test and par2 generation would be nice.
2422
2560
  - Look into a way to move the .par2 files away from the `dar` slices, to maximize chance of good redundancy.
2423
2561
  - Add option to dar-backup to use the `dar` option `--fsa-scope none`
2424
2562
 
@@ -2453,40 +2591,135 @@ One backup definition per file
2453
2591
  | [installer](#installer-options) | Set up directories and optionally create catalog databases according to a config file |
2454
2592
  | [demo](#demo-options) | Set up required directories and config files for a demo|
2455
2593
 
2456
- ### test coverage
2594
+ ### Test coverage
2595
+
2596
+ #### Test selection with markers
2597
+
2598
+ The test suite is annotated with these markers:
2599
+
2600
+ - `unit` (fast, pure logic)
2601
+ - `component` (subprocess boundary with mocks/lightweight commands)
2602
+ - `integration` (end-to-end workflows; external tools)
2603
+ - `slow` (long-running/heavier integration)
2604
+ - `live_discord` (sends real webhook messages; opt-in only)
2605
+
2606
+ #### Common runs
2607
+
2608
+ ```bash
2609
+ # Fast local loop (unit + component)
2610
+ pytest -m "unit or component"
2611
+
2612
+ # Integration (exclude slow + live webhook)
2613
+ pytest -m "integration and not slow and not live_discord"
2614
+
2615
+ # Slow-only
2616
+ pytest -m slow
2457
2617
 
2458
- Running
2618
+ # Full suite (default pytest.ini already excludes live_discord)
2619
+ pytest -m "not live_discord"
2620
+
2621
+ # Live webhook (requires DAR_BACKUP_DISCORD_WEBHOOK_URL)
2622
+ pytest -m live_discord
2623
+ ```
2624
+
2625
+ #### Run all tests
2459
2626
 
2460
2627
  ```bash
2461
- pytest --cov=dar_backup tests/
2628
+ pytest
2462
2629
  ```
2463
2630
 
2464
- Results for version 1.0.0 in this report:
2631
+ Results for version 1.1.0 (pre-release, Feb 1, 2026) in this report:
2465
2632
 
2466
2633
  ```text
2467
- ====================================== tests coverage ======================================
2468
- _____________________ coverage: platform linux, python 3.12.3-final-0 ______________________
2634
+ ===================================== test session starts =====================================
2635
+ platform linux -- Python 3.12.3, pytest-8.4.0, pluggy-1.6.0
2636
+ rootdir: /home/pj/git/dar-backup/v2
2637
+ configfile: pytest.ini
2638
+ testpaths: tests
2639
+ plugins: anyio-4.9.0, timeout-2.4.0, cov-6.1.1, mock-3.15.1
2640
+ timeout: 1800.0s
2641
+ timeout method: signal
2642
+ timeout func_only: False
2643
+ collected 559 items / 1 deselected / 558 selected
2644
+
2645
+ tests/test_add_old_archive_confirmation.py .... [ 0%]
2646
+ tests/test_alternate_reference_archive.py ... [ 1%]
2647
+ tests/test_autocompletion_install.py ... [ 1%]
2648
+ tests/test_binary_info.py ...... [ 2%]
2649
+ tests/test_bitrot.py .. [ 3%]
2650
+ tests/test_clean_log.py .................... [ 6%]
2651
+ tests/test_cleanup.py ............................... [ 12%]
2652
+ tests/test_command_runner.py ......................................... [ 19%]
2653
+ tests/test_config_comments.py . [ 19%]
2654
+ tests/test_config_settings.py .............. [ 22%]
2655
+ tests/test_create_backup_command.py ... [ 22%]
2656
+ tests/test_create_full_diff_incr_backup.py .......... [ 24%]
2657
+ tests/test_dar_backup.py ....................................................... [ 34%]
2658
+ tests/test_dar_backup_additional_coverage.py ....................... [ 38%]
2659
+ tests/test_dar_backup_startup.py .. [ 39%]
2660
+ tests/test_darrc.py .. [ 39%]
2661
+ tests/test_demo.py ............. [ 41%]
2662
+ tests/test_discord_webhook.py .. [ 42%]
2663
+ tests/test_filter_darrc_file.py . [ 42%]
2664
+ tests/test_generic_backup_command_execution.py . [ 42%]
2665
+ tests/test_get_config_file.py ....... [ 43%]
2666
+ tests/test_gpt_file_compression.py . [ 43%]
2667
+ tests/test_gpt_tests.py ....... [ 45%]
2668
+ tests/test_installer.py .................. [ 48%]
2669
+ tests/test_links.py . [ 48%]
2670
+ tests/test_list_definitions.py . [ 48%]
2671
+ tests/test_listing.py ... [ 49%]
2672
+ tests/test_logging_trace.py .. [ 49%]
2673
+ tests/test_manager.py ................................................................. [ 61%]
2674
+ [ 61%]
2675
+ tests/test_manager_coverage.py .................................. [ 67%]
2676
+ tests/test_par2.py . [ 67%]
2677
+ tests/test_par2_manifest.py . [ 67%]
2678
+ tests/test_par2_multi_definitions.py . [ 67%]
2679
+ tests/test_par2_overrides.py . [ 68%]
2680
+ tests/test_pitr.py .............................................. [ 76%]
2681
+ tests/test_pitr_integration.py ..... [ 77%]
2682
+ tests/test_postreq.py . [ 77%]
2683
+ tests/test_preflight.py ... [ 77%]
2684
+ tests/test_prereq.py . [ 78%]
2685
+ tests/test_readme_changelog.py .......... [ 79%]
2686
+ tests/test_restore.py .... [ 80%]
2687
+ tests/test_run_command.py ......s [ 81%]
2688
+ tests/test_sanity_checks.py ................. [ 84%]
2689
+ tests/test_space_definition.py . [ 85%]
2690
+ tests/test_startup_cleanup.py ....... [ 86%]
2691
+ tests/test_status_indicators.py ....... [ 87%]
2692
+ tests/test_stress.py . [ 87%]
2693
+ tests/test_systemd_unit_generation.py .......... [ 89%]
2694
+ tests/test_trace_logging.py .. [ 89%]
2695
+ tests/test_util.py .......................................... [ 97%]
2696
+ tests/test_util_completers.py .......... [ 99%]
2697
+ tests/test_verbose.py ... [ 99%]
2698
+ tests/test_verify_cleanup.py . [100%]
2699
+
2700
+ ======================================= tests coverage ========================================
2701
+ _______________________ coverage: platform linux, python 3.12.3-final-0 _______________________
2469
2702
 
2470
2703
  Name Stmts Miss Branch BrPart Cover
2471
2704
  ------------------------------------------------------------------------
2472
- src/dar_backup/__about__.py 2 0 0 0 100%
2705
+ src/dar_backup/__about__.py 3 0 0 0 100%
2473
2706
  src/dar_backup/__init__.py 0 0 0 0 100%
2474
- src/dar_backup/clean_log.py 76 15 40 7 81%
2475
- src/dar_backup/cleanup.py 203 16 66 7 91%
2476
- src/dar_backup/command_runner.py 129 16 26 5 86%
2477
- src/dar_backup/config_settings.py 73 3 18 1 96%
2478
- src/dar_backup/dar_backup.py 551 28 180 21 93%
2479
- src/dar_backup/dar_backup_systemd.py 56 7 10 2 86%
2480
- src/dar_backup/demo.py 92 20 26 6 75%
2707
+ src/dar_backup/clean_log.py 114 10 46 2 91%
2708
+ src/dar_backup/cleanup.py 294 42 100 9 87%
2709
+ src/dar_backup/command_runner.py 231 20 82 10 90%
2710
+ src/dar_backup/config_settings.py 162 9 62 10 92%
2711
+ src/dar_backup/dar_backup.py 1027 55 420 49 92%
2712
+ src/dar_backup/dar_backup_systemd.py 56 1 10 1 97%
2713
+ src/dar_backup/demo.py 100 1 34 2 98%
2481
2714
  src/dar_backup/exceptions.py 2 0 0 0 100%
2482
- src/dar_backup/installer.py 107 14 46 9 82%
2483
- src/dar_backup/manager.py 427 42 152 15 90%
2484
- src/dar_backup/rich_progress.py 70 7 30 4 89%
2485
- src/dar_backup/util.py 339 41 88 21 85%
2715
+ src/dar_backup/installer.py 120 4 54 4 95%
2716
+ src/dar_backup/manager.py 1105 91 454 38 91%
2717
+ src/dar_backup/rich_progress.py 70 2 30 3 95%
2718
+ src/dar_backup/util.py 521 43 142 24 90%
2486
2719
  ------------------------------------------------------------------------
2487
- TOTAL 2127 209 682 98 89%
2488
- Coverage XML written to file coverage.xml
2489
- ======================== 257 passed, 1 skipped in 223.21s (0:03:43) ========================
2720
+ TOTAL 3805 278 1434 152 91%
2721
+ Coverage XML written to file /tmp/coverage.xml
2722
+ ================== 557 passed, 1 skipped, 1 deselected in 409.66s (0:06:49) ===================
2490
2723
  ```
2491
2724
 
2492
2725
  ### Dar-backup options
@@ -2558,6 +2791,13 @@ Available options:
2558
2791
  -l, --list-catalogs List catalogs in databases for all backup definitions.
2559
2792
  --list-archive-contents <archive> List the contents of an archive’s catalog by archive name.
2560
2793
  --find-file <file> Search catalogs for a specific file.
2794
+ --restore-path <path> [<path> ...] Restore specific path(s) (Point-in-Time Recovery).
2795
+ --when <timestamp> Date/time for restoration (used with --restore-path).
2796
+ --target <path> Target directory for restoration (default: current dir).
2797
+ --pitr-report Report PITR archive chain for --restore-path/--when without restoring.
2798
+ --pitr-report-first Run PITR chain report before restore and abort if missing archives.
2799
+ --relocate-archive-path <old> <new> Rewrite archive path prefix in the catalog DB (requires --backup-def).
2800
+ --relocate-archive-path-dry-run Show archive path changes without applying them (use with --relocate-archive-path).
2561
2801
  --verbose Enable verbose output.
2562
2802
  --log-level <level> Set log level (`debug` or `trace`, default is `info`).
2563
2803
 
@@ -2754,10 +2994,48 @@ PAR2_RUN_VERIFY = true
2754
2994
  #
2755
2995
  #[etc]
2756
2996
  # Keep global PAR2 settings but tweak ratios for this backup definition
2757
- # RATIO is i percent number
2997
+ # RATIO is given in percent (%)
2758
2998
  #PAR2_RATIO_FULL = 15
2759
2999
  #PAR2_RATIO_DIFF = 8
2760
3000
  #PAR2_RATIO_INCR = 8
2761
3001
  ```
2762
3002
 
2763
3003
  [Per-backup override test case: `tests/test_par2_overrides.py`](v2/tests/test_par2_overrides.py)
3004
+
3005
+ #### 1.0.2
3006
+
3007
+ ##### Trace Logging
3008
+
3009
+ To support debugging without cluttering the main log file, a secondary trace log is now created (e.g., `dar-backup.trace.log`).
3010
+ This file captures all `DEBUG` level messages and full exception stack traces.
3011
+
3012
+ You can configure its rotation in the `[MISC]` section:
3013
+
3014
+ - `TRACE_LOG_MAX_BYTES`: Max size of the trace log file in bytes. Default is `10485760` (10 MB).
3015
+ - `TRACE_LOG_BACKUP_COUNT`: Number of rotated trace log files to keep. Default is `1`.
3016
+
3017
+ Example:
3018
+
3019
+ ```ini
3020
+ [MISC]
3021
+ TRACE_LOG_MAX_BYTES = 10485760
3022
+ TRACE_LOG_BACKUP_COUNT = 1
3023
+ ```
3024
+
3025
+ ##### Command output Capture
3026
+
3027
+ - New optional `[MISC]` setting: `COMMAND_CAPTURE_MAX_BYTES` (default 102400).
3028
+ - Limits how much stdout/stderr is kept in memory per command while still logging full output.
3029
+ - Set to `0` to disable buffering entirely. Command output is still streamed to dar-backup-commands.log
3030
+ - If set to `0`, the calling function cannot rely on output from the executed command. The exit value is the only result provided.
3031
+
3032
+ Example:
3033
+
3034
+ ```ini
3035
+ [MISC]
3036
+ COMMAND_CAPTURE_MAX_BYTES = 102400
3037
+ ```
3038
+
3039
+ #### 1.1.0
3040
+
3041
+ COMMAND_TIMEOUT_SECS=-1 now disables timeout for commands executed.
@@ -0,0 +1,23 @@
1
+ dar_backup/.darrc,sha256=-aerqivZmOsW_XBCh9IfbYTUvw0GkzDSr3Vx4GcNB1g,2113
2
+ dar_backup/__about__.py,sha256=DYQe7Z3Iqf23m_tT6w_2w8TNZxvVTYCEbt1HJwr0C4M,370
3
+ dar_backup/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ dar_backup/clean_log.py,sha256=Uf6MjpS_v1IVZdfx7ogRo6j5EIscdxjLImn8GKZo_rc,7038
5
+ dar_backup/cleanup.py,sha256=Hds6q-3w5RAg69280JmofaoPtuSVLoOJTvTX_i8Veyw,19106
6
+ dar_backup/command_runner.py,sha256=tqOwm-eaghS5jkwlwbaN1Wl9bO1WNlqk-zrIRdnp2Rs,15067
7
+ dar_backup/config_settings.py,sha256=t3lFbYZ6XCnvKIU2EEpqJUW7OAz3rNb5iuCisW3D2mg,12698
8
+ dar_backup/dar-backup.conf,sha256=ejucmhEbSdqFU4JEVfrWbFj9H6U87TWSnhex3LraEUY,2124
9
+ dar_backup/dar-backup.conf.j2,sha256=kD13msmP2IXLjnJ9lZmqtLTnsUZq1EkPZAI1LlOkYXo,3852
10
+ dar_backup/dar_backup.py,sha256=ai4miv7S3W2sE5NwN6A-OaHifp2wRvJyMbGcYKPngXM,71183
11
+ dar_backup/dar_backup_systemd.py,sha256=BWy5tvjq4Gex1YleQhQH57b_nFhSVhKUF_cLvSlDMkw,3874
12
+ dar_backup/demo.py,sha256=DONTzskD5lq6CSeHQUf_kOQ5ntekn6t-keOszgtUocI,8228
13
+ dar_backup/demo_backup_def.j2,sha256=hQW2Glp0QGV3Kt8cwjS0mpOCdyzjVlpgbgL6LpXTKJA,1793
14
+ dar_backup/exceptions.py,sha256=dBQwgKUilgfb1Tnlm_m1Dl1IqoY75L0n1uRkm0DBVTk,158
15
+ dar_backup/installer.py,sha256=yJ0xXi24C1Vo6gnj2BlhV1X55ZIG5t21t8tNKTYSclM,7616
16
+ dar_backup/manager.py,sha256=g-EzgAZiDLgDPmpLi30Ss5gkKytiLTx-WiN4R4cKHuM,65924
17
+ dar_backup/rich_progress.py,sha256=SfwFxebBl6jnDQMUQr4McknkW1yQWaJVo1Ju1OD3okA,3221
18
+ dar_backup/util.py,sha256=pq-SIAI_Tt4C9LiFfHxwTWmSAAkhgdE5QtS4IgYjqdY,38594
19
+ dar_backup-1.1.0.dist-info/METADATA,sha256=-reQRtVee46ypbaT8Rhm5icV29y74GficyFzh7GVqr8,133833
20
+ dar_backup-1.1.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
21
+ dar_backup-1.1.0.dist-info/entry_points.txt,sha256=pOK9M8cHeAcGIatrYzkm_1O89kPk0enyYONALYjFBx4,286
22
+ dar_backup-1.1.0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
23
+ dar_backup-1.1.0.dist-info/RECORD,,