浏览代码

Provide helpful message when borgmatic is run with only legacy config present.

Dan Helfman 8 年之前
父节点
当前提交
ef32b292a8
共有 4 个文件被更改,包括 65 次插入6 次删除
  1. 1 1
      README.md
  2. 4 5
      borgmatic/commands/borgmatic.py
  3. 29 0
      borgmatic/config/convert.py
  4. 31 0
      borgmatic/tests/unit/config/test_convert.py

+ 1 - 1
README.md

@@ -97,7 +97,7 @@ upgrade to the new version of borgmatic:
 
 Then, run:
 
-    sudo upgrade-borgmatic-configuration
+    sudo upgrade-borgmatic-config
 
 That will generate a new YAML configuration file at /etc/borgmatic/config.yaml
 (by default) using the values from both your existing configuration and

+ 4 - 5
borgmatic/commands/borgmatic.py

@@ -5,9 +5,10 @@ from subprocess import CalledProcessError
 import sys
 
 from borgmatic import borg
-from borgmatic.config.validate import parse_configuration, schema_filename
+from borgmatic.config import convert, validate
 
 
+LEGACY_CONFIG_FILENAME = '/etc/borgmatic/config'
 DEFAULT_CONFIG_FILENAME = '/etc/borgmatic/config.yaml'
 DEFAULT_EXCLUDES_FILENAME = '/etc/borgmatic/excludes'
 
@@ -41,11 +42,9 @@ def parse_arguments(*arguments):
 
 def main():  # pragma: no cover
     try:
-        # TODO: Detect whether only legacy config is present. If so, inform the user about how to
-        # upgrade, then exit.
-
         args = parse_arguments(*sys.argv[1:])
-        config = parse_configuration(args.config_filename, schema_filename())
+        convert.guard_configuration_upgraded(LEGACY_CONFIG_FILENAME, args.config_filename)
+        config = validate.parse_configuration(args.config_filename, validate.schema_filename())
         repository = config.location['repository']
         remote_path = config.location.get('remote_path')
 

+ 29 - 0
borgmatic/config/convert.py

@@ -1,3 +1,5 @@
+import os
+
 from ruamel import yaml
 
 from borgmatic.config import generate
@@ -48,3 +50,30 @@ def convert_legacy_parsed_config(source_config, source_excludes, schema):
         )
 
     return destination_config
+
+
+class LegacyConfigurationNotUpgraded(FileNotFoundError):
+    def __init__(self):
+        super(LegacyConfigurationNotUpgraded, self).__init__(
+            '''borgmatic changed its configuration file format in version 1.1.0 from INI-style
+to YAML. This better supports validation, and has a more natural way to express
+lists of values. To upgrade your existing configuration, run:
+
+    sudo upgrade-borgmatic-config
+
+That will generate a new YAML configuration file at /etc/borgmatic/config.yaml
+(by default) using the values from both your existing configuration and excludes
+files. The new version of borgmatic will consume the YAML configuration file
+instead of the old one.'''
+        )
+
+
+def guard_configuration_upgraded(source_config_filename, destination_config_filename):
+    '''
+    If legacy souce configuration exists but destination upgraded config doesn't, raise
+    LegacyConfigurationNotUpgraded.
+
+    The idea is that we want to alert the user about upgrading their config if they haven't already.
+    '''
+    if os.path.exists(source_config_filename) and not os.path.exists(destination_config_filename):
+        raise LegacyConfigurationNotUpgraded()

+ 31 - 0
borgmatic/tests/unit/config/test_convert.py

@@ -1,6 +1,8 @@
 from collections import defaultdict, OrderedDict, namedtuple
+import os
 
 from flexmock import flexmock
+import pytest
 
 from borgmatic.config import convert as module
 
@@ -61,3 +63,32 @@ def test_convert_legacy_parsed_config_splits_space_separated_values():
         ('retention', OrderedDict()),
         ('consistency', OrderedDict([('checks', ['repository', 'archives'])])),
     ])
+
+
+def test_guard_configuration_upgraded_raises_when_only_source_config_present():
+    flexmock(os.path).should_receive('exists').with_args('config').and_return(True)
+    flexmock(os.path).should_receive('exists').with_args('config.yaml').and_return(False)
+
+    with pytest.raises(module.LegacyConfigurationNotUpgraded):
+        module.guard_configuration_upgraded('config', 'config.yaml')
+
+
+def test_guard_configuration_upgraded_does_not_raise_when_only_destination_config_present():
+    flexmock(os.path).should_receive('exists').with_args('config').and_return(False)
+    flexmock(os.path).should_receive('exists').with_args('config.yaml').and_return(True)
+
+    module.guard_configuration_upgraded('config', 'config.yaml')
+
+
+def test_guard_configuration_upgraded_does_not_raise_when_both_configs_present():
+    flexmock(os.path).should_receive('exists').with_args('config').and_return(True)
+    flexmock(os.path).should_receive('exists').with_args('config.yaml').and_return(True)
+
+    module.guard_configuration_upgraded('config', 'config.yaml')
+
+
+def test_guard_configuration_upgraded_does_not_raise_when_neither_config_present():
+    flexmock(os.path).should_receive('exists').with_args('config').and_return(False)
+    flexmock(os.path).should_receive('exists').with_args('config.yaml').and_return(False)
+
+    module.guard_configuration_upgraded('config', 'config.yaml')