M5: retention policy, prune with repacking, append-only locations

- RetentionPolicy (last/daily/weekly/monthly) and PruneService: forget
  snapshots the policy drops, delete packs nothing uses and repack mostly
  unused ones by copying encrypted blobs as-is; new packs are indexed
  before old ones are removed
- a location lock keeps prune and backups apart; append-only locations
  are never pruned (cleanup via the location's lifecycle rules)
- weekly prune from the background job; occ backup:prune [--dry-run],
  backup:retention, backup:target:append-only
- tests: forget+prune frees space and the remaining snapshot restores
  identically, repack of mixed packs, dry-run preview, retention buckets
This commit is contained in:
2026-10-02 02:21:48 +02:00
parent fabdfa6786
commit 38654317a2
16 changed files with 606 additions and 1 deletions
+3
View File
@@ -51,6 +51,9 @@ class BackupService {
if ($this->config->getSystemValue('objectstore', null) !== null) {
throw new \RuntimeException('Object storage as primary storage is not supported yet');
}
if ($this->locking->isLocked(PruneService::lockKey($target), ILockingProvider::LOCK_EXCLUSIVE)) {
throw new \RuntimeException('A cleanup of ' . $target->getName() . ' is running; try again later');
}
$running = $this->runs->findRunning($target->getId(), self::KIND_FULL);
if ($running !== []) {
return $running[0];