dar-backup 0.6.18__py3-none-any.whl → 0.6.20__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/manager.py CHANGED
@@ -20,11 +20,14 @@
20
20
  This script creates and maintains `dar` databases with catalogs.
21
21
  """
22
22
 
23
-
23
+ import argcomplete
24
24
  import argparse
25
25
  import os
26
26
  import re
27
27
  import sys
28
+ import subprocess
29
+
30
+ from inputimeout import inputimeout, TimeoutOccurred
28
31
 
29
32
 
30
33
  from . import __about__ as about
@@ -32,13 +35,17 @@ from dar_backup.config_settings import ConfigSettings
32
35
  from dar_backup.util import setup_logging
33
36
  from dar_backup.util import CommandResult
34
37
  from dar_backup.util import get_logger
38
+ from dar_backup.util import get_binary_info
39
+ from dar_backup.util import show_version
40
+ from dar_backup.util import print_aligned_settings
35
41
 
36
42
  from dar_backup.command_runner import CommandRunner
37
43
  from dar_backup.command_runner import CommandResult
44
+ from dar_backup.util import backup_definition_completer, list_archive_completer, archive_content_completer, add_specific_archive_completer
38
45
 
39
46
  from datetime import datetime
40
47
  from time import time
41
- from typing import Dict, List, NamedTuple
48
+ from typing import Dict, List, NamedTuple, Tuple
42
49
 
43
50
  # Constants
44
51
  SCRIPTNAME = os.path.basename(__file__)
@@ -49,6 +56,15 @@ DB_SUFFIX = ".db"
49
56
  logger = None
50
57
  runner = None
51
58
 
59
+
60
+ def get_db_dir(config_settings: ConfigSettings) -> str:
61
+ """
62
+ Return the correct directory for storing catalog databases.
63
+ Uses manager_db_dir if set, otherwise falls back to backup_dir.
64
+ """
65
+ return getattr(config_settings, "manager_db_dir", None) or config_settings.backup_dir
66
+
67
+
52
68
  def show_more_help():
53
69
  help_text = f"""
54
70
  NAME
@@ -57,68 +73,95 @@ NAME
57
73
  print(help_text)
58
74
 
59
75
 
60
- def create_db(backup_def: str, config_settings: ConfigSettings):
76
+ def create_db(backup_def: str, config_settings: ConfigSettings, logger, runner) -> int:
77
+ db_dir = get_db_dir(config_settings)
78
+
79
+ if not os.path.exists(db_dir):
80
+ logger.error(f"DB dir does not exist: {db_dir}")
81
+ return 1
82
+ if not os.path.isdir(db_dir):
83
+ logger.error(f"DB path exists but is not a directory: {db_dir}")
84
+ return 1
85
+ if not os.access(db_dir, os.W_OK):
86
+ logger.error(f"DB dir is not writable: {db_dir}")
87
+ return 1
88
+
61
89
  database = f"{backup_def}{DB_SUFFIX}"
62
-
63
- database_path = os.path.join(config_settings.backup_dir, database)
64
-
65
- logger.debug(f"BACKUP_DIR: {config_settings.backup_dir}")
90
+ database_path = os.path.join(db_dir, database)
91
+
92
+ logger.debug(f"DB directory: {db_dir}")
66
93
 
67
94
  if os.path.exists(database_path):
68
- logger.warning(f'"{database_path}" already exists, skipping creation')
95
+ logger.info(f'"{database_path}" already exists, skipping creation')
69
96
  return 0
70
97
  else:
71
98
  logger.info(f'Create catalog database: "{database_path}"')
72
- command = ['dar_manager', '--create' , database_path]
99
+ command = ['dar_manager', '--create', database_path]
73
100
  process = runner.run(command)
74
101
  logger.debug(f"return code from 'db created': {process.returncode}")
75
102
  if process.returncode == 0:
76
103
  logger.info(f'Database created: "{database_path}"')
77
104
  else:
78
105
  logger.error(f'Something went wrong creating the database: "{database_path}"')
79
- stdout, stderr = process.stdout, process.stderr
106
+ stdout, stderr = process.stdout, process.stderr
80
107
  logger.error(f"stderr: {stderr}")
81
108
  logger.error(f"stdout: {stdout}")
82
109
 
83
110
  return process.returncode
84
111
 
85
112
 
