Repository: borgbackup/borg

Issue:
cache config checker fails
if you remove `$BORG_CACHE_DIR/config`, it seems to be expected that borg will fail with: `%s Does not look like a Borg cache`. Instead, it does this ugly backtrace:

```
(borg-env)root@marcos:/media/anarcat/BOOK/borg# borg create ./::test /etc/motd
borg: Error: Local Exception.
Traceback (most recent call last):
  File "/usr/lib/python3.4/configparser.py", line 1116, in _unify_values
    sectiondict = self._sections[section]
KeyError: 'cache'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/anarcat/src/borg/borg/archiver.py", line 1006, in main
    exit_code = archiver.run(sys.argv[1:])
  File "/home/anarcat/src/borg/borg/archiver.py", line 962, in run
    return args.func(args)
  File "/home/anarcat/src/borg/borg/archiver.py", line 116, in do_create
    cache = Cache(repository, key, manifest, do_files=args.cache_files)
  File "/home/anarcat/src/borg/borg/cache.py", line 53, in __init__
    self.open()
  File "/home/anarcat/src/borg/borg/cache.py", line 128, in open
    self.rollback()
  File "/home/anarcat/src/borg/borg/cache.py", line 202, in rollback
    self._do_open()
  File "/home/anarcat/src/borg/borg/cache.py", line 114, in _do_open
    if self.config.getint('cache', 'version') != 1:
  File "/usr/lib/python3.4/configparser.py", line 781, in getint
    return self._get(section, int, option, raw=raw, vars=vars)
  File "/usr/lib/python3.4/configparser.py", line 776, in _get
    return conv(self.get(section, option, **kwargs))
  File "/usr/lib/python3.4/configparser.py", line 754, in get
    d = self._unify_values(section, vars)
  File "/usr/lib/python3.4/configparser.py", line 1119, in _unify_values
    raise NoSectionError(section)
configparser.NoSectionError: No section: 'cache'

borg: Exiting with failure status due to previous errors
```

i found this problem while working on the attic converter (#231) but it could potentially cause problems for older borg repos or repos that had some damage... 



Discussion:

Resolving patch:
diff --git a/borg/cache.py b/borg/cache.py
--- a/borg/cache.py
+++ b/borg/cache.py
@@ -1,4 +1,4 @@
-from configparser import RawConfigParser
+import configparser
 from .remote import cache_if_remote
 import errno
 import msgpack
@@ -89,7 +89,7 @@ def create(self):
         os.makedirs(self.path)
         with open(os.path.join(self.path, 'README'), 'w') as fd:
             fd.write('This is a Borg cache')
-        config = RawConfigParser()
+        config = configparser.RawConfigParser()
         config.add_section('cache')
         config.set('cache', 'version', '1')
         config.set('cache', 'repository', hexlify(self.repository.id).decode('ascii'))
@@ -109,10 +109,17 @@ def destroy(self):
         shutil.rmtree(self.path)
 
     def _do_open(self):
-        self.config = RawConfigParser()
-        self.config.read(os.path.join(self.path, 'config'))
-        if self.config.getint('cache', 'version') != 1:
-            raise Exception('%s Does not look like a Borg cache')
+        self.config = configparser.RawConfigParser()
+        config_path = os.path.join(self.path, 'config')
+        self.config.read(config_path)
+        try:
+            cache_version = self.config.getint('cache', 'version')
+            wanted_version = 1
+            if  cache_version != wanted_version:
+                raise Exception('%s has unexpected cache version %d (wanted: %d).' % (
+                    config_path, cache_version, wanted_version))
+        except configparser.NoSectionError as e:
+            raise Exception('%s does not look like a Borg cache.' % config_path)
         self.id = self.config.get('cache', 'repository')
         self.manifest_id = unhexlify(self.config.get('cache', 'manifest'))
         self.timestamp = self.config.get('cache', 'timestamp', fallback=None)


Test patch: