Exemple #1
0
class MooseFS(object):
    def __init__(self, host='mfsmaster', port=9421):
        self.host = host
        self.mc = MasterConn(host, port)
        self.inode_cache = {}

    def _lookup(self, parent, name):
        cache = self.inode_cache.setdefault(parent, {})
        info = cache.get(name)
        if info is not None:
            return info
        
        info, err = self.mc.lookup(parent, name)
        if info is not None:
            cache[name] = info
        return info

    def lookup(self, path, followSymlink=True):
        parent = MFS_ROOT_INODE
        info = None
        ps = path.split('/')
        for i, n in enumerate(ps):
            if not n: continue
            info = self._lookup(parent, n)
            if not info:
                return
            if info.is_symlink() and followSymlink:
                target = self.mc.readlink(info.inode)
                if not target.startswith('/'):
                    target = os.path.join('/'.join(ps[:i]),
                        target)
                return self.lookup(target, True)
            parent = info.inode
        if info is None and parent == MFS_ROOT_INODE:
            info = self.mc.getattr(parent)
        return info

    def open(self, path):
        info = self.lookup(path)
        if not info:
            raise Exception("not found")
        return File(info.inode, path, info, self.host)

    def listdir(self, path):
        info = self.lookup(path)
        if not info:
            raise Exception("not found")
        files = self.mc.getdirplus(info.inode)
        for i in files.values():
            self.inode_cache.setdefault(info.inode, {})[i.name] = i
        return files

    def close(self):
        self.mc.close()
Exemple #2
0
class MooseFS(object):
    def __init__(self, host='mfsmaster', port=9421):
        self.host = host
        self.mc = MasterConn(host, port)
        self.inode_cache = {}

    def _lookup(self, parent, name):
        cache = self.inode_cache.setdefault(parent, {})
        info = cache.get(name)
        if info is not None:
            return info

        info, err = self.mc.lookup(parent, name)
        if info is not None:
            cache[name] = info
        return info

    def lookup(self, path, followSymlink=True):
        parent = MFS_ROOT_INODE
        info = None
        ps = path.split('/')
        for i, n in enumerate(ps):
            if not n: continue
            info = self._lookup(parent, n)
            if not info:
                return
            if info.is_symlink() and followSymlink:
                target = self.mc.readlink(info.inode)
                if not target.startswith('/'):
                    target = os.path.join('/'.join(ps[:i]), target)
                return self.lookup(target, True)
            parent = info.inode
        if info is None and parent == MFS_ROOT_INODE:
            info = self.mc.getattr(parent)
        return info

    def open(self, path):
        info = self.lookup(path)
        if not info:
            raise Exception("not found")
        return File(info.inode, path, info, self.host)

    def listdir(self, path):
        info = self.lookup(path)
        if not info:
            raise Exception("not found")
        files = self.mc.getdirplus(info.inode)
        for i in files.values():
            self.inode_cache.setdefault(info.inode, {})[i.name] = i
        return files

    def close(self):
        self.mc.close()
Exemple #3
0
class MooseFS(object):
    def __init__(self, host='mfsmaster', port=9421, mountpoint='/mfs'):
        self.host = host
        self.mountpoint = mountpoint
        self.mc = MasterConn(host, port)
        self.symlink_cache = {}

    def _lookup(self, parent, name):
        return self.mc.lookup(parent, name)[0]

    def readlink(self, inode):
        target = self.symlink_cache.get(inode)
        if target is None:
            target = self.mc.readlink(inode)
            self.symlink_cache[inode] = target
        return target

    def lookup(self, path, followSymlink=True):
        parent = MFS_ROOT_INODE
        info = None
        ps = path.split('/')
        for i, n in enumerate(ps):
            if not n:
                continue
            info = self._lookup(parent, n)
            if not info:
                return
            while info.is_symlink() and followSymlink:
                target = self.readlink(info.inode)
                if not target.startswith('/'):
                    target = os.path.join('/'.join(ps[:i]), target)
                    info = self.lookup(target, followSymlink)
                elif target.startswith(self.mountpoint):
                    info = self.lookup(target[len(self.mountpoint):], followSymlink)
                else:
                    raise CrossSystemSymlink(path, os.path.join(target, *ps[i+1:]))
            parent = info.inode
        if info is None and parent == MFS_ROOT_INODE:
            info = self.mc.getattr(parent)
        return info

    def open(self, path):
        info = self.lookup(path)
        if not info:
            raise Exception("not found")
        return File(info.inode, path, info, self.host)

    def listdir(self, path):
        info = self.lookup(path)
        if not info:
            raise Exception("not found")
        return self.mc.getdirplus(info.inode)

    def walk(self, path, followlinks=False):
        ds = [path]
        while ds:
            root = ds.pop()
            cs = self.listdir(root)
            dirs, files = [], []
            for name, info in cs.iteritems():
                if name in '..':
                    continue
                while followlinks and info and info.type == TYPE_SYMLINK:
                    target = self.readlink(info.inode)
                    if target.startswith('/'):
                        if not target.startswith(self.mountpoint):
                            if os.path.exists(target):
                                if os.path.isdir(target):
                                    dirs.append(target)
                                else:
                                    files.append(target)
                            info = None  # ignore broken symlink
                            break
                        else:
                            target = target[len(self.mountpoint):]
                            # use relative path for internal symlinks
                            name = ('../' * len(filter(None, root.split('/')))) + target
                    else:
                        name = target
                        target = os.path.join(root, target)
                    info = self.lookup(target)

                if info:
                    if info.type == TYPE_DIRECTORY:
                        if name not in dirs:
                            dirs.append(name)
                    elif info.type == TYPE_FILE:
                        if name not in files:
                            files.append(name)

            yield root, dirs, files
            for d in sorted(dirs, reverse=True):
                if not d.startswith('/'):  # skip external links
                    ds.append(os.path.join(root, d))

    def close(self):
        self.mc.terminate()
