Improve tracking of segments and segment utilization.
[cumulus.git] / python / cumulus / main.py
index 7700148..62f2665 100644 (file)
@@ -22,6 +22,7 @@ This implements maintenance functions and is a wrapper around the C++
 cumulus-backup program.
 """
 
+import datetime
 import re
 import sys
 
@@ -59,11 +60,55 @@ def prune_backups(backup_config, scheme):
     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)