Exemplo n.º 1
0
 def __init__(self, root):
     ''''''
     super(ConfigurablePyFuseBox, self).__init__(root, None)
     self.virtual_file = VirtualConfigFile(self.VIRTUAL_CONFIG_FILE, self)
     self.store_initialized = False
     self.logger.debug("initialized configurable pyfusebox")
     # public variable to trigger profiling in modules interactively (i.e. StoreSyncThread)
     self.do_profiling = False
 def __init__(self, root):
     ''''''
     super( ConfigurablePyFuseBox, self ).__init__(root, None)
     self.virtual_file = VirtualConfigFile(self.VIRTUAL_CONFIG_FILE, self)
     self.store_initialized = False
     self.logger.debug("initialized configurable pyfusebox")
     # public variable to trigger profiling in modules interactively (i.e. StoreSyncThread)
     self.do_profiling = False  
Exemplo n.º 3
0
class ConfigurablePyFuseBox(PyFuseBox):
    '''Offers a virtual configuration file, to configure Cloudfusion at runtime.
    To better separate the data from the configuration directory, data can be accessed in the 
    top level directory data, and the configuration file can be accessed in the top level
    directory config.  
    '''
    VIRTUAL_CONFIG_FILE = '/config/config'
    DATA_FOLDER_PATH = "/data"

    def __init__(self, root):
        ''''''
        super(ConfigurablePyFuseBox, self).__init__(root, None)
        self.virtual_file = VirtualConfigFile(self.VIRTUAL_CONFIG_FILE, self)
        self.store_initialized = False
        self.logger.debug("initialized configurable pyfusebox")
        # public variable to trigger profiling in modules interactively (i.e. StoreSyncThread)
        self.do_profiling = False

    def enable_logging(self):
        if not os.path.exists(".cloudfusion/logs"):
            os.makedirs(".cloudfusion/logs")
        logging.config.fileConfig(
            os.path.dirname(cloudfusion.__file__) + '/config/logging.conf')
        db_logging_thread.start()  #.handlers = []
        logging.disable(logging.NOTSET)

    def disable_logging(self):
        logging.disable(logging.CRITICAL)
        db_logging_thread.stop()

    def _getattr_for_folder_with_full_access(self):
        st = zstat()
        st['st_mode'] = 0777 | stat.S_IFDIR
        st['st_nlink'] = 2
        st['st_size'] = 4096
        st['st_blocks'] = (int)((st['st_size'] + 4095L) / 4096L)
        return st

    def getattr(self, path, fh=None):
        self.logger.debug("getattr %s", path)
        if path == "/":
            return self._getattr_for_folder_with_full_access()
        if path == self.virtual_file.get_path():
            return self.virtual_file.getattr()
        if self.virtual_file.get_subdir(path):
            return self._getattr_for_folder_with_full_access()
        if self.store_initialized and path.startswith(
                self.DATA_FOLDER_PATH +
                '/'):  #slash prevents getattr on /datata/x
            path = self.remove_data_folder_prefix(path)
            return super(ConfigurablePyFuseBox, self).getattr(path, fh)
        if path == self.DATA_FOLDER_PATH:
            return self._getattr_for_folder_with_full_access()
        raise FuseOSError(ENOENT)

    def truncate(self, path, length, fh=None):
        self.logger.debug("truncate %s to %s", path, length)
        if path == self.virtual_file.get_path():
            self.virtual_file.truncate()
            return 0
        if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH):
            path = self.remove_data_folder_prefix(path)
            return super(ConfigurablePyFuseBox,
                         self).truncate(path, length, fh)
        raise FuseOSError(ENOENT)

    def rmdir(self, path):
        self.logger.debug("rmdir %s", path)
        if path == self.DATA_FOLDER_PATH or path == self.virtual_file.get_dir(
        ):
            raise FuseOSError(EACCES)
        if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH):
            path = self.remove_data_folder_prefix(path)
            return super(ConfigurablePyFuseBox, self).rmdir(path)
        raise FuseOSError(ENOENT)

    def mkdir(self, path, mode):
        self.logger.debug("mkdir %s with mode: %s", path, mode)
        if path == self.DATA_FOLDER_PATH:
            raise FuseOSError(EEXIST)
        if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH):
            path = self.remove_data_folder_prefix(path)
            return super(ConfigurablePyFuseBox, self).mkdir(path, mode)
        raise FuseOSError(EACCES)

    def remove_data_folder_prefix(self, path):
        path = path[len(self.DATA_FOLDER_PATH):]
        if not path.startswith("/"):
            path = "/"
        return path

    def statfs(self, path):  #add size of vtf
        self.logger.debug("statfs %s", path)
        if self.store_initialized:
            path = self.remove_data_folder_prefix(path)
            return super(ConfigurablePyFuseBox, self).statfs(path)

    def rename(self, old, new):
        self.logger.debug("rename %s to %s", old, new)
        if old == self.virtual_file.get_path(
        ) and os.path.basename(new).startswith(
                '.fuse_hidden'
        ):  #rename to .fuse_hidden is like a remove (see: hard remove option in fuse manpage for details)
            print "shutdown"
            if sys.platform == "darwin":
                args = ["diskutil", "umount", self.root]
            elif "freebsd" in sys.platform:
                args = ["umount", "-l", self.root]
            else:
                args = ["fusermount", "-zu", self.root]
            import subprocess
            subprocess.Popen(args)
            sleep(5)  # Give CloudFusion some time to unmount.
            # If it does not work terminate it the hard way.
            os.kill(os.getpid(), signal.SIGINT)
        """if new == self.virtual_file.get_path():
            buf = 
            written_bytes =  self.virtual_file.write(buf, offset)
            if written_bytes >0: # configuration changed
                self._initialize_store()
            return written_bytes"""
        if old == self.DATA_FOLDER_PATH:
            raise FuseOSError(EACCES)
        if new == self.DATA_FOLDER_PATH:
            raise FuseOSError(EACCES)
        if self.store_initialized and old.startswith(
                self.DATA_FOLDER_PATH) and new.startswith(
                    self.DATA_FOLDER_PATH):
            old = self.remove_data_folder_prefix(old)
            new = self.remove_data_folder_prefix(new)
            return super(ConfigurablePyFuseBox, self).rename(old, new)
        raise FuseOSError(EACCES)

    def create(self, path, mode):
        self.logger.debug("create %s with mode %s", path, mode)
        if path == self.DATA_FOLDER_PATH:
            raise FuseOSError(EACCES)
        if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH):
            path = self.remove_data_folder_prefix(path)
            return super(ConfigurablePyFuseBox, self).create(path, mode)
        raise FuseOSError(EACCES)

    def unlink(self, path):
        if path == self.virtual_file.get_path():
            if sys.platform == "darwin":
                args = ["diskutil", "umount", self.root]
            elif "freebsd" in sys.platform:
                args = ["umount", "-l", self.root]
            else:
                args = ["fusermount", "-zu", self.root]
            import subprocess
            subprocess.Popen(args)
            sleep(5)  # Give CloudFusion some time to unmount.
            # If it does not work terminate it the hard way.
            os.kill(os.getpid(), signal.SIGINT)
        if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH):
            path = self.remove_data_folder_prefix(path)
            super(ConfigurablePyFuseBox, self).unlink(path)

    def read(self, path, size, offset, fh):
        #self.logger.debug("read %s", path)
        if path == self.virtual_file.get_path():
            return self.virtual_file.read(size, offset)
        if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH):
            path = self.remove_data_folder_prefix(path)
            return super(ConfigurablePyFuseBox,
                         self).read(path, size, offset, fh)

    def write(self, path, buf, offset, fh):
        #self.logger.debug("write %s ... starting with %s at %s - fh: %s", path, buf[0:10], offset, fh)
        if path == self.virtual_file.get_path():
            self.logger.debug("writing to virtual file %s", path)
            written_bytes = self.virtual_file.write(buf, offset)
            return written_bytes
        if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH):
            path = self.remove_data_folder_prefix(path)
            return super(ConfigurablePyFuseBox,
                         self).write(path, buf, offset, fh)
        return 0

    def flush(self, path, fh):
        self.logger.debug("flush %s - fh: %s", path, fh)
        if path == self.virtual_file.get_path():
            return 0
        if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH):
            path = self.remove_data_folder_prefix(path)
            return super(ConfigurablePyFuseBox, self).flush(path, fh)

    def release(self, path, fh):
        self.logger.debug("release %s - fh: %s", path, fh)
        if path == self.virtual_file.get_path():
            return 0
        if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH):
            path = self.remove_data_folder_prefix(path)
            return super(ConfigurablePyFuseBox, self).release(path, fh)

    def readdir(self, path, fh):
        self.logger.debug("readdir %s", path)
        directories = []
        if path == self.virtual_file.get_dir():  #add virtual file
            directories.append(self.virtual_file.get_name())
        if path == "/":  # add virtual folders
            directories.append(self.virtual_file.get_dir())
            directories.append(os.path.basename(self.DATA_FOLDER_PATH))
        elif self.store_initialized and path.startswith(self.DATA_FOLDER_PATH):
            path = self.remove_data_folder_prefix(path)
            directories += self.store.get_directory_listing(path)
        #self.logger.debug("readdir -> "+str(directories)+"")
        file_objects = [".", ".."]
        for file_object in directories:
            if file_object != "/":
                file_object = os.path.basename(file_object.encode('utf8'))
                file_objects.append(file_object)
        return file_objects
 def __init__(self, root):
     self.virtual_file = VirtualConfigFile(self.VIRTUAL_CONFIG_FILE)
     self.store_initialized = False
     self.logger = logging.getLogger('pyfusebox')
     self.logger.debug("initialized configurable pyfusebox")
     super( ConfigurablePyFuseBox, self ).__init__(root, None)