Exemple #4
0
class MooseFS(object):
    def __init__(self, host='mfsmaster', port=9421, mountpoint='/mfs'):
        self.host = host
        self.mountpoint = mountpoint
        self.mc = MasterConn(host, port)
        self.inode_cache = {}
        self.symlink_cache = {}

    def _lookup(self, parent, name):
        cache = self.inode_cache.get(parent)
        if cache is None:
            cache = self.mc.getdirplus(parent)
            self.inode_cache[parent] = cache
        return cache.get(name)

    def readlink(self, inode):
        target = self.symlink_cache.get(inode)
        if target is None:
            target = self.mc.readlink(inode)
            self.symlink_cache[inode] = target
        return target

    def lookup(self, path, followSymlink=True):
        parent = MFS_ROOT_INODE
        info = None
        ps = path.split('/')
        for i, n in enumerate(ps):
            if not n: continue
            info = self._lookup(parent, n)
            if not info:
                return
            while info.is_symlink() and followSymlink:
                target = self.readlink(info.inode)
                if not target.startswith('/'):
                    target = os.path.join('/'.join(ps[:i]), target)
                    info = self.lookup(target, followSymlink)
                elif target.startswith(self.mountpoint):
                    info = self.lookup(target[len(self.mountpoint):],
                                       followSymlink)
                else:
                    raise CrossSystemSymlink(path,
                                             os.path.join(target, *ps[i + 1:]))
            parent = info.inode
        if info is None and parent == MFS_ROOT_INODE:
            info = self.mc.getattr(parent)
        return info

    def open(self, path):
        info = self.lookup(path)
        if not info:
            raise Exception("not found")
        return File(info.inode, path, info, self.host)

    def listdir(self, path):
        info = self.lookup(path)
        if not info:
            raise Exception("not found")
        files = self.inode_cache.get(info.inode)
        if files is None:
            files = self.mc.getdirplus(info.inode)
            self.inode_cache[info.inode] = files
        return files

    def walk(self, path, followlinks=False):
        ds = [path]
        while ds:
            root = ds.pop()
            cs = self.listdir(root)
            dirs, files = [], []
            for name, info in cs.iteritems():
                if name in '..': continue
                while followlinks and info and info.type == TYPE_SYMLINK:
                    target = self.readlink(info.inode)
                    if target.startswith('/'):
                        if not target.startswith(self.mountpoint):
                            if os.path.exists(target):
                                if os.path.isdir(target):
                                    dirs.append(target)
                                else:
                                    files.append(target)
                            info = None  # ignore broken symlink
                            break
                        else:
                            target = target[len(self.mountpoint):]
                            # use relative path for internal symlinks
                            name = ('../' * len(filter(
                                None, root.split('/')))) + target
                    else:
                        name = target
                        target = os.path.join(root, target)
                    info = self.lookup(target)

                if info:
                    if info.type == TYPE_DIRECTORY:
                        if name not in dirs:
                            dirs.append(name)
                    elif info.type == TYPE_FILE:
                        if name not in files:
                            files.append(name)

            yield root, dirs, files
            for d in sorted(dirs, reverse=True):
                if not d.startswith('/'):  # skip external links
                    ds.append(os.path.join(root, d))

    def close(self):
        self.mc.close()