#!/usr/bin/python import osc import osc.conf import osc.core import sys import fuse from fuse import Fuse import stat import os import errno import tempfile fuse.fuse_python_api = (0, 2) projects = [] cache = {} class EmptyStat(fuse.Stat): def __init__(self): self.st_mode = 0 self.st_ino = 0 self.st_dev = 0 self.st_nlink = 0 self.st_uid = 0 self.st_gid = 0 self.st_size = 0 self.st_atime = 0 self.st_mtime = 0 self.st_ctime = 0 class CacheEntry(object): def __init__(self): self.stat = None self.handle = None self.tmpname = None class oscFS(Fuse): def __init__(self, *args, **kw): Fuse.__init__(self, *args, **kw) print 'OK' def getattr(self, path): st = EmptyStat() # path is project if path == '/' or path in projects or len(filter(lambda x: x.startswith(path), projects)) > 0: st.st_mode = stat.S_IFDIR | 0555 st.st_nlink = 2 return st # path is package if os.path.dirname(path) in projects: st.st_mode = stat.S_IFDIR | 0555 st.st_nlink = 2 return st # path is file if cache.has_key(path): return cache[path].stat else: return -errno.ENOENT def readdir(self, path, offset): yield fuse.Direntry('.') yield fuse.Direntry('..') if os.path.dirname(path) in projects: # path is package prj = os.path.dirname(path).replace('/','') pkg = os.path.basename(path) for f in osc.core.meta_get_filelist(osc.conf.config['apiurl'], prj, pkg, verbose=True): st = EmptyStat() st.st_mode = stat.S_IFREG | 0444 st.st_size = f.size st.st_atime = f.mtime st.st_ctime = f.mtime st.st_mtime = f.mtime cache[path + '/' + f.name] = CacheEntry() cache[path + '/' + f.name].stat = st yield fuse.Direntry(f.name) return if path in projects: # path is project prj = path.replace('/','') for p in osc.core.meta_get_packagelist(osc.conf.config['apiurl'], prj): yield fuse.Direntry(p) else: # path is project structure if (path != '/'): path += '/' l = len(path) for d in set( map(lambda x: x[l:].split('/')[0], filter(lambda x: x.startswith(path), projects) ) ) : yield fuse.Direntry(d) def mythread ( self ): print '*** mythread' return -errno.ENOSYS def chmod ( self, path, mode ): print '*** chmod', path, oct(mode) return -errno.ENOSYS def chown ( self, path, uid, gid ): print '*** chown', path, uid, gid return -errno.ENOSYS def fsync ( self, path, isFsyncFile ): print '*** fsync', path, isFsyncFile return -errno.ENOSYS def link ( self, targetPath, linkPath ): print '*** link', targetPath, linkPath return -errno.ENOSYS def mkdir ( self, path, mode ): print '*** mkdir', path, oct(mode) return -errno.ENOSYS def mknod ( self, path, mode, dev ): print '*** mknod', path, oct(mode), dev return -errno.ENOSYS def open ( self, path, flags ): file = os.path.basename(path) d = os.path.dirname(path) pkg = os.path.basename(d) prj = os.path.dirname(d).replace('/','') if not cache.has_key(path): return -errno.ENOENT if cache[path].stat == None: return -errno.ENOENT tmp = tempfile.mktemp(prefix = 'oscfs_') osc.core.get_source_file(osc.conf.config['apiurl'], prj, pkg, file, tmp) cache[path].handle = open(tmp, 'r') cache[path].tmpname = tmp def read ( self, path, length, offset ): if not cache.has_key(path): return -errno.EACCES f = cache[path].handle f.seek(offset) return f.read(length) def readlink ( self, path ): print '*** readlink', path return -errno.ENOSYS def release ( self, path, flags ): if cache.has_key(path): cache[path].handle.close() cache[path].handle = None os.unlink(f.cache[path].tmpname) cache[path].tmpname = None def rename ( self, oldPath, newPath ): print '*** rename', oldPath, newPath return -errno.ENOSYS def rmdir ( self, path ): print '*** rmdir', path return -errno.ENOSYS def statfs ( self ): print '*** statfs' return -errno.ENOSYS def symlink ( self, targetPath, linkPath ): print '*** symlink', targetPath, linkPath return -errno.ENOSYS def truncate ( self, path, size ): print '*** truncate', path, size return -errno.ENOSYS def unlink ( self, path ): print '*** unlink', path return -errno.ENOSYS def utime ( self, path, times ): print '*** utime', path, times return -errno.ENOSYS def write ( self, path, buf, offset ): print '*** write', path, buf, offset return -errno.ENOSYS def fill_projects(): for prj in osc.core.meta_get_project_list(osc.conf.config['apiurl']): projects.append( '/' + prj.replace(':', ':/') ) if __name__ == '__main__': print 'Loading config ...', osc.conf.get_config() print 'OK' print 'Getting projects list ...', fill_projects() print 'OK' print 'Starting FUSE ...', oscfs = oscFS( version = '%prog ' + fuse.__version__, usage = '', dash_s_do = 'setsingle') oscfs.flags = 0 oscfs.multithreaded = 0 oscfs.parse(values = oscfs, errex = 1) oscfs.main()