dar-backup 0.6.7__py3-none-any.whl → 0.6.8__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/.darrc +6 -4
- dar_backup/__about__.py +1 -1
- dar_backup/dar_backup.py +9 -9
- dar_backup/manager.py +38 -2
- {dar_backup-0.6.7.dist-info → dar_backup-0.6.8.dist-info}/METADATA +6 -2
- dar_backup-0.6.8.dist-info/RECORD +13 -0
- dar_backup-0.6.7.dist-info/RECORD +0 -13
- {dar_backup-0.6.7.dist-info → dar_backup-0.6.8.dist-info}/WHEEL +0 -0
- {dar_backup-0.6.7.dist-info → dar_backup-0.6.8.dist-info}/entry_points.txt +0 -0
- {dar_backup-0.6.7.dist-info → dar_backup-0.6.8.dist-info}/licenses/LICENSE +0 -0
dar_backup/.darrc
CHANGED
|
@@ -26,19 +26,22 @@ verbose:
|
|
|
26
26
|
# -va
|
|
27
27
|
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
restore-options:
|
|
30
30
|
# don't restore File Specific Attributes
|
|
31
31
|
#--fsa-scope none
|
|
32
32
|
|
|
33
33
|
# ignore owner, useful when used by a non-privileged user
|
|
34
34
|
--comparison-field=ignore-owner
|
|
35
35
|
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
# Exclude specific file types from compression
|
|
39
|
+
compress-exclusion:
|
|
40
|
+
|
|
36
41
|
# First setting case insensitive mode on:
|
|
37
42
|
-an
|
|
38
43
|
-ag
|
|
39
44
|
|
|
40
|
-
# Exclude specific file types from compression
|
|
41
|
-
compress-exclusion:
|
|
42
45
|
-Z "*.gz"
|
|
43
46
|
-Z "*.bz2"
|
|
44
47
|
-Z "*.xz"
|
|
@@ -105,6 +108,5 @@ compress-exclusion:
|
|
|
105
108
|
-Z "*.dar"
|
|
106
109
|
|
|
107
110
|
# Now we swap back to case sensitive mode for masks which is the default
|
|
108
|
-
# mode:
|
|
109
111
|
-acase
|
|
110
112
|
|
dar_backup/__about__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.6.
|
|
1
|
+
__version__ = "0.6.8"
|
dar_backup/dar_backup.py
CHANGED
|
@@ -66,7 +66,7 @@ def generic_backup(type: str, command: List[str], backup_file: str, backup_defin
|
|
|
66
66
|
raise Exception(str(process))
|
|
67
67
|
|
|
68
68
|
if process.returncode == 0 or process.returncode == 5:
|
|
69
|
-
add_catalog_command = ['manager', '--add-specific-archive' ,backup_file, '--config-file', args.config_file
|
|
69
|
+
add_catalog_command = ['manager', '--add-specific-archive' ,backup_file, '--config-file', args.config_file]
|
|
70
70
|
command_result = run_command(add_catalog_command, config_settings.command_timeout_secs)
|
|
71
71
|
if command_result.returncode == 0:
|
|
72
72
|
logger.info(f"Catalog for archive '{backup_file}' added successfully to its manager.")
|
|
@@ -209,7 +209,7 @@ def verify(args: argparse.Namespace, backup_file: str, backup_definition: str, c
|
|
|
209
209
|
for restored_file_path in random_files:
|
|
210
210
|
try:
|
|
211
211
|
logger.info(f"Restoring file: '{restored_file_path}' from backup to: '{config_settings.test_restore_dir}' for file comparing")
|
|
212
|
-
command = ['dar', '-x', backup_file, '-g', restored_file_path.lstrip("/"), '-R', config_settings.test_restore_dir, '-
|
|
212
|
+
command = ['dar', '-x', backup_file, '-g', restored_file_path.lstrip("/"), '-R', config_settings.test_restore_dir, '-Q', '-B', args.darrc, 'restore-options']
|
|
213
213
|
logger.info(f"Running command: {' '.join(map(shlex.quote, command))}")
|
|
214
214
|
process = run_command(command, config_settings.command_timeout_secs)
|
|
215
215
|
if process.returncode != 0:
|
|
@@ -228,7 +228,7 @@ def verify(args: argparse.Namespace, backup_file: str, backup_definition: str, c
|
|
|
228
228
|
|
|
229
229
|
|
|
230
230
|
|
|
231
|
-
def restore_backup(backup_name: str, config_settings: ConfigSettings, restore_dir: str, selection: str =None):
|
|
231
|
+
def restore_backup(backup_name: str, config_settings: ConfigSettings, restore_dir: str, darrc: str, selection: str =None):
|
|
232
232
|
"""
|
|
233
233
|
Restores a backup file to a specified directory.
|
|
234
234
|
|
|
@@ -239,7 +239,7 @@ def restore_backup(backup_name: str, config_settings: ConfigSettings, restore_di
|
|
|
239
239
|
selection (str, optional): A selection criteria to restore specific files or directories. Defaults to None.
|
|
240
240
|
"""
|
|
241
241
|
backup_file = os.path.join(config_settings.backup_dir, backup_name)
|
|
242
|
-
command = ['dar', '-x', backup_file, '-
|
|
242
|
+
command = ['dar', '-x', backup_file, '-Q', '-D']
|
|
243
243
|
if restore_dir:
|
|
244
244
|
if not os.path.exists(restore_dir):
|
|
245
245
|
os.makedirs(restore_dir)
|
|
@@ -249,6 +249,7 @@ def restore_backup(backup_name: str, config_settings: ConfigSettings, restore_di
|
|
|
249
249
|
if selection:
|
|
250
250
|
selection_criteria = shlex.split(selection)
|
|
251
251
|
command.extend(selection_criteria)
|
|
252
|
+
command.extend(['-B', darrc, 'restore-options']) # the .darrc `restore-options` section
|
|
252
253
|
logger.info(f"Running restore command: {' '.join(map(shlex.quote, command))}")
|
|
253
254
|
try:
|
|
254
255
|
process = run_command(command, config_settings.command_timeout_secs)
|
|
@@ -428,10 +429,9 @@ def perform_backup(args: argparse.Namespace, config_settings: ConfigSettings, ba
|
|
|
428
429
|
logger.error("Verification failed.")
|
|
429
430
|
|
|
430
431
|
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
logger.info("par2 files completed successfully.")
|
|
432
|
+
logger.info("Generate par2 redundancy files.")
|
|
433
|
+
generate_par2_files(backup_file, config_settings, args)
|
|
434
|
+
logger.info("par2 files completed successfully.")
|
|
435
435
|
|
|
436
436
|
|
|
437
437
|
except Exception as e:
|
|
@@ -677,7 +677,7 @@ def main():
|
|
|
677
677
|
list_contents(args.list_contents, config_settings.backup_dir, args.selection)
|
|
678
678
|
elif args.restore:
|
|
679
679
|
logger.debug(f"Restoring {args.restore} to {restore_dir}")
|
|
680
|
-
restore_backup(args.restore, config_settings, restore_dir, args.selection)
|
|
680
|
+
restore_backup(args.restore, config_settings, restore_dir, args.darrc, args.selection)
|
|
681
681
|
else:
|
|
682
682
|
parser.print_help()
|
|
683
683
|
|
dar_backup/manager.py
CHANGED
|
@@ -141,16 +141,41 @@ def cat_no_for_name(archive: str, config_settings: ConfigSettings) -> int:
|
|
|
141
141
|
|
|
142
142
|
|
|
143
143
|
|
|
144
|
+
def list_archive_contents(archive: str, config_settings: ConfigSettings) -> int :
|
|
145
|
+
"""
|
|
146
|
+
List the contents of a specific archive, given the archive name
|
|
147
|
+
"""
|
|
148
|
+
backup_def = backup_def_from_archive(archive)
|
|
149
|
+
database = f"{backup_def}{DB_SUFFIX}"
|
|
150
|
+
database_path = os.path.join(config_settings.backup_dir, database)
|
|
151
|
+
if not os.path.exists(database_path):
|
|
152
|
+
logger.error(f'Database not found: "{database_path}"')
|
|
153
|
+
return 1
|
|
154
|
+
cat_no = cat_no_for_name(archive, config_settings)
|
|
155
|
+
if cat_no < 0:
|
|
156
|
+
logger.error(f"archive: '{archive}' not found in database: '{database_path}'")
|
|
157
|
+
return 1
|
|
158
|
+
command = ['dar_manager', '--base', database_path, '-u', f"{cat_no}"]
|
|
159
|
+
process = run_command(command)
|
|
160
|
+
stdout, stderr = process.stdout, process.stderr
|
|
161
|
+
if process.returncode != 0:
|
|
162
|
+
logger.error(f'Error listing catalogs for: "{database_path}"')
|
|
163
|
+
logger.error(f"stderr: {stderr}")
|
|
164
|
+
logger.error(f"stdout: {stdout}")
|
|
165
|
+
else:
|
|
166
|
+
print(stdout)
|
|
167
|
+
return process.returncode
|
|
168
|
+
|
|
144
169
|
|
|
145
170
|
|
|
146
|
-
def list_catalog_contents(catalog_number: int, backup_def: str, config_settings: ConfigSettings):
|
|
171
|
+
def list_catalog_contents(catalog_number: int, backup_def: str, config_settings: ConfigSettings) -> int:
|
|
147
172
|
"""
|
|
148
173
|
List the contents of catalog # in catalog database for given backup definition
|
|
149
174
|
"""
|
|
150
175
|
database = f"{backup_def}{DB_SUFFIX}"
|
|
151
176
|
database_path = os.path.join(config_settings.backup_dir, database)
|
|
152
177
|
if not os.path.exists(database_path):
|
|
153
|
-
logger.error(f'
|
|
178
|
+
logger.error(f'Catalog database not found: "{database_path}"')
|
|
154
179
|
return 1
|
|
155
180
|
command = ['dar_manager', '--base', database_path, '-u', f"{catalog_number}"]
|
|
156
181
|
process = run_command(command)
|
|
@@ -347,6 +372,7 @@ def main():
|
|
|
347
372
|
parser.add_argument('--remove-specific-archive', type=str, help='Remove this archive from catalog database')
|
|
348
373
|
parser.add_argument('-l', '--list-catalogs', action='store_true', help='List catalogs in databases for all backup definitions')
|
|
349
374
|
parser.add_argument('--list-catalog-contents', type=int, help="List contents of a catalog. Argument is the 'archive #', '-d <definition>' argument is also required")
|
|
375
|
+
parser.add_argument('--list-archive-contents', type=str, help="List contents of the archive's catalog.")
|
|
350
376
|
parser.add_argument('--find-file', type=str, help="List catalogs containing <path>/file. '-d <definition>' argument is also required")
|
|
351
377
|
parser.add_argument('--verbose', action='store_true', help='Be more verbose')
|
|
352
378
|
parser.add_argument('--log-level', type=str, help="`debug` or `trace`, default is `info`", default="info")
|
|
@@ -415,6 +441,11 @@ See section 15 and section 16 in the supplied "LICENSE" file.''')
|
|
|
415
441
|
sys.exit(1)
|
|
416
442
|
|
|
417
443
|
|
|
444
|
+
if args.list_archive_contents and not args.list_archive_contents.strip():
|
|
445
|
+
logger.error(f"--list-archive-contents <param> not given, exiting")
|
|
446
|
+
sys.exit(1)
|
|
447
|
+
|
|
448
|
+
|
|
418
449
|
if args.list_catalog_contents and not args.backup_def:
|
|
419
450
|
logger.error(f"--list-catalog-contents requires the --backup-def, exiting")
|
|
420
451
|
sys.exit(1)
|
|
@@ -470,6 +501,11 @@ See section 15 and section 16 in the supplied "LICENSE" file.''')
|
|
|
470
501
|
result = 1
|
|
471
502
|
sys.exit(result)
|
|
472
503
|
|
|
504
|
+
|
|
505
|
+
if args.list_archive_contents:
|
|
506
|
+
result = list_archive_contents(args.list_archive_contents, config_settings)
|
|
507
|
+
sys.exit(result)
|
|
508
|
+
|
|
473
509
|
if args.list_catalog_contents:
|
|
474
510
|
result = list_catalog_contents(args.list_catalog_contents, args.backup_def, config_settings)
|
|
475
511
|
sys.exit(result)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dar-backup
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.8
|
|
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: Homepage, https://github.com/per2jensen/dar-backup/tree/main/v2
|
|
6
6
|
Project-URL: Changelog, https://github.com/per2jensen/dar-backup/blob/main/v2/Changelog.md
|
|
@@ -681,7 +681,7 @@ License: GNU GENERAL PUBLIC LICENSE
|
|
|
681
681
|
Public License instead of this License. But first, please read
|
|
682
682
|
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
|
683
683
|
License-File: LICENSE
|
|
684
|
-
Classifier: Development Status ::
|
|
684
|
+
Classifier: Development Status :: 4 - Beta
|
|
685
685
|
Classifier: Intended Audience :: End Users/Desktop
|
|
686
686
|
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
|
|
687
687
|
Classifier: Operating System :: POSIX :: Linux
|
|
@@ -718,9 +718,13 @@ Description-Content-Type: text/markdown
|
|
|
718
718
|
These scripts are licensed under the GPLv3 license.
|
|
719
719
|
Read more here: https://www.gnu.org/licenses/gpl-3.0.en.html, or have a look at the ["LICENSE"](https://github.com/per2jensen/dar-backup/blob/main/LICENSE) file in this repository.
|
|
720
720
|
|
|
721
|
+
|
|
721
722
|
# Status
|
|
722
723
|
As of August 8, 2024 I am using the alpha versions of `dar-backup` (alpha-0.5.9 onwards) in my automated backup routine.
|
|
723
724
|
|
|
725
|
+
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.
|
|
726
|
+
|
|
727
|
+
|
|
724
728
|
**Breaking change in version 0.6.0**
|
|
725
729
|
|
|
726
730
|
Version 0.6.0 and forwards requires the config variable *COMMAND_TIMEOUT_SECS* in the config file.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
dar_backup/.darrc,sha256=-aerqivZmOsW_XBCh9IfbYTUvw0GkzDSr3Vx4GcNB1g,2113
|
|
2
|
+
dar_backup/__about__.py,sha256=qbWTdDuFyvScwNj95KArnOcQph9tiLZZ8rgNJYlJ4AE,21
|
|
3
|
+
dar_backup/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
dar_backup/cleanup.py,sha256=9yEdRR84XPtEvBGc2QfwGBQl2tdTPttjetHeiSc_TsM,11419
|
|
5
|
+
dar_backup/config_settings.py,sha256=CBMUhLOOZ-x7CRdS3vBDk4TYaGqC4N1Ot8IMH-qPaI0,3617
|
|
6
|
+
dar_backup/dar_backup.py,sha256=VbpyiCnoVvJuMWS7LO9wo8WIcDegCPVjb5Q7xN9J9Gg,32731
|
|
7
|
+
dar_backup/manager.py,sha256=HDa8eYF89QFhlBRR4EWRzzmswOW00S_w8ToZ5SARO_o,21359
|
|
8
|
+
dar_backup/util.py,sha256=SSSJYM9lQZfubhTUBlX1xDGWmCpYEF3ePARmlY544xM,11283
|
|
9
|
+
dar_backup-0.6.8.dist-info/METADATA,sha256=U3iy7Gzz-D6p5UePy0VLzX2lNbELs0teKBEZXr-sSqc,64610
|
|
10
|
+
dar_backup-0.6.8.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
11
|
+
dar_backup-0.6.8.dist-info/entry_points.txt,sha256=x9vnW-JEl8mpDJC69f_XBcn0mBSkV1U0cyvFV-NAP1g,126
|
|
12
|
+
dar_backup-0.6.8.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
13
|
+
dar_backup-0.6.8.dist-info/RECORD,,
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
dar_backup/.darrc,sha256=3d9opAnnZGU9XLyQpTDsLtgo6hqsvZ3JU-yMLz-7_f0,2110
|
|
2
|
-
dar_backup/__about__.py,sha256=0ouks3vBIBYQpXQLGG2c_DveClXKjoOTb3ZY9LRV9Xw,21
|
|
3
|
-
dar_backup/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
-
dar_backup/cleanup.py,sha256=9yEdRR84XPtEvBGc2QfwGBQl2tdTPttjetHeiSc_TsM,11419
|
|
5
|
-
dar_backup/config_settings.py,sha256=CBMUhLOOZ-x7CRdS3vBDk4TYaGqC4N1Ot8IMH-qPaI0,3617
|
|
6
|
-
dar_backup/dar_backup.py,sha256=oUlGCLeYwkJKSqn1qzKqkhpoQVTp-fCWyJcpmkSnLjc,32703
|
|
7
|
-
dar_backup/manager.py,sha256=S66gC6m-xaMMZR3MtaB0VGYEaGPohAO0DNMSSXvimM4,19869
|
|
8
|
-
dar_backup/util.py,sha256=SSSJYM9lQZfubhTUBlX1xDGWmCpYEF3ePARmlY544xM,11283
|
|
9
|
-
dar_backup-0.6.7.dist-info/METADATA,sha256=QB3M9KzbnyRUhRBbljmYFN5rYEhvzVBB2EbOD6QWsTs,64452
|
|
10
|
-
dar_backup-0.6.7.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
11
|
-
dar_backup-0.6.7.dist-info/entry_points.txt,sha256=x9vnW-JEl8mpDJC69f_XBcn0mBSkV1U0cyvFV-NAP1g,126
|
|
12
|
-
dar_backup-0.6.7.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
13
|
-
dar_backup-0.6.7.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|