86
- def list_catalogs(backup_def: str, config_settings: ConfigSettings) -> NamedTuple:
113
+ def list_catalogs(backup_def: str, config_settings: ConfigSettings, suppress_output=False) -> CommandResult:
87
114
  """
115
+ List catalogs from the database for the given backup definition.
116
+
88
117
  Returns:
89
- a typing.NamedTuple of class dar-backup.util.CommandResult with the following properties:
90
- - process: of type subprocess.CompletedProcess: The result of the command execution.
91
- - stdout: of type str: The standard output of the command.
92
- - stderr: of type str: The standard error of the command.
93
- - returncode: of type int: The return code of the command.
94
- - timeout: of type int: The timeout value in seconds used to run the command.
95
- - command: of type list[str): The command executed.
118
+ A CommandResult containing the raw stdout/stderr and return code.
96
119
  """
97
120
  database = f"{backup_def}{DB_SUFFIX}"
98
- database_path = os.path.join(config_settings.backup_dir, database)
121
+ database_path = os.path.join(get_db_dir(config_settings), database)
122
+
99
123
  if not os.path.exists(database_path):
100
124
  error_msg = f'Database not found: "{database_path}"'
101
125
  logger.error(error_msg)
102
126
  return CommandResult(1, '', error_msg)
103
127
 
104
- # commandResult = CommandResult(
105
- # process=None,
106
- # stdout='',
107
- # stderr=error_msg,
108
- # returncode=1,
109
- # timeout=1,
110
- # command=[])
111
-
112
- # return commandResult
113
128
  command = ['dar_manager', '--base', database_path, '--list']
114
129
  process = runner.run(command)
115
- stdout, stderr = process.stdout, process.stderr
130
+ stdout, stderr = process.stdout, process.stderr
131
+
116
132
  if process.returncode != 0:
117
133
  logger.error(f'Error listing catalogs for: "{database_path}"')
118
- logger.error(f"stderr: {stderr}")
134
+ logger.error(f"stderr: {stderr}")
119
135
  logger.error(f"stdout: {stdout}")
120
- else:
121
- print(stdout)
136
+ return process
137
+
138
+ # Extract only archive basenames from stdout
139
+ archive_names = []
140
+ for line in stdout.splitlines():
141
+ line = line.strip()
142
+ if not line or "archive #" in line or "dar path" in line or "compression" in line:
143
+ continue
144
+ parts = line.split("\t")
145
+ if len(parts) >= 3:
146
+ archive_names.append(parts[2].strip())
147
+
148
+ # Sort by prefix and date
149
+ def extract_date(arch_name):
150
+ match = re.search(r"(\d{4}-\d{2}-\d{2})", arch_name)
151
+ if match:
152
+ return datetime.strptime(match.group(1), "%Y-%m-%d")
153
+ return datetime.min
154
+
155
+ def sort_key(name):
156
+ prefix = name.split("_", 1)[0]
157
+ return (prefix, extract_date(name))
158
+
159
+ archive_names = sorted(archive_names, key=sort_key)
160
+
161
+ if not suppress_output:
162
+ for name in archive_names:
163
+ print(name)
164
+
122
165
  return process
123
166
 
124
167
 
@@ -130,47 +173,65 @@ def cat_no_for_name(archive: str, config_settings: ConfigSettings) -> int:
130
173
  - the found number, if the archive catalog is present in the database
131
174
  - "-1" if the archive is not found
132
175
  """
176
+
133
177
  backup_def = backup_def_from_archive(archive)
134
- process = list_catalogs(backup_def, config_settings)
178
+ process = list_catalogs(backup_def, config_settings, suppress_output=True)
135
179
  if process.returncode != 0:
136
180
  logger.error(f"Error listing catalogs for backup def: '{backup_def}'")
137
181
  return -1
138
182
  line_no = 1
139
183
  for line in process.stdout.splitlines():
140
- #print(f"{line_no}: '{line}'")
141
184
  line_no += 1
142
185
  search = re.search(rf".*?(\d+)\s+.*?({archive}).*", line)
143
186
  if search:
144
- #print(f"FOUND: archive: {search.group(2)}, catalog #: '{search.group(1)}'")
145
187
  logger.info(f"Found archive: '{archive}', catalog #: '{search.group(1)}'")
146
188
  return int(search.group(1))
147
189
  return -1
148
190
 
149
191
 
150
-
151
- def list_archive_contents(archive: str, config_settings: ConfigSettings) -> int :
192
+ def list_archive_contents(archive: str, config_settings: ConfigSettings) -> int:
152
193
  """
