mirror of
https://git.selfprivacy.org/SelfPrivacy/selfprivacy-rest-api.git
synced 2024-11-28 06:51:28 +00:00
feature(backups): batched removals of snapshots
This commit is contained in:
parent
564fedf806
commit
409d4fc2bb
|
@ -397,9 +397,8 @@ class Backups:
|
|||
|
||||
# TODO: Can be optimized since there is forgetting of an array in one restic op
|
||||
# but most of the time this will be only one snap to forget.
|
||||
for snap in auto_snaps:
|
||||
if snap not in new_snaplist:
|
||||
Backups.forget_snapshot(snap)
|
||||
deletable_snaps = [snap for snap in auto_snaps if snap not in new_snaplist]
|
||||
Backups.forget_snapshots(deletable_snaps)
|
||||
|
||||
@staticmethod
|
||||
def _standardize_quotas(i: int) -> int:
|
||||
|
@ -606,6 +605,19 @@ class Backups:
|
|||
|
||||
return snap
|
||||
|
||||
@staticmethod
|
||||
def forget_snapshots(snapshots: List[Snapshot]) -> None:
|
||||
"""
|
||||
Deletes a batch of snapshots from the repo and from cache
|
||||
Optimized
|
||||
"""
|
||||
ids = [snapshot.id for snapshot in snapshots]
|
||||
Backups.provider().backupper.forget_snapshots(ids)
|
||||
|
||||
# less critical
|
||||
for snapshot in snapshots:
|
||||
Storage.delete_cached_snapshot(snapshot)
|
||||
|
||||
@staticmethod
|
||||
def forget_snapshot(snapshot: Snapshot) -> None:
|
||||
"""Deletes a snapshot from the repo and from cache"""
|
||||
|
|
|
@ -66,3 +66,8 @@ class AbstractBackupper(ABC):
|
|||
def forget_snapshot(self, snapshot_id) -> None:
|
||||
"""Forget a snapshot"""
|
||||
raise NotImplementedError
|
||||
|
||||
@abstractmethod
|
||||
def forget_snapshots(self, snapshot_ids: List[str]) -> None:
|
||||
"""Maybe optimized deletion of a batch of snapshots, just cycling if unsupported"""
|
||||
raise NotImplementedError
|
||||
|
|
|
@ -39,4 +39,7 @@ class NoneBackupper(AbstractBackupper):
|
|||
raise NotImplementedError
|
||||
|
||||
def forget_snapshot(self, snapshot_id):
|
||||
raise NotImplementedError
|
||||
raise NotImplementedError("forget_snapshot")
|
||||
|
||||
def forget_snapshots(self, snapshots):
|
||||
raise NotImplementedError("forget_snapshots")
|
||||
|
|
|
@ -86,6 +86,10 @@ class ResticBackupper(AbstractBackupper):
|
|||
return f"echo {LocalBackupSecret.get()}"
|
||||
|
||||
def restic_command(self, *args, tags: Optional[List[str]] = None) -> List[str]:
|
||||
"""
|
||||
Construct a restic command against the currently configured repo
|
||||
Can support [nested] arrays as arguments, will flatten them into the final commmand
|
||||
"""
|
||||
if tags is None:
|
||||
tags = []
|
||||
|
||||
|
@ -384,15 +388,15 @@ class ResticBackupper(AbstractBackupper):
|
|||
output,
|
||||
)
|
||||
|
||||
def forget_snapshot(self, snapshot_id: str) -> None:
|
||||
self.forget_snapshots([snapshot_id])
|
||||
|
||||
@unlocked_repo
|
||||
def forget_snapshot(self, snapshot_id) -> None:
|
||||
"""
|
||||
Either removes snapshot or marks it for deletion later,
|
||||
depending on server settings
|
||||
"""
|
||||
def forget_snapshots(self, snapshot_ids: List[str]) -> None:
|
||||
# in case the backupper program supports batching, otherwise implement it by cycling
|
||||
forget_command = self.restic_command(
|
||||
"forget",
|
||||
snapshot_id,
|
||||
[snapshot_ids],
|
||||
# TODO: prune should be done in a separate process
|
||||
"--prune",
|
||||
)
|
||||
|
@ -414,7 +418,7 @@ class ResticBackupper(AbstractBackupper):
|
|||
|
||||
if "no matching ID found" in err:
|
||||
raise ValueError(
|
||||
"trying to delete, but no such snapshot: ", snapshot_id
|
||||
"trying to delete, but no such snapshot(s): ", snapshot_ids
|
||||
)
|
||||
|
||||
assert (
|
||||
|
|
Loading…
Reference in a new issue