mirror of
https://github.com/psy0rz/zfs_autobackup.git
synced 2025-04-17 22:52:20 +03:00
got rid of the rest of CachedProperty. (its too hacky, and confuses pycharm as well, and now we can actually partually invalidate caches. take that past self!)
This commit is contained in:
parent
07542365ac
commit
b54c10ef9a
@ -1,39 +0,0 @@
|
||||
# NOTE: this should inherit from (object) to function correctly with python 2.7
|
||||
class CachedProperty(object):
|
||||
""" A property that is only computed once per instance and
|
||||
then stores the result in _cached_properties of the object.
|
||||
|
||||
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
|
||||
|
||||
propname = self.func.__name__
|
||||
|
||||
if not hasattr(obj, '_cached_properties'):
|
||||
obj._cached_properties = {}
|
||||
|
||||
if propname not in obj._cached_properties:
|
||||
obj._cached_properties[propname] = self.func(obj)
|
||||
# value = obj.__dict__[propname] = self.func(obj)
|
||||
|
||||
return obj._cached_properties[propname]
|
||||
|
||||
@staticmethod
|
||||
def clear(obj):
|
||||
"""clears cache of obj"""
|
||||
if hasattr(obj, '_cached_properties'):
|
||||
obj._cached_properties = {}
|
||||
|
||||
@staticmethod
|
||||
def is_cached(obj, propname):
|
||||
if hasattr(obj, '_cached_properties') and propname in obj._cached_properties:
|
||||
return True
|
||||
else:
|
||||
return False
|
@ -41,7 +41,6 @@ class ZfsDataset:
|
||||
|
||||
def invalidate_cache(self):
|
||||
"""clear caches"""
|
||||
# CachedProperty.clear(self)
|
||||
self.force_exists = None
|
||||
self.__snapshots = None
|
||||
self.__written_since_ours = None
|
||||
@ -448,19 +447,6 @@ class ZfsDataset:
|
||||
seconds = time.mktime(dt.timetuple())
|
||||
return seconds
|
||||
|
||||
# def add_virtual_snapshot(self, snapshot):
|
||||
# """pretend a snapshot exists (usefull in test mode)"""
|
||||
#
|
||||
# # NOTE: we could just call self.snapshots.append() but this would trigger a zfs list which is not always needed.
|
||||
# if CachedProperty.is_cached(self, 'snapshots'):
|
||||
# # already cached so add it
|
||||
# print ("ADDED")
|
||||
# self.snapshots.append(snapshot)
|
||||
# else:
|
||||
# # self.snapshots will add it when requested
|
||||
# print ("ADDED VIRT")
|
||||
# self._virtual_snapshots.append(snapshot)
|
||||
|
||||
@property
|
||||
def snapshots(self):
|
||||
"""get all snapshots of this dataset
|
||||
|
@ -8,7 +8,6 @@ import time
|
||||
|
||||
from .ExecuteNode import ExecuteNode
|
||||
from .Thinner import Thinner
|
||||
from .CachedProperty import CachedProperty
|
||||
from .ZfsPool import ZfsPool
|
||||
from .ZfsDataset import ZfsDataset
|
||||
from .ExecuteNode import ExecuteError
|
||||
@ -18,7 +17,8 @@ from .util import datetime_now
|
||||
class ZfsNode(ExecuteNode):
|
||||
"""a node that contains zfs datasets. implements global (systemwide/pool wide) zfs commands"""
|
||||
|
||||
def __init__(self, logger, utc=False, snapshot_time_format="", hold_name="", ssh_config=None, ssh_to=None, readonly=False,
|
||||
def __init__(self, logger, utc=False, snapshot_time_format="", hold_name="", ssh_config=None, ssh_to=None,
|
||||
readonly=False,
|
||||
description="",
|
||||
debug_output=False, thinner=None, exclude_snapshot_patterns=[]):
|
||||
|
||||
@ -30,6 +30,9 @@ class ZfsNode(ExecuteNode):
|
||||
|
||||
self.logger = logger
|
||||
|
||||
self.__supported_send_options = None
|
||||
self.__supported_recv_options = None
|
||||
|
||||
self.exclude_snapshot_patterns = exclude_snapshot_patterns
|
||||
|
||||
if ssh_config:
|
||||
@ -74,27 +77,30 @@ class ZfsNode(ExecuteNode):
|
||||
else:
|
||||
return (keep_snapshots, [])
|
||||
|
||||
@CachedProperty
|
||||
@property
|
||||
def supported_send_options(self):
|
||||
"""list of supported options, for optimizing sends"""
|
||||
# not every zfs implementation supports them all
|
||||
|
||||
ret = []
|
||||
for option in ["-L", "-e", "-c"]:
|
||||
if self.valid_command(["zfs", "send", option, "zfs_autobackup_option_test"]):
|
||||
ret.append(option)
|
||||
return ret
|
||||
if self.__supported_send_options is None:
|
||||
self.__supported_send_options = []
|
||||
for option in ["-L", "-e", "-c"]:
|
||||
if self.valid_command(["zfs", "send", option, "zfs_autobackup_option_test"]):
|
||||
self.__supported_send_options.append(option)
|
||||
return self.__supported_send_options
|
||||
|
||||
@CachedProperty
|
||||
@property
|
||||
def supported_recv_options(self):
|
||||
"""list of supported options"""
|
||||
# not every zfs implementation supports them all
|
||||
|
||||
ret = []
|
||||
for option in ["-s"]:
|
||||
if self.valid_command(["zfs", "recv", option, "zfs_autobackup_option_test"]):
|
||||
ret.append(option)
|
||||
return ret
|
||||
if self.__supported_recv_options is None:
|
||||
self.__supported_recv_options = []
|
||||
for option in ["-s"]:
|
||||
if self.valid_command(["zfs", "recv", option, "zfs_autobackup_option_test"]):
|
||||
self.__supported_recv_options.append(option)
|
||||
|
||||
return self.__supported_recv_options
|
||||
|
||||
def valid_command(self, cmd):
|
||||
"""test if a specified zfs options are valid exit code. use this to determine support options"""
|
||||
@ -129,13 +135,12 @@ class ZfsNode(ExecuteNode):
|
||||
|
||||
"""
|
||||
|
||||
ret=[]
|
||||
ret = []
|
||||
for name in names:
|
||||
ret.append(self.get_dataset(name, force_exists))
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
# def reset_progress(self):
|
||||
# """reset progress output counters"""
|
||||
# self._progress_total_bytes = 0
|
||||
@ -275,7 +280,6 @@ class ZfsNode(ExecuteNode):
|
||||
property_name
|
||||
])
|
||||
|
||||
|
||||
# The returnlist of selected ZfsDataset's:
|
||||
selected_filesystems = []
|
||||
excluded_filesystems = []
|
||||
@ -298,14 +302,14 @@ class ZfsNode(ExecuteNode):
|
||||
source = raw_source
|
||||
|
||||
# determine it
|
||||
selected=dataset.is_selected(value=value, source=source, inherited=inherited, exclude_received=exclude_received,
|
||||
exclude_paths=exclude_paths, exclude_unchanged=exclude_unchanged)
|
||||
selected = dataset.is_selected(value=value, source=source, inherited=inherited,
|
||||
exclude_received=exclude_received,
|
||||
exclude_paths=exclude_paths, exclude_unchanged=exclude_unchanged)
|
||||
|
||||
if selected==True:
|
||||
if selected == True:
|
||||
selected_filesystems.append(dataset)
|
||||
elif selected==False:
|
||||
elif selected == False:
|
||||
excluded_filesystems.append(dataset)
|
||||
#returns None when no property is set.
|
||||
# returns None when no property is set.
|
||||
|
||||
|
||||
return ( selected_filesystems, excluded_filesystems)
|
||||
return (selected_filesystems, excluded_filesystems)
|
||||
|
@ -1,6 +1,3 @@
|
||||
from .CachedProperty import CachedProperty
|
||||
|
||||
|
||||
class ZfsPool():
|
||||
"""a zfs pool"""
|
||||
|
||||
@ -10,6 +7,10 @@ class ZfsPool():
|
||||
|
||||
self.zfs_node = zfs_node
|
||||
self.name = name
|
||||
self.__properties = None
|
||||
|
||||
def invalidate_cache(self):
|
||||
self.__properties = None
|
||||
|
||||
def __repr__(self):
|
||||
return "{}: {}".format(self.zfs_node, self.name)
|
||||
@ -32,22 +33,24 @@ class ZfsPool():
|
||||
def debug(self, txt):
|
||||
self.zfs_node.debug("zpool {}: {}".format(self.name, txt))
|
||||
|
||||
@CachedProperty
|
||||
@property
|
||||
def properties(self):
|
||||
"""all zpool properties"""
|
||||
|
||||
self.debug("Getting zpool properties")
|
||||
if self.__properties is None:
|
||||
|
||||
cmd = [
|
||||
"zpool", "get", "-H", "-p", "all", self.name
|
||||
]
|
||||
self.debug("Getting zpool properties")
|
||||
|
||||
ret = {}
|
||||
cmd = [
|
||||
"zpool", "get", "-H", "-p", "all", self.name
|
||||
]
|
||||
|
||||
for pair in self.zfs_node.run(tab_split=True, cmd=cmd, readonly=True, valid_exitcodes=[0]):
|
||||
ret[pair[1]] = pair[2]
|
||||
self.__properties = {}
|
||||
|
||||
return ret
|
||||
for pair in self.zfs_node.run(tab_split=True, cmd=cmd, readonly=True, valid_exitcodes=[0]):
|
||||
self.__properties[pair[1]] = pair[2]
|
||||
|
||||
return self.__properties
|
||||
|
||||
@property
|
||||
def features(self):
|
||||
|
Loading…
x
Reference in New Issue
Block a user