class ConfigurablePyFuseBox(FlushingPyFuseBox):
    VIRTUAL_CONFIG_FILE = '/config/config'
    DATA_FOLDER_PATH = "/data"
    def __init__(self, root):
        self.virtual_file = VirtualConfigFile(self.VIRTUAL_CONFIG_FILE)
        self.store_initialized = False
        self.logger = logging.getLogger('pyfusebox')
        self.logger.debug("initialized configurable pyfusebox")
        super( ConfigurablePyFuseBox, self ).__init__(root, None)
    
    def _getattr_for_folder_with_full_access(self):
        st = zstat()
        st['st_mode'] = 0777 | stat.S_IFDIR
        st['st_nlink']=2
        st['st_size'] = 4096
        st['st_blocks'] = (int) ((st['st_size'] + 4095L) / 4096L);
        return st;
    
    def getattr(self, path, fh=None):
        self.logger.debug("getattr "+path+"")
        if path == "/": 
            return self._getattr_for_folder_with_full_access();
        if path == self.virtual_file.get_path():
            return self.virtual_file.getattr()
        if self.virtual_file.get_subdir(path):
            return self._getattr_for_folder_with_full_access()
        if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH):
            path = self.remove_data_folder_prefix(path)
            return super( ConfigurablePyFuseBox, self ).getattr(path, fh)
        if path == self.DATA_FOLDER_PATH: 
            return self._getattr_for_folder_with_full_access();
        raise FuseOSError(ENOENT)
    
    def truncate(self, path, length, fh=None):
        self.logger.debug("truncate %s to %s" % (path, length))
        if path == self.virtual_file.get_path():
            self.virtual_file.truncate()
            return 0
        if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH):
            path = self.remove_data_folder_prefix(path)
            return super( ConfigurablePyFuseBox, self ).truncate(path, length, fh)
        raise FuseOSError(ENOENT)
    
    def rmdir(self, path):
        self.logger.debug("rmdir %s" % (path))
        if  path == self.DATA_FOLDER_PATH or path == self.virtual_file.get_dir():
            raise FuseOSError(EACCES)             
        if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH):
            path = self.remove_data_folder_prefix(path)
            return super( ConfigurablePyFuseBox, self ).rmdir(path)
        raise FuseOSError(ENOENT)
        
    def mkdir(self, path, mode):
        self.logger.debug("mkdir %s with mode: %s" % (path, str(mode)))
        if path == self.DATA_FOLDER_PATH: 
            raise FuseOSError(EEXIST) 
        if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH):
            path = self.remove_data_folder_prefix(path)
            return super( ConfigurablePyFuseBox, self ).mkdir(path, mode)
        raise FuseOSError(EACCES) 
            
    def remove_data_folder_prefix(self, path):
        path = path[len(self.DATA_FOLDER_PATH):]
        if not path.startswith("/"):
            path = "/"
        return path
    
    def statfs(self, path):#add size of vtf
        self.logger.debug("statfs %s" % (path))
        if self.store_initialized:
            path = self.remove_data_folder_prefix(path)
            return super( ConfigurablePyFuseBox, self ).statfs(path)
    
    def rename(self, old, new):
        self.logger.debug("rename %s to %s" % (old, new))
        """if new == self.virtual_file.get_path():
            buf = 
            written_bytes =  self.virtual_file.write(buf, offset)
            if written_bytes >0: # configuration changed
                self._initialize_store()
            return written_bytes"""
        if old == self.DATA_FOLDER_PATH: 
            raise FuseOSError(EACCES) 
        if new == self.DATA_FOLDER_PATH: 
            raise FuseOSError(EACCES) 
        if self.store_initialized and old.startswith(self.DATA_FOLDER_PATH)  and new.startswith(self.DATA_FOLDER_PATH):
            old = self.remove_data_folder_prefix(old)
            new = self.remove_data_folder_prefix(new)
            return super( ConfigurablePyFuseBox, self ).rename(old, new)
        raise FuseOSError(EACCES) 

    def create(self, path, mode):
        self.logger.debug("create %s with mode %s" % (path, str(mode)))
        if path == self.DATA_FOLDER_PATH : 
            raise FuseOSError(EACCES) 
        if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH):
            path = self.remove_data_folder_prefix(path)
            return super( ConfigurablePyFuseBox, self ).create(path, mode)
        raise FuseOSError(EACCES) 
    
    def unlink(self, path):
        if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH):
            path = self.remove_data_folder_prefix(path)
            super( ConfigurablePyFuseBox, self ).unlink(path)

    def read(self, path, size, offset, fh):
        self.logger.debug("read %s" % path)
        if path == self.virtual_file.get_path():
            return self.virtual_file.read(size, offset)
        if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH):
            path = self.remove_data_folder_prefix(path)
            return super( ConfigurablePyFuseBox, self ).read(path, size, offset, fh)

    def _initialize_store(self):
        self.logger.debug("_initialize_store:")
        conf = self.virtual_file.get_store_config_data()
        service = conf['name']
        self.logger.debug("got service name")
        cache_time = 0
        metadata_cache_time = 0
        if 'cache' in conf:
            cache_time = int(conf['cache']) 
        if 'metadata_cache' in conf:
            metadata_cache_time = int(conf['metadata_cache']) 
        self.logger.debug("got cache parameter")
        auth = self.virtual_file.get_service_auth_data()
        self.logger.debug("got auth data: "+str(auth))
        store = self.__get_new_store(service, auth) #catch error?
        self.logger.debug("initialized store")
        if cache_time > 0 and metadata_cache_time > 0:
            store = MetadataCachingStore( CachingStore( MetadataCachingStore( store, metadata_cache_time ), cache_time ), metadata_cache_time )
            self.set_cache_expiration_time(cache_time)
            super( ConfigurablePyFuseBox, self ).start_cyclic_flushing()
        elif cache_time > 0:
            store = CachingStore(store, cache_time)
            self.set_cache_expiration_time(cache_time)
            super( ConfigurablePyFuseBox, self ).start_cyclic_flushing()
        elif metadata_cache_time > 0:
            store = MetadataCachingStore( store, metadata_cache_time )
            super( ConfigurablePyFuseBox, self ).start_cyclic_flushing()
        self.store = store
        self.logger.debug("initialized service")
        self.store_initialized = True
        
    def __get_new_store(self, service, auth):
        self.logger.debug("__get_new_store:")
        if service.lower() == "sugarsync":
            store = SugarsyncStore(auth)
        elif service.lower() == "mangafuse":
            store = MangaStore(auth)
        else: # default
            self.logger.debug("get dropbox store")
            try:
                store = DropboxStore(auth)
            except Exception as e:
                self.logger.debug(str(e))
            self.logger.debug("got dropbox store")
        return store
    
    def write(self, path, buf, offset, fh):
        self.logger.debug("write %s ... starting with %s at %s - fh: %s" % (path, buf[0:10], offset, fh))
        if path == self.virtual_file.get_path():
            self.logger.debug("writing to virtual file "+path)
            written_bytes = self.virtual_file.write(buf, offset)
            self.logger.debug("written bytes:"+str(written_bytes))
            if written_bytes >0: # configuration changed
                self._initialize_store()
            return written_bytes
        if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH):
            path = self.remove_data_folder_prefix(path)
            return super( ConfigurablePyFuseBox, self ).write(path, buf, offset, fh)
        return 0
    
    def flush(self, path, fh):
        self.logger.debug("flush %s - fh: %s" % (path, fh))
        if path == self.virtual_file.get_path():
            return 0
        if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH):
            path = self.remove_data_folder_prefix(path)
            return super( ConfigurablePyFuseBox, self ).flush(path, fh)
    
    def release(self, path, fh):
        self.logger.debug("release %s - fh: %s" % (path, fh))
        if path == self.virtual_file.get_path():
            return 0
        if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH):
            path = self.remove_data_folder_prefix(path)
            return super( ConfigurablePyFuseBox, self ).release(path, fh) 
       
    def readdir(self, path, fh):
        self.logger.debug("readdir "+path+"")
        directories = []
        if path == self.virtual_file.get_dir(): #add virtual file
            directories.append(self.virtual_file.get_name())
        if path == "/":# add virtual folders
            directories.append(self.virtual_file.get_dir())
            directories.append(os.path.basename(self.DATA_FOLDER_PATH))
        elif self.store_initialized and path.startswith(self.DATA_FOLDER_PATH):
            path = self.remove_data_folder_prefix(path)
            directories += self.store.get_directory_listing(path)
        #self.logger.debug("readdir -> "+str(directories)+"")
        file_objects = [".", ".."]
        for file_object in directories:
            if file_object != "/":
                file_object = os.path.basename(file_object.encode('utf8'))
                file_objects.append( file_object )
        return file_objects;