153
- List the contents of a specific archive, given the archive name
194
+ List the contents of a specific archive, given the archive name.
195
+ Prints only actual file entries (lines beginning with '[ Saved ]').
196
+ If none are found, a notice is printed instead.
154
197
  """
155
198
  backup_def = backup_def_from_archive(archive)
156
199
  database = f"{backup_def}{DB_SUFFIX}"
157
- database_path = os.path.join(config_settings.backup_dir, database)
200
+ database_path = os.path.join(get_db_dir(config_settings), database)
201
+
158
202
  if not os.path.exists(database_path):
159
203
  logger.error(f'Database not found: "{database_path}"')
160
204
  return 1
205
+
161
206
  cat_no = cat_no_for_name(archive, config_settings)
162
207
  if cat_no < 0:
163
208
  logger.error(f"archive: '{archive}' not found in database: '{database_path}'")
164
209
  return 1
210
+
211
+
165
212
  command = ['dar_manager', '--base', database_path, '-u', f"{cat_no}"]
166
- process = runner.run(command)
167
- stdout, stderr = process.stdout, process.stderr
213
+ process = runner.run(command, timeout = 10)
214
+
215
+
216
+ stdout = process.stdout or ""
217
+ stderr = process.stderr or ""
218
+
219
+
168
220
  if process.returncode != 0:
169
221
  logger.error(f'Error listing catalogs for: "{database_path}"')
170
- logger.error(f"stderr: {stderr}")
222
+ logger.error(f"stderr: {stderr}")
171
223
  logger.error(f"stdout: {stdout}")
224
+
225
+
226
+ combined_lines = (stdout + "\n" + stderr).splitlines()
227
+ file_lines = [line for line in combined_lines if line.strip().startswith("[ Saved ]")]
228
+
229
+ if file_lines:
230
+ for line in file_lines:
231
+ print(line)
172
232
  else:
173
- print(stdout)
233
+ print(f"[info] Archive '{archive}' is empty.")
234
+
174
235
  return process.returncode
175
236
 
176
237
 
@@ -179,8 +240,9 @@ def list_catalog_contents(catalog_number: int, backup_def: str, config_settings:
179
240
  """
180
241
  List the contents of catalog # in catalog database for given backup definition
181
242
  """
243
+ logger = get_logger()
182
244
  database = f"{backup_def}{DB_SUFFIX}"
183
- database_path = os.path.join(config_settings.backup_dir, database)
245
+ database_path = os.path.join(get_db_dir(config_settings), database)
184
246
  if not os.path.exists(database_path):
185
247
  logger.error(f'Catalog database not found: "{database_path}"')
186
248
  return 1
@@ -201,7 +263,7 @@ def find_file(file, backup_def, config_settings):
201
263
  Find a specific file
202
264
  """
203
265
  database = f"{backup_def}{DB_SUFFIX}"
204
- database_path = os.path.join(config_settings.backup_dir, database)
266
+ database_path = os.path.join(get_db_dir(config_settings), database)
205
267
  if not os.path.exists(database_path):
206
268
  logger.error(f'Database not found: "{database_path}"')
207
269
  return 1
@@ -217,42 +279,82 @@ def find_file(file, backup_def, config_settings):
217
279
  return process.returncode
218
280
 
219
281
 
220
- def add_specific_archive(archive: str, config_settings: ConfigSettings, directory: str =None) -> int:
221
- # sanity check - does dar backup exist?
282
+ def add_specific_archive(archive: str, config_settings: ConfigSettings, directory: str = None) -> int:
283
+ """
284
+ Adds the specified archive to its catalog database. Prompts for confirmation if it's older than existing entries.
285
+
286
+ Returns:
287
+ 0 on success
288
+ 1 on failure
289
+ """
290
+ # Determine archive path
222
291
  if not directory:
223
292
  directory = config_settings.backup_dir
224
- archive = os.path.basename(archive) # remove path if it was given
225
- archive_path = os.path.join(directory, f'{archive}')
293
+ archive = os.path.basename(archive) # strip path if present
294
+ archive_path = os.path.join(directory, archive)
295
+ archive_test_path = os.path.join(directory, f'{archive}.1.dar')
226
296
 
