-# Cumulus: Smart Filesystem Backup to Dumb Servers
-#
-# Copyright (C) 2012 Google Inc.
-# Written by Michael Vrable <mvrable@cs.ucsd.edu>
+# Cumulus: Efficient Filesystem Backup to the Cloud
+# Copyright (C) 2012 The Cumulus Developers
+# See the AUTHORS file for a list of contributors.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
cumulus-backup program.
"""
+import datetime
import re
import sys
cmd_util.options = options
cmd_util.cmd_garbage_collect([])
+def prune_localdb(backup_config, scheme, next_snapshot=None):
+ """Clean old snapshots out of the local database.
+
+ Clear old snapshots out of the local database, possibly in preparation for
+ running a new backup. One snapshot of each configured retention period is
+ kept (i.e., one weekly and one daily), and the most recent snapshot is
+ always retained. If next_snapshot is not None, it should be the timestamp
+ when (approximately) the next snapshot will be taken; if that snapshot
+ would be a daily, weekly, etc. snapshot, then it may result in the previous
+ snapshot of the same duration being evicted from the local database.
+
+ Note that in this sense, "evict" merely refers to tracking the snapshots in
+ the local database; this function does not delete backups from the backup
+ storage.
+ """
+ # Fetch the list of existing snapshots in the local database. Pruning only
+ # makes sense if there are more than one snapshots present.
+ db = cumulus.LocalDatabase(backup_config.get_global("localdb"))
+ snapshots = sorted(db.list_snapshots(scheme))
+ if len(snapshots) <= 1:
+ return
+
+ # Classify the snapshots (daily, weekly, etc.) and keep the most recent one
+ # of each category. Also ensure that the most recent snapshot is retained.
+ retention = backup_config.get_retention_for_scheme(scheme)
+ for snapshot in snapshots:
+ retention.consider_snapshot(snapshot)
+ if next_snapshot is not None:
+ retention.consider_snapshot(next_snapshot)
+ retained = set(retention.last_snapshots().values())
+ retained.add(snapshots[-1])
+ print retention.last_snapshots()
+ print retained
+ for s in snapshots:
+ print s, s in retained
+
+ evicted = [s for s in snapshots if s not in retained]
+ for s in evicted:
+ db.delete_snapshot(scheme, s)
+ db.garbage_collect()
+ db.commit()
+
def main(argv):
backup_config = config.CumulusConfig(argv[1])
for scheme in backup_config.backup_schemes():
print scheme
- prune_backups(backup_config, scheme)
+ #prune_backups(backup_config, scheme)
+ prune_localdb(backup_config, scheme, datetime.datetime.utcnow())
+ #prune_localdb(backup_config, scheme, datetime.datetime(2013, 1, 1))
if __name__ == "__main__":
main(sys.argv)