[utils/ldapcertfs] Fonction wrappant les appels à ldap

Cache + gestion d'exception
This commit is contained in:
Valentin Samir 2014-10-26 02:13:53 +02:00
parent 55a3a56d65
commit 808a91a60b

View file

@ -44,6 +44,7 @@ import os
import sys
import ssl
import stat
import ldap
import time
import fuse
import errno
@ -59,7 +60,7 @@ fuse.fuse_python_api = (0, 2)
import logging
LOG_FILENAME = 'ldapcertfs.log'
logging.basicConfig(filename=LOG_FILENAME,level=logging.DEBUG)
logging.basicConfig(filename=LOG_FILENAME,level=logging.WARNING)
CACHE = {}
@ -81,7 +82,7 @@ def get_from_cache(key, now=None, expire=CACHE_TIMEOUT):
now = time.time()
if key in CACHE:
(ts, v) = CACHE[key]
if now - ts < expire:
if now - ts < expire or expire < 0:
return v
else:
raise ValueError("Expired")
@ -172,13 +173,39 @@ class LdapCertFS(fuse.Fuse):
self._storage = {}
self.passphrase = {}
def search_cache(self, filter, **kwargs):
def _func_cache(self, func, *args, **kwargs):
rec = kwargs.pop('rec', False)
kwargs_l = ["%s=%s" % kv for kv in kwargs.items()]
kwargs_l.sort()
serial = "%s(%s,%s)" % (func.__name__, ", ".join(args), ", ".join(kwargs_l))
try:
return get_from_cache(filter)
return get_from_cache(serial)
except ValueError:
objects = self.conn.search(filter, **kwargs)
set_to_cache(filter, objects)
return objects
try:
objects = func(*args, **kwargs)
set_to_cache(serial, objects)
return objects
except ldap.SERVER_DOWN:
try:
self.conn = lc_ldap.shortcuts.lc_ldap_readonly()
if not rec:
logger.warning("[ldapcertfs] ldap down, retrying")
kwargs['rec'] = rec
self.func_cache(func, *args, **kwargs)
except Exception as e:
logger.error("[ldapcertfs] uncaught exception %r" % e)
# Si le serveur est down on essaye de fournir un ancienne valeur du cache
try:
return get_from_cache(serial, expire=-1)
except ValueError:
logger.critical("[ldapcertfs] fail to return a valid result, I will probably crash next to this")
return []
def search_cache(self, filter, **kwargs):
return self._func_cache(self.conn.search, filter, **kwargs)
def get_local_machines(self):
return self._func_cache(self.conn.get_local_machines)
def make_root(self):
self._storage['/'] = Item(0755 | stat.S_IFDIR, self.uid, self.gid)
@ -187,7 +214,7 @@ class LdapCertFS(fuse.Fuse):
elif self.ldap_filter:
machines = self.search_cache("(&(%s)(mid=*))" % self.ldap_filter, sizelimit=8000)
else:
machines = self.conn.get_local_machines()
machines = self.get_local_machines()
for machine in machines:
if not machine.certificats():
continue