227
- archive_test_path = os.path.join(directory, f'{archive}.1.dar')
228
297
  if not os.path.exists(archive_test_path):
229
298
  logger.error(f'dar backup: "{archive_test_path}" not found, exiting')
230
299
  return 1
231
-
232
- # sanity check - does backup definition exist?
300
+
301
+ # Validate backup definition
233
302
  backup_definition = archive.split('_')[0]
234
303
  backup_def_path = os.path.join(config_settings.backup_d_dir, backup_definition)
235
304
  if not os.path.exists(backup_def_path):
236
305
  logger.error(f'backup definition "{backup_definition}" not found (--add-specific-archive option probably not correct), exiting')
237
306
  return 1
238
-
307
+
308
+ # Determine catalog DB path
239
309
  database = f"{backup_definition}{DB_SUFFIX}"
240
- database_path = os.path.realpath(os.path.join(config_settings.backup_dir, database))
310
+ database_path = os.path.realpath(os.path.join(get_db_dir(config_settings), database))
311
+
312
+ # Safety check: is archive older than latest in catalog?
313
+ try:
314
+ result = subprocess.run(
315
+ ["dar_manager", "--base", database_path, "--list"],
316
+ stdout=subprocess.PIPE,
317
+ stderr=subprocess.DEVNULL,
318
+ text=True,
319
+ check=True
320
+ )
321
+ all_lines = result.stdout.splitlines()
322
+ date_pattern = re.compile(r"\d{4}-\d{2}-\d{2}")
323
+
324
+ catalog_dates = [
325
+ datetime.strptime(date_match.group(), "%Y-%m-%d")
326
+ for line in all_lines
327
+ if (date_match := date_pattern.search(line))
328
+ ]
329
+
330
+ if catalog_dates:
331
+ latest_date = max(catalog_dates)
332
+ archive_date_match = date_pattern.search(archive)
333
+ if archive_date_match:
334
+ archive_date = datetime.strptime(archive_date_match.group(), "%Y-%m-%d")
335
+ if archive_date < latest_date:
336
+ if not confirm_add_old_archive(archive, latest_date.strftime("%Y-%m-%d")):
337
+ logger.info(f"Archive {archive} skipped due to user declining to add older archive.")
338
+ return 1
339
+
340
+ except subprocess.CalledProcessError:
341
+ logger.warning("Could not determine latest catalog date for chronological check.")
342
+
241
343
  logger.info(f'Add "{archive_path}" to catalog: "{database}"')
242
-
243
- command = ['dar_manager', '--base', database_path, "--add", archive_path, "-Q"]
344
+
345
+ command = ['dar_manager', '--base', database_path, "--add", archive_path, "-Q", "--alter=ignore-order"]
244
346
  process = runner.run(command)
245
347
  stdout, stderr = process.stdout, process.stderr
246
348
 
247
349
  if process.returncode == 0:
248
- logger.info(f'"{archive_path}" added to it\'s catalog')
350
+ logger.info(f'"{archive_path}" added to its catalog')
249
351
  elif process.returncode == 5:
250
- logger.warning(f'Something did not go completely right adding "{archive_path}" to it\'s catalog, dar_manager error: "{process.returncode}"')
251
- else:
252
- logger.error(f'something went wrong adding "{archive_path}" to it\'s catalog, dar_manager error: "{process.returncode}"')
352
+ logger.warning(f'Something did not go completely right adding "{archive_path}" to its catalog, dar_manager error: "{process.returncode}"')
353
+ else:
354
+ logger.error(f'something went wrong adding "{archive_path}" to its catalog, dar_manager error: "{process.returncode}"')
253
355
  logger.error(f"stderr: {stderr}")
254
356
  logger.error(f"stdout: {stdout}")
255
-
357
+
256
358
  return process.returncode
257
359
 
258
360
 
@@ -330,6 +432,31 @@ def backup_def_from_archive(archive: str) -> str:
330
432
  return None
331
433
 
332
434
 
