Mode = ["full", "incr", "diff"]
-Epoch = { \
+RealEpoch = { \
"hour" : datetime.timedelta(0, 3600), \
"day" : datetime.timedelta(1), \
"week" : datetime.timedelta(7), \
"month" : datetime.timedelta(30), \
"year" : datetime.timedelta(365) }
+Epoch = dict(RealEpoch, **{ \
+ "sporadic" : datetime.timedelta(0,0) \
+ })
+
+
class Backup:
"""A single backup has a date, an epoch and a mode."""
def __init__(self):
self.directory = "/media/backup"
self.format = self.formats[0]
- self.epochkeeps = { k : 0 for k in Epoch.keys() }
- self.epochmodes = { k : "full" for k in Epoch.keys() }
+ self.epochkeeps = { k : 0 for k in RealEpoch.keys() }
+ self.epochmodes = { k : "full" for k in RealEpoch.keys() }
self.exclpatterns = []
self.sets = []
self.checksum = None
for opt in config.options("history"):
if opt.startswith("keep"):
epoch = opt[4:]
- if not epoch in Epoch.keys():
+ if not epoch in RealEpoch.keys():
raise Config.ReadException("Invalid option 'keep" + epoch + "'.")
self.epochkeeps[epoch] = int(config.getint("history", opt))
elif opt.startswith("mode"):
epoch = opt[4:]
- if not epoch in Epoch.keys():
+ if not epoch in RealEpoch.keys():
raise Config.ReadException("Invalid option 'mode" + epoch + "'.")
self.epochmodes[epoch] = config.get("history", opt)
if not self.epochmodes[epoch] in Mode:
raise Config.ReadException("Invalid mode given.")
else:
raise Config.ReadException("Invalid option '" + opt + "'.")
-
+
if config.has_section("input"):
for opt in config.options("input"):
if opt.startswith("exclude"):
def listAllDirs(self):
"""List all dirs in destination directory"""
-
+
# Get all entries
basedir = self.conf.directory
dirs = os.listdir(basedir)
# Filter directories
return [ d for d in dirs if os.path.isdir(os.path.join(basedir, d)) ]
+
def listOldBackups(self):
"""Returns a list of old backups."""
# Find the longest epoch for which we would like the make a backup
latest = datetime.datetime(1900, 1, 1)
- for timespan, e in reversed(sorted( [ (Epoch[e], e) for e in Epoch ] )):
+ for timespan, e in reversed(sorted( [ (Epoch[e], e) for e in RealEpoch ] )):
# We make backups of that epoch
if self.conf.epochkeeps[e] == 0:
continue
if since != None:
taropts += ["-N", since.strftime("%Y-%m-%d %H:%M:%S")]
-
+
for pat in self.conf.exclpatterns:
taropts += ["--exclude", pat]
print("tarargs: ", tarargs)
tarp = subprocess.Popen( tarargs, \
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-
+
while tarp.poll():
l = tarp.stdout.readline()
if len(l) > 0:
# No old full backups existing
if mode != "full" and len(oldfullbackups)==0:
- print("No full backups existing. Making a full backup.")
+ print("No full backups existing. Making a full backup.")
# Checksum changed -> self.config file changed
if self.conf.checksum != self.conf.lastchecksum:
f = open( os.path.join(basedir, self.conf.checksumfn), "w")
f.write( self.conf.checksum )
f.close()
-
+
def prune(self):
"""Prune old backup files"""
# Get all directories which are outdated
backups = self.listOldBackups()
byepoch = { e : list(sorted( [ b for b in backups if b.epoch == e ], \
- key=lambda b : b.date, reverse=True)) for e in Epoch }
+ key=lambda b : b.date, reverse=True)) for e in RealEpoch }
for e in byepoch:
keep = self.conf.epochkeeps[e]
old = byepoch[e][keep:]
print("shbackup - a simple backup solution.")
print("")
print("Usage:")
- print(" " + sys.argv[0] + " [-C <configfile>] [cmd]")
+ print(" " + sys.argv[0] + " {options} [cmd]")
print(" " + sys.argv[0] + " --help")
print("")
print("Commands:")
- print(" backup make a new backup, if necessary")
- print(" list list all backups")
- print(" prune prune outdated/old backups")
+ print(" backup make a new backup, if necessary")
+ print(" list list all backups (default)")
+ print(" prune prune outdated/old backups")
print("")
print("Options:")
- print(" -C <configfile> use given configuration file")
- print(" default: /etc/shbackup.conf")
- print(" -m, --mode <mode> override mode: full, diff, or incr")
- print(" -e, --epoch <epoch> create backup for given epoch:")
- print(" year, month, week, day, hour")
- print(" -h, --help print this usage text")
+ print(" -C <configfile> use given configuration file")
+ print(" default: /etc/shbackup.conf")
+ print(" -m, --mode <mode> override mode: full, diff, or incr")
+ print(" -e, --epoch <epoch> force to create backup for given epoch:")
+ print(" year, month, week, day, hour, sporadic")
+ print(" -h, --help print this usage text")
if __name__ == "__main__":