mirror of
https://github.com/psy0rz/zfs_autobackup.git
synced 2025-04-11 22:40:01 +03:00
wip
This commit is contained in:
parent
052890a7e0
commit
8fbbb59055
@ -33,24 +33,6 @@ class Log:
|
||||
self.show_debug=show_debug
|
||||
self.show_verbose=show_verbose
|
||||
|
||||
# def titled_str(self, txt, titles):
|
||||
# """magic to make our log messages ident and more clear"""
|
||||
# str=""
|
||||
# count=0
|
||||
# changed=False
|
||||
# for title in titles:
|
||||
# if not self.show_debug and not changed and len(self.titles)>count and self.titles[count]==title:
|
||||
# str=str+ ( " " * len(title))+ " "
|
||||
# else:
|
||||
# str=str+title+": "
|
||||
# changed=True
|
||||
# # str=str+": "
|
||||
# count=count+1
|
||||
#
|
||||
# str=str+txt
|
||||
# self.titles=list(titles)
|
||||
# return(str)
|
||||
|
||||
def error(self, txt):
|
||||
if use_color:
|
||||
print(colorama.Fore.RED+colorama.Style.BRIGHT+ "! "+txt+colorama.Style.RESET_ALL, file=sys.stderr)
|
||||
@ -92,6 +74,16 @@ class ThinnerRule:
|
||||
's' : 1,
|
||||
}
|
||||
|
||||
TIME_DESC={
|
||||
'y' : 'year',
|
||||
'm' : 'month',
|
||||
'w' : 'week',
|
||||
'd' : 'day',
|
||||
'h' : 'hour',
|
||||
'min' : 'minute',
|
||||
's' : 'second',
|
||||
}
|
||||
|
||||
def parse_rule(self, rule_str):
|
||||
"""parse scheduling string
|
||||
example:
|
||||
@ -125,15 +117,20 @@ class ThinnerRule:
|
||||
if self.period>self.ttl:
|
||||
raise(Exception("Period cant be longer than ttl in schedule: '{}'".format(rule_str)))
|
||||
|
||||
|
||||
self.rule_str=rule_str
|
||||
|
||||
self.human_str="Keep a snapshot every {} {}{}, delete after {} {}{}.".format(
|
||||
period_amount, self.TIME_DESC[period_unit], period_amount!=1 and "s" or "", ttl_amount, self.TIME_DESC[ttl_unit], ttl_amount!=1 and "s" or "" )
|
||||
|
||||
|
||||
def __str__(self):
|
||||
"""get schedule as a schedule string"""
|
||||
|
||||
return(self.rule_str)
|
||||
|
||||
|
||||
|
||||
|
||||
def __init__(self, rule_str):
|
||||
self.parse_rule(rule_str)
|
||||
pass
|
||||
@ -142,17 +139,34 @@ class ThinnerRule:
|
||||
class Thinner:
|
||||
"""progressive thinner (universal, used for cleaning up snapshots)"""
|
||||
|
||||
def __init__(self, schedule_str, always_keep=1):
|
||||
"""schedule_str: comman seperated list of ThinnerRules
|
||||
always_keep: always keep the last X snapshots
|
||||
def __init__(self, schedule_str=""):
|
||||
"""schedule_str: comma seperated list of ThinnerRules. A plain number specifies how many snapshots to always keep.
|
||||
"""
|
||||
|
||||
self.always_keep=always_keep
|
||||
self.rules=[]
|
||||
self.always_keep=0
|
||||
|
||||
if schedule_str=="":
|
||||
return
|
||||
|
||||
rule_strs=schedule_str.split(",")
|
||||
for rule_str in rule_strs:
|
||||
self.rules.append(ThinnerRule(rule_str))
|
||||
if rule_str.isdigit():
|
||||
self.always_keep=int(rule_str)
|
||||
if self.always_keep<0:
|
||||
raise(Exception("Number of snapshots to keep cant be negative: {}".format(self.keep_source)))
|
||||
else:
|
||||
self.rules.append(ThinnerRule(rule_str))
|
||||
|
||||
def human_rules(self):
|
||||
"""get list of human readable rules"""
|
||||
ret=[]
|
||||
if self.always_keep:
|
||||
ret.append("Keep the last {} snapshot{}.".format(self.always_keep, self.always_keep!=1 and "s" or ""))
|
||||
for rule in self.rules:
|
||||
ret.append(rule.human_str)
|
||||
|
||||
return(ret)
|
||||
|
||||
def run(self,objects, now=None):
|
||||
"""thin list of objects with current schedule rules.
|
||||
@ -800,7 +814,7 @@ class ZfsDataset():
|
||||
class ZfsNode(ExecuteNode):
|
||||
"""a node that contains zfs datasets. implements global (systemwide/pool wide) zfs commands"""
|
||||
|
||||
def __init__(self, backup_name, zfs_autobackup, ssh_to=None, readonly=False, description="", debug_output=False):
|
||||
def __init__(self, backup_name, zfs_autobackup, ssh_to=None, readonly=False, description="", debug_output=False, thinner=Thinner()):
|
||||
self.backup_name=backup_name
|
||||
if not description:
|
||||
self.description=ssh_to
|
||||
@ -809,6 +823,9 @@ class ZfsNode(ExecuteNode):
|
||||
|
||||
self.zfs_autobackup=zfs_autobackup #for logging
|
||||
|
||||
for rule in thinner.human_rules():
|
||||
self.verbose(rule)
|
||||
|
||||
ExecuteNode.__init__(self, ssh_to=ssh_to, readonly=readonly, debug_output=debug_output)
|
||||
|
||||
def verbose(self,txt):
|
||||
@ -910,8 +927,9 @@ class ZfsAutobackup:
|
||||
epilog='When a filesystem fails, zfs_backup will continue and report the number of failures at that end. Also the exit code will indicate the number of failures.')
|
||||
parser.add_argument('--ssh-source', default=None, help='Source host to get backup from. (user@hostname) Default %(default)s.')
|
||||
parser.add_argument('--ssh-target', default=None, help='Target host to push backup to. (user@hostname) Default %(default)s.')
|
||||
parser.add_argument('--keep-source', type=int, default=30, help='Number of days to keep old snapshots on source. Default %(default)s.')
|
||||
parser.add_argument('--keep-target', type=int, default=30, help='Number of days to keep old snapshots on target. Default %(default)s.')
|
||||
parser.add_argument('--keep-source', type=str, default="3,1d1w,1w1m,1m1y", help='Thinning schedule for old source snapshots. Default %(default)s')
|
||||
parser.add_argument('--keep-target', type=str, default="3,1d1w,1w1m,1m1y", help='Thinning schedule for old target snapshots. Default %(default)s')
|
||||
|
||||
parser.add_argument('backup_name', help='Name of the backup (you should set the zfs property "autobackup:backup-name" to true on filesystems you want to backup')
|
||||
parser.add_argument('target_path', help='Target ZFS filesystem')
|
||||
|
||||
@ -964,11 +982,15 @@ class ZfsAutobackup:
|
||||
self.log.verbose("#### "+title)
|
||||
|
||||
def run(self):
|
||||
self.set_title("Snapshot schedule")
|
||||
|
||||
description="[Source]"
|
||||
source_node=ZfsNode(self.args.backup_name, self, ssh_to=self.args.ssh_source, readonly=self.args.test, debug_output=self.args.debug_output, description=description)
|
||||
source_thinner=Thinner(self.args.keep_source)
|
||||
source_node=ZfsNode(self.args.backup_name, self, ssh_to=self.args.ssh_source, readonly=self.args.test, debug_output=self.args.debug_output, description=description, thinner=source_thinner)
|
||||
|
||||
description="[Target]"
|
||||
target_node=ZfsNode(self.args.backup_name, self, ssh_to=self.args.ssh_target, readonly=self.args.test, debug_output=self.args.debug_output, description=description)
|
||||
target_thinner=Thinner(self.args.keep_target)
|
||||
target_node=ZfsNode(self.args.backup_name, self, ssh_to=self.args.ssh_target, readonly=self.args.test, debug_output=self.args.debug_output, description=description, thinner=target_thinner)
|
||||
# target_node.run(["/root/outputtest"], readonly=True)
|
||||
|
||||
self.set_title("Selecting")
|
||||
|
Loading…
x
Reference in New Issue
Block a user