summaryrefslogtreecommitdiff
path: root/rdiff-backup/src/manage.py
diff options
context:
space:
mode:
Diffstat (limited to 'rdiff-backup/src/manage.py')
-rw-r--r--rdiff-backup/src/manage.py99
1 files changed, 99 insertions, 0 deletions
diff --git a/rdiff-backup/src/manage.py b/rdiff-backup/src/manage.py
new file mode 100644
index 0000000..c0f4a85
--- /dev/null
+++ b/rdiff-backup/src/manage.py
@@ -0,0 +1,99 @@
+execfile("restore.py")
+
+#######################################################################
+#
+# manage - list, delete, and otherwise manage increments
+#
+
+class ManageException(Exception): pass
+
+class Manage:
+ def get_incobjs(datadir):
+ """Return Increments objects given the rdiff-backup data directory"""
+ return map(IncObj, Manage.find_incrps_with_base(datadir, "increments"))
+
+ def find_incrps_with_base(dir_rp, basename):
+ """Return list of incfiles with given basename in dir_rp"""
+ rps = map(dir_rp.append, dir_rp.listdir())
+ incrps = filter(RPath.isincfile, rps)
+ result = filter(lambda rp: rp.getincbase_str() == basename, incrps)
+ Log("find_incrps_with_base: found %d incs" % len(result), 6)
+ return result
+
+ def describe_root_incs(datadir):
+ """Return a string describing all the the root increments"""
+ result = []
+ currentrps = Manage.find_incrps_with_base(datadir, "current_mirror")
+ if not currentrps:
+ Log("Warning: no current mirror marker found", 1)
+ elif len(currentrps) > 1:
+ Log("Warning: multiple mirror markers found", 1)
+ for rp in currentrps:
+ result.append("Found mirror marker %s" % rp.path)
+ result.append("Indicating latest mirror taken at %s" %
+ Time.stringtopretty(rp.getinctime()))
+ result.append("---------------------------------------------"
+ "-------------")
+
+ # Sort so they are in reverse order by time
+ time_w_incobjs = map(lambda io: (-io.time, io),
+ Manage.get_incobjs(datadir))
+ time_w_incobjs.sort()
+ incobjs = map(lambda x: x[1], time_w_incobjs)
+ result.append("Found %d increments:" % len(incobjs))
+ result.append("\n------------------------------------------\n".join(
+ map(IncObj.full_description, incobjs)))
+ return "\n".join(result)
+
+ def delete_earlier_than(baserp, time):
+ """Deleting increments older than time in directory baserp
+
+ time is in seconds. It will then delete any empty directories
+ in the tree. To process the entire backup area, the
+ rdiff-backup-data directory should be the root of the tree.
+
+ """
+ def yield_files(rp):
+ yield rp
+ if rp.isdir():
+ for filename in rp.listdir():
+ for sub_rp in yield_files(rp.append(filename)):
+ yield sub_rp
+
+ for rp in yield_files(baserp):
+ if ((rp.isincfile() and
+ Time.stringtotime(rp.getinctime()) < time) or
+ (rp.isdir() and not rp.listdir())):
+ Log("Deleting increment file %s" % rp.path, 5)
+ rp.delete()
+
+MakeStatic(Manage)
+
+
+class IncObj:
+ """Increment object - represent a completed increment"""
+ def __init__(self, incrp):
+ """IncObj initializer
+
+ incrp is an RPath of a path like increments.TIMESTR.dir
+ standing for the root of the increment.
+
+ """
+ if not incrp.isincfile():
+ raise ManageException("%s is not an inc file" % incrp.path)
+ self.incrp = incrp
+ self.time = Time.stringtotime(incrp.getinctime())
+
+ def getbaserp(self):
+ """Return rp of the incrp without extensions"""
+ return self.incrp.getincbase()
+
+ def pretty_time(self):
+ """Return a formatted version of inc's time"""
+ return Time.timetopretty(self.time)
+
+ def full_description(self):
+ """Return string describing increment"""
+ s = ["Increment file %s" % self.incrp.path,
+ "Date: %s" % self.pretty_time()]
+ return "\n".join(s)