class ConfigurablePyFuseBox(PyFuseBox):
    '''Offers a virtual configuration file, to configure Cloudfusion at runtime.
    To better separate the data from the configuration directory, data can be accessed in the 
    top level directory data, and the configuration file can be accessed in the top level
    directory config.  
    '''
    VIRTUAL_CONFIG_FILE = '/config/config'
    DATA_FOLDER_PATH = "/data"
    
    def __init__(self, root):
        ''''''
        super( ConfigurablePyFuseBox, self ).__init__(root, None)
        self.virtual_file = VirtualConfigFile(self.VIRTUAL_CONFIG_FILE, self)
        self.store_initialized = False
        self.logger.debug("initialized configurable pyfusebox")
        # public variable to trigger profiling in modules interactively (i.e. StoreSyncThread)
        self.do_profiling = False  
    
    def enable_logging(self):
        if not os.path.exists(".cloudfusion/logs"):
            os.makedirs(".cloudfusion/logs")
        logging.config.fileConfig(os.path.dirname(cloudfusion.__file__)+'/config/logging.conf')
        db_logging_thread.start()    #.handlers = []
        logging.disable(logging.NOTSET)
        
    def disable_logging(self):
        logging.disable(logging.CRITICAL)
        db_logging_thread.stop()
    
    def _getattr_for_folder_with_full_access(self):
        st = zstat()
        st['st_mode'] = 0777 | stat.S_IFDIR
        st['st_nlink']=2
        st['st_size'] = 4096
        st['st_blocks'] = (int) ((st['st_size'] + 4095L) / 4096L)
        return st
    
    def getattr(self, path, fh=None):
        self.logger.debug("getattr %s", path)
        if path == "/": 
            return self._getattr_for_folder_with_full_access()
        if path == self.virtual_file.get_path():
            return self.virtual_file.getattr()
        if self.virtual_file.get_subdir(path):
            return self._getattr_for_folder_with_full_access()
        if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH+'/'): #slash prevents getattr on /datata/x
            path = self.remove_data_folder_prefix(path)
            return super( ConfigurablePyFuseBox, self ).getattr(path, fh)
        if path == self.DATA_FOLDER_PATH: 
            return self._getattr_for_folder_with_full_access()
        raise FuseOSError(ENOENT)
    
    def truncate(self, path, length, fh=None):
        self.logger.debug("truncate %s to %s", path, length)
        if path == self.virtual_file.get_path():
            self.virtual_file.truncate()
            return 0
        if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH):
            path = self.remove_data_folder_prefix(path)
            return super( ConfigurablePyFuseBox, self ).truncate(path, length, fh)
        raise FuseOSError(ENOENT)
    
    def rmdir(self, path):
        self.logger.debug("rmdir %s", path)
        if  path == self.DATA_FOLDER_PATH or path == self.virtual_file.get_dir():
            raise FuseOSError(EACCES)             
        if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH):
            path = self.remove_data_folder_prefix(path)
            return super( ConfigurablePyFuseBox, self ).rmdir(path)
        raise FuseOSError(ENOENT)
        
    def mkdir(self, path, mode):
        self.logger.debug("mkdir %s with mode: %s", path, mode)
        if path == self.DATA_FOLDER_PATH: 
            raise FuseOSError(EEXIST) 
        if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH):
            path = self.remove_data_folder_prefix(path)
            return super( ConfigurablePyFuseBox, self ).mkdir(path, mode)
        raise FuseOSError(EACCES) 
            
    def remove_data_folder_prefix(self, path):
        path = path[len(self.DATA_FOLDER_PATH):]
        if not path.startswith("/"):
            path = "/"
        return path
    
    def statfs(self, path):#add size of vtf
        self.logger.debug("statfs %s", path)
        if self.store_initialized:
            path = self.remove_data_folder_prefix(path)
            return super( ConfigurablePyFuseBox, self ).statfs(path)
    
    def rename(self, old, new):
        self.logger.debug("rename %s to %s", old, new)
        if old == self.virtual_file.get_path() and os.path.basename(new).startswith('.fuse_hidden'): #rename to .fuse_hidden is like a remove (see: hard remove option in fuse manpage for details)
            print "shutdown"
            if sys.platform == "darwin":
                args = ["diskutil", "umount", self.root]
            elif "freebsd" in sys.platform:
                args = ["umount", "-l", self.root]
            else:
                args = ["fusermount", "-zu", self.root]
            import subprocess
            subprocess.Popen(args)
            sleep(5) # Give CloudFusion some time to unmount.
            # If it does not work terminate it the hard way.
            os.kill(os.getpid(), signal.SIGINT)
        """if new == self.virtual_file.get_path():
            buf = 
            written_bytes =  self.virtual_file.write(buf, offset)
            if written_bytes >0: # configuration changed
                self._initialize_store()
            return written_bytes"""
        if old == self.DATA_FOLDER_PATH: 
            raise FuseOSError(EACCES) 
        if new == self.DATA_FOLDER_PATH: 
            raise FuseOSError(EACCES) 
        if self.store_initialized and old.startswith(self.DATA_FOLDER_PATH)  and new.startswith(self.DATA_FOLDER_PATH):
            old = self.remove_data_folder_prefix(old)
            new = self.remove_data_folder_prefix(new)
            return super( ConfigurablePyFuseBox, self ).rename(old, new)
        raise FuseOSError(EACCES) 

    def create(self, path, mode):
        self.logger.debug("create %s with mode %s", path, mode)
        if path == self.DATA_FOLDER_PATH : 
            raise FuseOSError(EACCES) 
        if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH):
            path = self.remove_data_folder_prefix(path)
            return super( ConfigurablePyFuseBox, self ).create(path, mode)
        raise FuseOSError(EACCES) 

    def unlink(self, path):
        if path == self.virtual_file.get_path():    
            if sys.platform == "darwin":
                args = ["diskutil", "umount", self.root]
            elif "freebsd" in sys.platform:
                args = ["umount", "-l", self.root]
            else:
                args = ["fusermount", "-zu", self.root]
            import subprocess
            subprocess.Popen(args)
            sleep(5) # Give CloudFusion some time to unmount.
            # If it does not work terminate it the hard way.
            os.kill(os.getpid(), signal.SIGINT)
        if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH):
            path = self.remove_data_folder_prefix(path)
            super( ConfigurablePyFuseBox, self ).unlink(path)

    def read(self, path, size, offset, fh):
        #self.logger.debug("read %s", path)
        if path == self.virtual_file.get_path():
            return self.virtual_file.read(size, offset)
        if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH):
            path = self.remove_data_folder_prefix(path)
            return super( ConfigurablePyFuseBox, self ).read(path, size, offset, fh)

    def write(self, path, buf, offset, fh):
        #self.logger.debug("write %s ... starting with %s at %s - fh: %s", path, buf[0:10], offset, fh)
        if path == self.virtual_file.get_path():
            self.logger.debug("writing to virtual file %s", path)
            written_bytes = self.virtual_file.write(buf, offset)
            return written_bytes
        if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH):
            path = self.remove_data_folder_prefix(path)
            return super( ConfigurablePyFuseBox, self ).write(path, buf, offset, fh)
        return 0
    
    def flush(self, path, fh):
        self.logger.debug("flush %s - fh: %s", path, fh)
        if path == self.virtual_file.get_path():
            return 0
        if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH):
            path = self.remove_data_folder_prefix(path)
            return super( ConfigurablePyFuseBox, self ).flush(path, fh)
    
    def release(self, path, fh):
        self.logger.debug("release %s - fh: %s", path, fh)
        if path == self.virtual_file.get_path():
            return 0
        if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH):
            path = self.remove_data_folder_prefix(path)
            return super( ConfigurablePyFuseBox, self ).release(path, fh) 
       
    def readdir(self, path, fh):
        self.logger.debug("readdir %s", path)
        directories = []
        if path == self.virtual_file.get_dir(): #add virtual file
            directories.append(self.virtual_file.get_name())
        if path == "/":# add virtual folders
            directories.append(self.virtual_file.get_dir())
            directories.append(os.path.basename(self.DATA_FOLDER_PATH))
        elif self.store_initialized and path.startswith(self.DATA_FOLDER_PATH):
            path = self.remove_data_folder_prefix(path)
            directories += self.store.get_directory_listing(path)
        #self.logger.debug("readdir -> "+str(directories)+"")
        file_objects = [".", ".."]
        for file_object in directories:
            if file_object != "/":
                file_object = os.path.basename(file_object.encode('utf8'))
                file_objects.append( file_object )
        return file_objects