浏览代码

Fix traceback when a configuration section is present but lacking any options (#604).

Dan Helfman 2 年之前
父节点
当前提交
89500df429
共有 4 个文件被更改,包括 27 次插入11 次删除
  1. 3 0
      NEWS
  2. 14 10
      borgmatic/config/normalize.py
  3. 1 1
      setup.py
  4. 9 0
      tests/unit/config/test_normalize.py

+ 3 - 0
NEWS

@@ -1,3 +1,6 @@
+1.7.5.dev0
+ * #604: Fix traceback when a configuration section is present but lacking any options.
+
 1.7.4
 1.7.4
  * #596: Fix special file detection erroring when broken symlinks are encountered.
  * #596: Fix special file detection erroring when broken symlinks are encountered.
  * #597, #598: Fix regression in which "check" action errored on certain systems ("Cannot determine
  * #597, #598: Fix regression in which "check" action errored on certain systems ("Cannot determine

+ 14 - 10
borgmatic/config/normalize.py

@@ -8,49 +8,53 @@ def normalize(config_filename, config):
     message warnings produced based on the normalization performed.
     message warnings produced based on the normalization performed.
     '''
     '''
     logs = []
     logs = []
+    location = config.get('location') or {}
+    storage = config.get('storage') or {}
+    consistency = config.get('consistency') or {}
+    hooks = config.get('hooks') or {}
 
 
     # Upgrade exclude_if_present from a string to a list.
     # Upgrade exclude_if_present from a string to a list.
-    exclude_if_present = config.get('location', {}).get('exclude_if_present')
+    exclude_if_present = location.get('exclude_if_present')
     if isinstance(exclude_if_present, str):
     if isinstance(exclude_if_present, str):
         config['location']['exclude_if_present'] = [exclude_if_present]
         config['location']['exclude_if_present'] = [exclude_if_present]
 
 
     # Upgrade various monitoring hooks from a string to a dict.
     # Upgrade various monitoring hooks from a string to a dict.
-    healthchecks = config.get('hooks', {}).get('healthchecks')
+    healthchecks = hooks.get('healthchecks')
     if isinstance(healthchecks, str):
     if isinstance(healthchecks, str):
         config['hooks']['healthchecks'] = {'ping_url': healthchecks}
         config['hooks']['healthchecks'] = {'ping_url': healthchecks}
 
 
-    cronitor = config.get('hooks', {}).get('cronitor')
+    cronitor = hooks.get('cronitor')
     if isinstance(cronitor, str):
     if isinstance(cronitor, str):
         config['hooks']['cronitor'] = {'ping_url': cronitor}
         config['hooks']['cronitor'] = {'ping_url': cronitor}
 
 
-    pagerduty = config.get('hooks', {}).get('pagerduty')
+    pagerduty = hooks.get('pagerduty')
     if isinstance(pagerduty, str):
     if isinstance(pagerduty, str):
         config['hooks']['pagerduty'] = {'integration_key': pagerduty}
         config['hooks']['pagerduty'] = {'integration_key': pagerduty}
 
 
-    cronhub = config.get('hooks', {}).get('cronhub')
+    cronhub = hooks.get('cronhub')
     if isinstance(cronhub, str):
     if isinstance(cronhub, str):
         config['hooks']['cronhub'] = {'ping_url': cronhub}
         config['hooks']['cronhub'] = {'ping_url': cronhub}
 
 
     # Upgrade consistency checks from a list of strings to a list of dicts.
     # Upgrade consistency checks from a list of strings to a list of dicts.
-    checks = config.get('consistency', {}).get('checks')
+    checks = consistency.get('checks')
     if isinstance(checks, list) and len(checks) and isinstance(checks[0], str):
     if isinstance(checks, list) and len(checks) and isinstance(checks[0], str):
         config['consistency']['checks'] = [{'name': check_type} for check_type in checks]
         config['consistency']['checks'] = [{'name': check_type} for check_type in checks]
 
 
     # Rename various configuration options.
     # Rename various configuration options.
-    numeric_owner = config.get('location', {}).pop('numeric_owner', None)
+    numeric_owner = location.pop('numeric_owner', None)
     if numeric_owner is not None:
     if numeric_owner is not None:
         config['location']['numeric_ids'] = numeric_owner
         config['location']['numeric_ids'] = numeric_owner
 
 
-    bsd_flags = config.get('location', {}).pop('bsd_flags', None)
+    bsd_flags = location.pop('bsd_flags', None)
     if bsd_flags is not None:
     if bsd_flags is not None:
         config['location']['flags'] = bsd_flags
         config['location']['flags'] = bsd_flags
 
 
-    remote_rate_limit = config.get('storage', {}).pop('remote_rate_limit', None)
+    remote_rate_limit = storage.pop('remote_rate_limit', None)
     if remote_rate_limit is not None:
     if remote_rate_limit is not None:
         config['storage']['upload_rate_limit'] = remote_rate_limit
         config['storage']['upload_rate_limit'] = remote_rate_limit
 
 
     # Upgrade remote repositories to ssh:// syntax, required in Borg 2.
     # Upgrade remote repositories to ssh:// syntax, required in Borg 2.
-    repositories = config.get('location', {}).get('repositories')
+    repositories = location.get('repositories')
     if repositories:
     if repositories:
         config['location']['repositories'] = []
         config['location']['repositories'] = []
         for repository in repositories:
         for repository in repositories:

+ 1 - 1
setup.py

@@ -1,6 +1,6 @@
 from setuptools import find_packages, setup
 from setuptools import find_packages, setup
 
 
-VERSION = '1.7.4'
+VERSION = '1.7.5.dev0'
 
 
 
 
 setup(
 setup(

+ 9 - 0
tests/unit/config/test_normalize.py

@@ -21,11 +21,13 @@ from borgmatic.config import normalize as module
             {'location': {'source_directories': ['foo', 'bar']}},
             {'location': {'source_directories': ['foo', 'bar']}},
             False,
             False,
         ),
         ),
+        ({'location': None}, {'location': None}, False,),
         (
         (
             {'storage': {'compression': 'yes_please'}},
             {'storage': {'compression': 'yes_please'}},
             {'storage': {'compression': 'yes_please'}},
             {'storage': {'compression': 'yes_please'}},
             False,
             False,
         ),
         ),
+        ({'storage': None}, {'storage': None}, False,),
         (
         (
             {'hooks': {'healthchecks': 'https://example.com'}},
             {'hooks': {'healthchecks': 'https://example.com'}},
             {'hooks': {'healthchecks': {'ping_url': 'https://example.com'}}},
             {'hooks': {'healthchecks': {'ping_url': 'https://example.com'}}},
@@ -46,11 +48,18 @@ from borgmatic.config import normalize as module
             {'hooks': {'cronhub': {'ping_url': 'https://example.com'}}},
             {'hooks': {'cronhub': {'ping_url': 'https://example.com'}}},
             False,
             False,
         ),
         ),
+        ({'hooks': None}, {'hooks': None}, False,),
         (
         (
             {'consistency': {'checks': ['archives']}},
             {'consistency': {'checks': ['archives']}},
             {'consistency': {'checks': [{'name': 'archives'}]}},
             {'consistency': {'checks': [{'name': 'archives'}]}},
             False,
             False,
         ),
         ),
+        (
+            {'consistency': {'checks': ['archives']}},
+            {'consistency': {'checks': [{'name': 'archives'}]}},
+            False,
+        ),
+        ({'consistency': None}, {'consistency': None}, False,),
         ({'location': {'numeric_owner': False}}, {'location': {'numeric_ids': False}}, False,),
         ({'location': {'numeric_owner': False}}, {'location': {'numeric_ids': False}}, False,),
         ({'location': {'bsd_flags': False}}, {'location': {'flags': False}}, False,),
         ({'location': {'bsd_flags': False}}, {'location': {'flags': False}}, False,),
         (
         (