Modes = ["full", "incr", "diff"]
+
+class Options:
+ dryrun = False
+
+
class Epoch:
units = {
e = Epoch()
if name in self.epochs:
raise Config.ReadError("Epoch '{0}' already defined.".format(name))
+ p = re.compile(r'^\w+$')
+ if not p.match(name):
+ raise Config.ReadError("Epoch name '{0}' does not only " + \
+ "comprise alphanumeric characters.".format(name))
if name in Epoch.units:
e.unit = name
def _read_set(self, config, sec):
name = sec[4:].strip()
+ p = re.compile(r'^\w+$')
+ if not p.match(name):
+ raise Config.ReadError("Set name '{0}' does not only " + \
+ "comprise alphanumeric characters.".format(name))
+
dirs = []
excludes = []
return [ d for d in dirs if os.path.isdir(os.path.join(basedir, d)) ]
- def listOldBackups(self):
+ def listExistingBackups(self):
"""Returns a list of old backups."""
backups = []
taropts = []
# Tar is verbose is sitarba is verbose
- if LogConf.con.level <= logging.INFO:
+ if LogConf.con.level <= logging.DEBUG:
taropts += ["--verbose"]
# Add the since date, if given
then use mode for given epoch. Use given mode otherwise."""
now = datetime.datetime.now()
- oldbackups = self.listOldBackups()
+ oldbackups = self.listExistingBackups()
# Get epoch of backup
if epoch == None:
if since != None:
logging.debug("Making backup relative to " + since.ctime())
+ if Options.dryrun:
+ return
+
yesno = self.ask_user_yesno("Proceed? [Y, n] ")
if yesno == "n":
return
dirname = Backup.getDirName(now, epoch, mode)
tmpdirname = dirname + ("-%x" % (random.random()*2e16) )
targetdir = os.path.join(basedir, tmpdirname)
- os.mkdir( targetdir )
+ os.mkdir(targetdir)
# Add file logger
logfile = logging.getLogger("backuplog")
- fil = logging.FileHandler( os.path.join(targetdir, "log") )
+ fil = logging.FileHandler(os.path.join(targetdir, "log"))
fil.setLevel(logging.DEBUG)
logfile.addHandler(fil)
"""Prune old backup files"""
allDirs = sorted(self.listAllDirs())
- # Collect all directories not matching backup name
+ # Collect all directories that are removed
removeDirs = [ d for d in allDirs if not Backup.isBackupDir(d) ]
- # Get all directories which are kept
- backups = self.listOldBackups()
- keepdirs = []
+ # Get all backups
+ backups = self.listExistingBackups()
+ # Group backups by epoch and sort them by age
byepoch = { e : list(sorted( [ b for b in backups if b.epoch == e ], \
- key=lambda b : b.date, reverse=True)) for e in self.conf.getRealEpochsSorted() }
+ key=lambda b : b.date, reverse=True)) \
+ for e in self.conf.getRealEpochsSorted() }
+ # If we have too many backups of a specific epoch --> add them to remove list
for e in byepoch:
epoch = self.conf.epochs[e]
old = byepoch[e][epoch.numkeeps:]
logging.info("No stale/outdated entries to remove.")
return
+ if Options.dryrun:
+ return
+
basedir = self.conf.backupdir
yesno = self.ask_user_yesno("Remove entries marked by '*'? [y, N] ")
if yesno == "y":
print(" -e, --epoch EPOCH force to create backup for given epoch, which")
print(" can be 'sporadic' or one of the configured epochs")
print(" -m, --mode MODE override mode: full, diff, or incr")
+ print(" -n, --dry-run don't do anything, just tell what would be done")
print(" -v, --verbose be more verbose and interact with user")
print(" --verbosity LEVEL set verbosity to LEVEL, which can be")
print(" error, warning, info, debug")
logging.error("Unknown mode '" + mode + "'.")
exit(1)
+ elif opt in ["-n", "--dry-run"]:
+ Options.dryrun = True
+
elif opt in ["-e", "--epoch"]:
i += 1
epoch = sys.argv[i]
man.backup(epoch, mode)
if cmd == "list":
- for b in sorted(man.listOldBackups(), key=lambda b: b.date):
+ for b in sorted(man.listExistingBackups(), key=lambda b: b.date):
print(b.colAlignedString())
if cmd == "prune":