rotator/rotator/__main__.py

135 lines
4.0 KiB
Python

import argparse
import logging
import logging.handlers
import os
import re
import stat
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)
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')
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)