mirror of
https://git.selfprivacy.org/SelfPrivacy/selfprivacy-rest-api.git
synced 2024-09-29 11:37:52 +00:00
fix(backups): robustness against stale locks: is_initted
This commit is contained in:
parent
eca4b26a31
commit
26ab7b4d7b
|
@ -256,6 +256,7 @@ class ResticBackupper(AbstractBackupper):
|
||||||
if "created restic repository" not in output:
|
if "created restic repository" not in output:
|
||||||
raise ValueError("cannot init a repo: " + output)
|
raise ValueError("cannot init a repo: " + output)
|
||||||
|
|
||||||
|
@unlocked_repo
|
||||||
def is_initted(self) -> bool:
|
def is_initted(self) -> bool:
|
||||||
command = self.restic_command(
|
command = self.restic_command(
|
||||||
"check",
|
"check",
|
||||||
|
@ -267,9 +268,10 @@ class ResticBackupper(AbstractBackupper):
|
||||||
shell=False,
|
shell=False,
|
||||||
stderr=subprocess.STDOUT,
|
stderr=subprocess.STDOUT,
|
||||||
) as handle:
|
) as handle:
|
||||||
# communication forces to complete and for returncode to get defined
|
|
||||||
output = handle.communicate()[0].decode("utf-8")
|
output = handle.communicate()[0].decode("utf-8")
|
||||||
if handle.returncode != 0:
|
if handle.returncode != 0:
|
||||||
|
if "unable to create lock" in output:
|
||||||
|
raise ValueError("Stale lock detected: ", output)
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -319,6 +321,7 @@ class ResticBackupper(AbstractBackupper):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise ValueError("could not lock repository") from e
|
raise ValueError("could not lock repository") from e
|
||||||
|
|
||||||
|
@unlocked_repo
|
||||||
def restored_size(self, snapshot_id: str) -> int:
|
def restored_size(self, snapshot_id: str) -> int:
|
||||||
"""
|
"""
|
||||||
Size of a snapshot
|
Size of a snapshot
|
||||||
|
|
|
@ -776,6 +776,21 @@ def test_double_lock_unlock(backups, dummy_service):
|
||||||
|
|
||||||
|
|
||||||
def test_operations_while_locked(backups, dummy_service):
|
def test_operations_while_locked(backups, dummy_service):
|
||||||
|
# Stale lock prevention test
|
||||||
|
|
||||||
|
# consider making it fully at the level of backupper?
|
||||||
|
# because this is where prevention lives?
|
||||||
|
# Backups singleton is here only so that we can run this against B2, S3 and whatever
|
||||||
|
# But maybe it is not necessary (if restic treats them uniformly enough)
|
||||||
|
|
||||||
Backups.provider().backupper.lock()
|
Backups.provider().backupper.lock()
|
||||||
snap = Backups.back_up(dummy_service)
|
snap = Backups.back_up(dummy_service)
|
||||||
assert snap is not None
|
assert snap is not None
|
||||||
|
|
||||||
|
Backups.provider().backupper.lock()
|
||||||
|
# using lowlevel to make sure no caching interferes
|
||||||
|
assert Backups.provider().backupper.is_initted() is True
|
||||||
|
|
||||||
|
# check that no locks were left
|
||||||
|
Backups.provider().backupper.lock()
|
||||||
|
Backups.provider().backupper.unlock()
|
||||||
|
|
Loading…
Reference in a new issue