Merge pull request #8441 from ThomasWaldmann/fix-close-store-on-exception

make sure the store gets closed in case of exceptions, fixes #8413
This commit is contained in:
TW 2024-10-02 11:07:34 +02:00 committed by GitHub
commit 29d16f5c41
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -130,6 +130,7 @@ def __init__(
self.store = Store(url, levels=levels_config)
except StoreBackendError as e:
raise Error(str(e))
self.store_opened = False
self.version = None
# long-running repository methods which emit log or progress output are responsible for calling
# the ._send_log method periodically to get log and progress output transferred to the borg client
@ -156,7 +157,11 @@ def __enter__(self):
self.do_create = False
self.create()
self.created = True
self.open(exclusive=bool(self.exclusive), lock_wait=self.lock_wait, lock=self.do_lock)
try:
self.open(exclusive=bool(self.exclusive), lock_wait=self.lock_wait, lock=self.do_lock)
except Exception:
self.close()
raise
return self
def __exit__(self, exc_type, exc_val, exc_tb):
@ -170,11 +175,13 @@ def create(self):
"""Create a new empty repository"""
self.store.create()
self.store.open()
self.store.store("config/readme", REPOSITORY_README.encode())
self.version = 3
self.store.store("config/version", str(self.version).encode())
self.store.store("config/id", bin_to_hex(os.urandom(32)).encode())
self.store.close()
try:
self.store.store("config/readme", REPOSITORY_README.encode())
self.version = 3
self.store.store("config/version", str(self.version).encode())
self.store.store("config/id", bin_to_hex(os.urandom(32)).encode())
finally:
self.store.close()
def _set_id(self, id):
# for testing: change the id of an existing repository
@ -207,6 +214,8 @@ def open(self, *, exclusive, lock_wait=None, lock=True):
self.store.open()
except StoreBackendDoesNotExist:
raise self.DoesNotExist(str(self._location)) from None
else:
self.store_opened = True
if lock:
self.lock = Lock(self.store, exclusive, timeout=lock_wait).acquire()
else:
@ -224,12 +233,13 @@ def open(self, *, exclusive, lock_wait=None, lock=True):
self.opened = True
def close(self):
if self.opened:
if self.lock:
self.lock.release()
self.lock = None
if self.lock:
self.lock.release()
self.lock = None
if self.store_opened:
self.store.close()
self.opened = False
self.store_opened = False
self.opened = False
def info(self):
"""return some infos about the repo (must be opened first)"""