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
1cbf92cabc
commit
9ee5b2545c
@ -22,6 +22,10 @@ def debug(txt):
|
||||
if args.debug:
|
||||
print(txt)
|
||||
|
||||
#fatal abort execution, exit code 255
|
||||
def abort(txt):
|
||||
error(txt)
|
||||
sys.exit(255)
|
||||
|
||||
# class TreeNode():
|
||||
# """generic tree implementation, with parent/child and prev/next relations"""
|
||||
@ -69,6 +73,24 @@ def debug(txt):
|
||||
#
|
||||
#
|
||||
|
||||
class cached_property(object):
|
||||
""" A property that is only computed once per instance and then replaces
|
||||
itself with an ordinary attribute. Deleting the attribute resets the
|
||||
property.
|
||||
|
||||
Source: https://github.com/bottlepy/bottle/commit/fa7733e075da0d790d809aa3d2f53071897e6f76
|
||||
"""
|
||||
|
||||
def __init__(self, func):
|
||||
self.__doc__ = getattr(func, '__doc__')
|
||||
self.func = func
|
||||
|
||||
def __get__(self, obj, cls):
|
||||
if obj is None:
|
||||
return self
|
||||
value = obj.__dict__[self.func.__name__] = self.func(obj)
|
||||
return value
|
||||
|
||||
|
||||
|
||||
class ExecuteNode:
|
||||
@ -80,6 +102,7 @@ class ExecuteNode:
|
||||
"""
|
||||
|
||||
self.ssh_to=ssh_to
|
||||
self.readonly=readonly
|
||||
|
||||
|
||||
def run(self, cmd, input=None, tab_split=False, valid_exitcodes=[ 0 ], readonly=False):
|
||||
@ -136,21 +159,39 @@ class ExecuteNode:
|
||||
ret.append(line.split("\t"))
|
||||
return(ret)
|
||||
|
||||
def __repr__(self):
|
||||
return(self.ssh_to)
|
||||
|
||||
|
||||
class ZfsDataset:
|
||||
class ZfsDataset():
|
||||
"""a zfs dataset (filesystem/volume/snapshot)"""
|
||||
def __init__(self, zfs_node, name):
|
||||
self.zfs_node=zfs_node
|
||||
self.name=name
|
||||
|
||||
def __repr__(self):
|
||||
return("{}: {}".format(self.zfs_node, self.name))
|
||||
|
||||
@cached_property
|
||||
def properties(self):
|
||||
"""gets all zfs properties"""
|
||||
|
||||
cmd=[
|
||||
"zfs", "get", "all", "-H", "-o", "property,value", self.name
|
||||
]
|
||||
|
||||
return(dict(self.zfs_node.run(tab_split=True, cmd=cmd, valid_exitcodes=[ 0, 1 ])))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class ZfsNode(ExecuteNode):
|
||||
"""a node that contains zfs datasets. implements global lowlevel zfs commands"""
|
||||
|
||||
def __init__(self, backup_name, ssh_to=None, readonly=False):
|
||||
self.backup_name=backup_name
|
||||
ExecuteNode.__init__(self, ssh_to=None, readonly=readonly)
|
||||
ExecuteNode.__init__(self, ssh_to=ssh_to, readonly=readonly)
|
||||
|
||||
def get_selected_datasets(self):
|
||||
"""determine filesystems that should be backupped by looking at the special autobackup-property
|
||||
@ -180,7 +221,7 @@ class ZfsNode(ExecuteNode):
|
||||
elif source.find("inherited from ")==0 and (value=="true" or value=="child"):
|
||||
inherited_from=re.sub("^inherited from ", "", source)
|
||||
if inherited_from in direct_filesystems:
|
||||
selected_filesystems.append(name)
|
||||
selected_filesystems.append(ZfsDataset(self, name))
|
||||
verbose("* Selected: {0} (inherited selection)".format(name))
|
||||
else:
|
||||
verbose("* Ignored : {0} (already a backup)".format(name))
|
||||
@ -306,4 +347,18 @@ args = parser.parse_args()
|
||||
|
||||
node=ZfsNode(args.backup_name, ssh_to=args.ssh_source)
|
||||
|
||||
node.get_selected_datasets()
|
||||
|
||||
source_datasets=node.get_selected_datasets()
|
||||
if not source_datasets:
|
||||
abort("No source filesystems selected, please do a 'zfs set autobackup:{0}=true' on {1}".format(args.backup_name,args.ssh_source))
|
||||
|
||||
|
||||
|
||||
pprint.pprint(source_datasets)
|
||||
print()
|
||||
pprint.pprint(source_datasets[0].__dict__)
|
||||
|
||||
print(source_datasets[0].properties['mountpoint'])
|
||||
print(source_datasets[1].properties['mountpoint'])
|
||||
print(source_datasets[0].properties['mountpoint'])
|
||||
print(source_datasets[1].properties['mountpoint'])
|
||||
|
Loading…
x
Reference in New Issue
Block a user