435
+ def confirm_add_old_archive(archive_name: str, latest_known_date: str, timeout_secs: int = 20) -> bool:
436
+ """
437
+ Confirm with the user if they want to proceed with adding an archive older than the most recent in the catalog.
438
+ Returns True if the user confirms with "yes", False otherwise.
439
+ """
440
+ try:
441
+ prompt = (
442
+ f"⚠️ Archive '{archive_name}' is older than the latest in the catalog ({latest_known_date}).\n"
443
+ f"Adding older archives may lead to inconsistent restore chains.\n"
444
+ f"Are you sure you want to continue? (yes/no): "
445
+ )
446
+ confirmation = inputimeout(prompt=prompt, timeout=timeout_secs)
447
+
448
+ if confirmation is None:
449
+ logger.info(f"No confirmation received for old archive: {archive_name}. Skipping.")
450
+ return False
451
+ return confirmation.strip().lower() == "yes"
452
+
453
+ except TimeoutOccurred:
454
+ logger.info(f"Timeout waiting for confirmation for old archive: {archive_name}. Skipping.")
455
+ return False
456
+ except KeyboardInterrupt:
457
+ logger.info(f"User interrupted confirmation for old archive: {archive_name}. Skipping.")
458
+ return False
459
+
333
460
 
334
461
  def remove_specific_archive(archive: str, config_settings: ConfigSettings) -> int:
335
462
  """
@@ -341,7 +468,7 @@ def remove_specific_archive(archive: str, config_settings: ConfigSettings) -> in
341
468
 
342
469
  """
343
470
  backup_def = backup_def_from_archive(archive)
344
- database_path = os.path.join(config_settings.backup_dir, f"{backup_def}{DB_SUFFIX}")
471
+ database_path = os.path.join(get_db_dir(config_settings), f"{backup_def}{DB_SUFFIX}")
345
472
  cat_no:int = cat_no_for_name(archive, config_settings)
346
473
  if cat_no >= 0:
347
474
  command = ['dar_manager', '--base', database_path, "--delete", str(cat_no)]
@@ -366,12 +493,11 @@ def build_arg_parser():
366
493
  parser.add_argument('--create-db', action='store_true', help='Create missing databases for all backup definitions')
367
494
  parser.add_argument('--alternate-archive-dir', type=str, help='Use this directory instead of BACKUP_DIR in config file')
368
495
  parser.add_argument('--add-dir', type=str, help='Add all archive catalogs in this directory to databases')
369
- parser.add_argument('-d', '--backup-def', type=str, help='Restrict to work only on this backup definition')
370
- parser.add_argument('--add-specific-archive', type=str, help='Add this archive to catalog database')
371
- parser.add_argument('--remove-specific-archive', type=str, help='Remove this archive from catalog database')
496
+ parser.add_argument('-d', '--backup-def', type=str, help='Restrict to work only on this backup definition').completer = backup_definition_completer
497
+ parser.add_argument('--add-specific-archive', type=str, help='Add this archive to catalog database').completer = add_specific_archive_completer
498
+ parser.add_argument('--remove-specific-archive', type=str, help='Remove this archive from catalog database').completer = archive_content_completer
372
499
  parser.add_argument('-l', '--list-catalogs', action='store_true', help='List catalogs in databases for all backup definitions')
373
- parser.add_argument('--list-catalog-contents', type=int, help="List contents of a catalog. Argument is the 'archive #', '-d <definition>' argument is also required")
374
- parser.add_argument('--list-archive-contents', type=str, help="List contents of the archive's catalog.")
500
+ parser.add_argument('--list-archive-contents', type=str, help="List contents of the archive's catalog. Argument is the archive name.").completer = archive_content_completer
375
501
  parser.add_argument('--find-file', type=str, help="List catalogs containing <path>/file. '-d <definition>' argument is also required")
376
502
  parser.add_argument('--verbose', action='store_true', help='Be more verbose')
377
503
  parser.add_argument('--log-level', type=str, help="`debug` or `trace`, default is `info`", default="info")
@@ -382,8 +508,6 @@ def build_arg_parser():
382
508
  return parser
383
509
 
384
510
 
385
-
386
-
387
511
  def main():
388
512
  global logger, runner
389
513
 
@@ -394,9 +518,10 @@ def main():
394
518
  return
395
519
 
396
520
  parser = argparse.ArgumentParser(description="Creates/maintains `dar` database catalogs")
397
- # [parser.add_argument(...) as before...]
398
-
399
521
  parser = build_arg_parser()
522
+
523
+ argcomplete.autocomplete(parser)
524
+
400
525
  args = parser.parse_args()
401
526
 
402
527
  if args.more_help:
@@ -405,16 +530,13 @@ def main():
405
530
  return
406
531
 
407
532
  if args.version:
