2020-12-17 10:06:30 +01:00
|
|
|
import argparse
|
|
|
|
import logging
|
|
|
|
import logging.handlers
|
2020-12-21 15:48:22 +01:00
|
|
|
import os
|
2020-12-17 10:06:30 +01:00
|
|
|
import re
|
2020-12-21 15:48:22 +01:00
|
|
|
import stat
|
2020-12-17 10:06:30 +01:00
|
|
|
import sys
|
|
|
|
|
|
|
|
import rotator
|
|
|
|
|
|
|
|
def parse_args():
|
|
|
|
parser = argparse.ArgumentParser(description="Rotate backups based on timestamp in names")
|
|
|
|
parser.add_argument(
|
|
|
|
'-y', '--yearly',
|
|
|
|
help='number of yearly backups to keep',
|
|
|
|
type=int,
|
|
|
|
default=0)
|
|
|
|
parser.add_argument(
|
|
|
|
'-m', '--monthly',
|
|
|
|
help='number of monthly backups to keep',
|
|
|
|
type=int,
|
|
|
|
default=0)
|
|
|
|
parser.add_argument(
|
|
|
|
'-w', '--weekly',
|
|
|
|
help='number of weekly backups to keep',
|
|
|
|
type=int,
|
|
|
|
default=0)
|
|
|
|
parser.add_argument(
|
|
|
|
'-d', '--daily',
|
|
|
|
help='number of daily backups to keep',
|
|
|
|
type=int,
|
|
|
|
default=0)
|
|
|
|
parser.add_argument(
|
|
|
|
'-o', '--hourly',
|
|
|
|
help='number of hourly backups to keep',
|
|
|
|
type=int,
|
|
|
|
default=0)
|
|
|
|
parser.add_argument(
|
|
|
|
'--min30',
|
|
|
|
help='number of half-hourly backups to keep',
|
|
|
|
type=int,
|
|
|
|
default=0)
|
|
|
|
parser.add_argument(
|
|
|
|
'--min15',
|
|
|
|
help='number of quarterly-hourly backups to keep',
|
|
|
|
type=int,
|
|
|
|
default=0)
|
|
|
|
parser.add_argument(
|
|
|
|
'--min5',
|
|
|
|
help='number of 5-minutely backups to keep',
|
|
|
|
type=int,
|
|
|
|
default=0)
|
|
|
|
parser.add_argument(
|
|
|
|
'--min1',
|
|
|
|
help='number of minutely backups to keep',
|
|
|
|
type=int,
|
|
|
|
default=0)
|
|
|
|
|
|
|
|
parser.add_argument(
|
|
|
|
'-r', '--regex',
|
|
|
|
help='''only rotate backups matching the given regex. Regex must
|
|
|
|
contain at least two match groups, the first being identifier for
|
|
|
|
the backup set and the second being the date.''',
|
|
|
|
default=r'^(.*)[-_.]([0-9]{4}-[0-9]{2}-[0-9]{2}_[0-9]{4})')
|
|
|
|
parser.add_argument(
|
|
|
|
'-t', '--time-format',
|
|
|
|
help='time format of the timestamp (python format)',
|
|
|
|
default='%Y-%m-%d_%H%M')
|
|
|
|
|
|
|
|
parser.add_argument(
|
|
|
|
'-R', '--recurse',
|
|
|
|
action='store_true',
|
|
|
|
help='process paths recursively')
|
|
|
|
parser.add_argument(
|
|
|
|
'path',
|
|
|
|
help='Full path to the directory containing the backup files',
|
|
|
|
nargs='+')
|
|
|
|
return parser.parse_args()
|
|
|
|
|
|
|
|
def main():
|
|
|
|
log = logging.getLogger(rotator._logger)
|
|
|
|
log.setLevel(logging.INFO)
|
|
|
|
|
|
|
|
handler = logging.StreamHandler()
|
|
|
|
handler.setLevel(logging.WARNING)
|
|
|
|
log.addHandler(handler)
|
|
|
|
|
2020-12-21 15:48:22 +01:00
|
|
|
handler = None
|
|
|
|
for logsocket in ('/var/run/log', '/dev/log'):
|
|
|
|
try:
|
|
|
|
mode = os.stat(logsocket).st_mode
|
|
|
|
except FileNotFoundError:
|
|
|
|
continue
|
|
|
|
|
|
|
|
if stat.S_ISSOCK(mode):
|
|
|
|
handler = logging.handlers.SysLogHandler(address=logsocket)
|
|
|
|
formatter = logging.Formatter(fmt='rotator[%(process)s] %(message)s')
|
|
|
|
handler.setFormatter(formatter)
|
|
|
|
handler.setLevel(logging.INFO)
|
|
|
|
log.addHandler(handler)
|
|
|
|
break
|
|
|
|
|
|
|
|
if not handler:
|
|
|
|
log.warning('No syslog socket found, will not log to syslog')
|
2020-12-17 10:06:30 +01:00
|
|
|
|
|
|
|
args = parse_args()
|
|
|
|
|
|
|
|
if all([not x for x in
|
|
|
|
[args.yearly,
|
|
|
|
args.monthly,
|
|
|
|
args.weekly,
|
|
|
|
args.daily,
|
|
|
|
args.hourly,
|
|
|
|
args.min30,
|
|
|
|
args.min15,
|
|
|
|
args.min5,
|
|
|
|
args.min1]]):
|
|
|
|
log.error('All time intervals set to 0, this would remove all backups, refusing to run')
|
|
|
|
sys.exit(2)
|
|
|
|
|
|
|
|
rotator.rotate(
|
|
|
|
args.path,
|
|
|
|
re.compile(args.regex),
|
|
|
|
args.time_format,
|
|
|
|
recurse=args.recurse,
|
|
|
|
keep_yearly=args.yearly,
|
|
|
|
keep_monthly=args.monthly,
|
|
|
|
keep_weekly=args.weekly,
|
|
|
|
keep_daily=args.daily,
|
|
|
|
keep_hourly=args.hourly,
|
|
|
|
keep_30min=args.min30,
|
|
|
|
keep_15min=args.min15,
|
|
|
|
keep_5min=args.min5,
|
|
|
|
keep_1min=args.min1)
|