diff --git a/zfs_autobackup b/zfs_autobackup index ce89c65..bc6276b 100755 --- a/zfs_autobackup +++ b/zfs_autobackup @@ -23,74 +23,75 @@ def debug(txt): print(txt) -class TreeNode(): - """generic tree implementation, with parent/child and prev/next relations""" - def __init__(self, name, parent=None, next=None, prev=None, *args, **kwargs): - self.childs={} - - self.name=name - self.parent=parent - if parent: - if name in parent.childs: - raise(Exception("parent {} already has child {}").format(parent.name, name)) - parent.childs[name]=self - - - self.next=next - if next: - if next.prev: - raise(Exception("{} already has a previous item").format(next.name)) - next.prev=self - - self.prev=prev - if prev: - if prev.next: - raise(Exception("{} already has a next item").format(prev.name)) - prev.next=self - - - def remove(self): - """remove the item from other referenced TreeNodes. call before you actually delete a treeobject""" - - if self.parent: - self.parent.childs.remove(self.name) - - - # let previous and next objects point to eachother - if self.next: - self.next.prev=self.prev - - if self.prev: - self.prev.next=self.next - - self.parent=None - self.next=None - self.prev=None +# class TreeNode(): +# """generic tree implementation, with parent/child and prev/next relations""" +# def __init__(self, name, parent=None, next=None, prev=None, *args, **kwargs): +# self.childs={} +# +# self.name=name +# self.parent=parent +# if parent: +# if name in parent.childs: +# raise(Exception("parent {} already has child {}").format(parent.name, name)) +# parent.childs[name]=self +# +# +# self.next=next +# if next: +# if next.prev: +# raise(Exception("{} already has a previous item").format(next.name)) +# next.prev=self +# +# self.prev=prev +# if prev: +# if prev.next: +# raise(Exception("{} already has a next item").format(prev.name)) +# prev.next=self +# +# +# def remove(self): +# """remove the item from other referenced TreeNodes. call before you actually delete a treeobject""" +# +# if self.parent: +# self.parent.childs.remove(self.name) +# +# +# # let previous and next objects point to eachother +# if self.next: +# self.next.prev=self.prev +# +# if self.prev: +# self.prev.next=self.next +# +# self.parent=None +# self.next=None +# self.prev=None +# +# -class ZfsNode(TreeNode): - """an endpoint that contains zfs filesystems. +class ExecuteNode: + """an endpoint to execute local or remote commands via ssh""" - contains lowlevel zfs wrappers for actual zfs commands on remote nodes via ssh (or local) + def __init__(self, ssh_to=None, readonly=False): + """ssh_to: server you want to ssh to. none means local + readonly: only execute commands that dont make any changes (usefull for testing-runs) + """ - methods only accept and return simple dataset names, just like the real commands - """ - - def __init__(self, ssh_to, *args, **kwargs): - """ssh_to: server you want to ssh to. specify 'local' to just use local commands without ssh""" - - super().__init__(*args, **kwargs) self.ssh_to=ssh_to - def run(cmd, input=None, tab_split=False, valid_exitcodes=[ 0 ], test=False): - """run a command on the node""" + def run(cmd, input=None, tab_split=False, valid_exitcodes=[ 0 ], readonly=False): + """run a command on the node + + readonly: make this True if the command doesnt make any changes and is safe to execute in testmode + """ encoded_cmd=[] #use ssh? - if self.ssh_to != "local": + if self.ssh_to != None: encoded_cmd.extend(["ssh", self.ssh_to]) #make sure the command gets all the data in utf8 format: @@ -106,8 +107,8 @@ class ZfsNode(TreeNode): #debug and test stuff debug_txt="# "+" ".join(encoded_cmd) - if test: - debug("[SKIPPING] "+debug_txt) + if self.readonly and not readonly: + debug("[NOT EXECUTING (readonly mode)] "+debug_txt) else: debug(debug_txt) @@ -117,7 +118,7 @@ class ZfsNode(TreeNode): else: stdin=None - if test: + if self.readonly and not readonly: return #execute and parse/return results @@ -137,6 +138,12 @@ class ZfsNode(TreeNode): +"""a node that contains zfs datasets""" +class ZfsNode(ExecuteNode): + def __init__(self, ssh_to=None, readonly=False): + super().__init__(ssh_to=None, readonly=readonly) + + class ZfsPool(TreeNode): """a zfs pool"""