408
- print(f"{SCRIPTNAME} {about.__version__}")
409
- print(f"Source code is here: https://github.com/per2jensen/dar-backup")
410
- print('''Licensed under GNU GENERAL PUBLIC LICENSE v3, see the supplied file "LICENSE" for details.
411
- THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW, not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
412
- See section 15 and section 16 in the supplied "LICENSE" file.''')
533
+ show_version()
413
534
  sys.exit(0)
414
- return
415
535
 
416
536
  args.config_file = os.path.expanduser(os.path.expandvars(args.config_file))
417
537
  config_settings = ConfigSettings(args.config_file)
538
+ print(f"Config settings: {config_settings}")
539
+
418
540
  if not os.path.dirname(config_settings.logfile_location):
419
541
  print(f"Directory for log file '{config_settings.logfile_location}' does not exist, exiting")
420
542
  sys.exit(1)
@@ -425,12 +547,23 @@ See section 15 and section 16 in the supplied "LICENSE" file.''')
425
547
  command_logger = get_logger(command_output_logger=True)
426
548
  runner = CommandRunner(logger=logger, command_logger=command_logger)
427
549
 
550
+ start_msgs: List[Tuple[str, str]] = []
551
+
428
552
  start_time = int(time())
429
- logger.info(f"=====================================")
430
- logger.info(f"{SCRIPTNAME} started, version: {about.__version__}")
553
+ start_msgs.append((f"{SCRIPTNAME}:", about.__version__))
431
554
  logger.info(f"START TIME: {start_time}")
432
555
  logger.debug(f"`args`:\n{args}")
433
556
  logger.debug(f"`config_settings`:\n{config_settings}")
557
+ start_msgs.append(("Config file:", args.config_file))
558
+ args.verbose and start_msgs.append(("Backup dir:", config_settings.backup_dir))
559
+ start_msgs.append(("Logfile:", config_settings.logfile_location))
560
+ args.verbose and start_msgs.append(("--alternate-archive-dir:", args.alternate_archive_dir))
561
+ args.verbose and start_msgs.append(("--cleanup-specific-archives:", args.cleanup_specific_archives))
562
+ dar_manager_properties = get_binary_info(command='dar_manager')
563
+ start_msgs.append(("dar_manager:", dar_manager_properties['path']))
564
+ start_msgs.append(("dar_manager v.:", dar_manager_properties['version']))
565
+
566
+ print_aligned_settings(start_msgs)
434
567
 
435
568
  # --- Sanity checks ---
436
569
  if args.add_dir and not args.add_dir.strip():
@@ -475,11 +608,6 @@ See section 15 and section 16 in the supplied "LICENSE" file.''')
475
608
  sys.exit(1)
476
609
  return
477
610
 
478
- if args.list_catalog_contents and not args.backup_def:
479
- logger.error(f"--list-catalog-contents requires the --backup-def, exiting")
480
- sys.exit(1)
481
- return
482
-
483
611
  if args.find_file and not args.backup_def:
484
612
  logger.error(f"--find-file requires the --backup-def, exiting")
485
613
  sys.exit(1)
@@ -496,14 +624,14 @@ See section 15 and section 16 in the supplied "LICENSE" file.''')
496
624
  # --- Functional logic ---
497
625
  if args.create_db:
498
626
  if args.backup_def:
499
- sys.exit(create_db(args.backup_def, config_settings))
627
+ sys.exit(create_db(args.backup_def, config_settings, logger, runner))
500
628
  return
501
629
  else:
502
630
  for root, dirs, files in os.walk(config_settings.backup_d_dir):
503
631
  for file in files:
504
632
  current_backupdef = os.path.basename(file)
505
633
  logger.debug(f"Create catalog db for backup definition: '{current_backupdef}'")
506
- result = create_db(current_backupdef, config_settings)
634
+ result = create_db(current_backupdef, config_settings, logger, runner)
507
635
  if result != 0:
508
636
  sys.exit(result)
509
637
  return
@@ -538,10 +666,6 @@ See section 15 and section 16 in the supplied "LICENSE" file.''')
538
666
  sys.exit(result)
539
667
  return
540
668
 
541
- if args.list_catalog_contents:
542
- result = list_catalog_contents(args.list_catalog_contents, args.backup_def, config_settings)
543
- sys.exit(result)
544
- return
545
669
 
546
670
  if args.find_file:
547
671
  result = find_file(args.find_file, args.backup_def, config_settings)