diff --git a/kubefuse/cache.py b/kubefuse/cache.py index 1c71feb..0b6fbd8 100644 --- a/kubefuse/cache.py +++ b/kubefuse/cache.py @@ -25,5 +25,8 @@ def get(self, key): return None def delete(self, key): - del(self._timestamps[key]) - del(self._cache[key]) + try: + del(self._timestamps[key]) + del(self._cache[key]) + except KeyError: + pass diff --git a/kubefuse/client.py b/kubefuse/client.py index 07f351f..34aa20d 100644 --- a/kubefuse/client.py +++ b/kubefuse/client.py @@ -1,9 +1,12 @@ +import logging import subprocess import yaml import tempfile from cache import ExpiringCache +LOGGER = logging.getLogger(__name__) + class KubernetesClient(object): def __init__(self): self._cache = ExpiringCache(30) @@ -24,17 +27,31 @@ def _load_from_cache_or_do(self, key, func): result = func() self._cache.set(key, result) return result - + def get_namespaces(self): key = "namespaces" cb = self._get_namespaces return self._load_from_cache_or_do(key, cb) + def delete_namespace(self, namespace): + LOGGER.info(self._run_command(('delete namespace ' + namespace).split())) + self._cache.delete('namespaces') + def get_entities(self, ns, entity): key = "%s.%s" % (ns, entity) cb = lambda: self._get_entities(ns,entity) return self._load_from_cache_or_do(key, cb) + def delete_entities(self, ns, entity_type): + key = "%s.%s" % (ns, entity_type) + LOGGER.info(self._run_command(("delete %s --all " % entity_type).split() + self._namespace(ns))) + self._cache.delete(key) + + def delete_entity(self, ns, entity_type, object_name): + key = "%s.%s" % (ns, entity_type) + LOGGER.info(self._run_command(("delete %s %s " % (entity_type, object_name)).split() + self._namespace(ns))) + self._cache.delete(key) + def get_object_in_format(self, ns, entity_type, object, format): key = "%s.%s.%s.%s" % (ns, entity_type, object, format) cb = lambda: self._get_object_in_format(ns, entity_type, object, format) diff --git a/kubefuse/filesystem.py b/kubefuse/filesystem.py index 929e943..4599e5b 100644 --- a/kubefuse/filesystem.py +++ b/kubefuse/filesystem.py @@ -83,6 +83,37 @@ def list_files(self, path): return p.SUPPORTED_RESOURCE_TYPES return self.client.get_namespaces() # + ['all'] + def rmdir(self, path): + p = KubePath().parse_path(path) + if not p.exists(self.client): + logging.info("path doesn't exist") + raise FuseOSError(errno.ENOENT) + if not p.is_dir(): + logging.info("not a directory") + raise FuseOSError(errno.ENOTDIR) + + if p.action: + raise FuseOSError(errno.EROFS) + if p.object_id: + return self.client.delete_entity(p.namespace, p.resource_type, p.object_id) + if p.resource_type: + return self.client.delete_entities(p.namespace, p.resource_type) + if p.namespace: + return self.client.delete_namespace(p.namespace) + raise FuseOSError(errno.EROFS) + + def unlink(self, path): + p = KubePath().parse_path(path) + if not p.exists(self.client): + logging.info("path doesn't exist") + raise FuseOSError(errno.ENOENT) + if p.is_dir(): + logging.info("is a directory") + raise FuseOSError(errno.EISDIR) + # We just let unlinks succeed, though the files will remain + # This is for compatibility with `rm -rf` - though just using rmdir + # will have the same effect in this implementation + def getattr(self, path): p = KubePath().parse_path(path) if path in self.open_files: diff --git a/kubefuse/kubefuse.py b/kubefuse/kubefuse.py index 45375c5..312d27a 100644 --- a/kubefuse/kubefuse.py +++ b/kubefuse/kubefuse.py @@ -25,6 +25,12 @@ def readdir(self, path, fh): def getattr(self, path, fh=None): return self.fs.getattr(path) + def rmdir(self, path): + return self.fs.rmdir(path) + + def unlink(self, path): + return self.fs.unlink(path) + def open(self, path, fh): self.fd += 1 self.fs.open(path, fh)