コード例 #1
0
ファイル: cloudfs.py プロジェクト: sangla1/CloudFS
class CloudFS(LoggingMixIn, Operations):
	
	def __init__(self):
		# initialize file table
		self.maxFiles = 1024
#		self.files = [dict(path=None, dirty=False, data=None)] * self.maxFiles
		self.files = [None] * self.maxFiles
		for i in range(0, self.maxFiles):
			self.files[i] = dict(path=None, dirty=False, data=None)
		self.conn = Connector()
		
	def chmod(self, path, mode):
		# chmod is not allowed
		raise FuseOSError(EPERM)

	def chown(self, path, uid, gid):
		# chown is not allowed
		raise FuseOSError(EPERM)
	
	def create(self, path, mode):
		# create file
		paths = splitPath(path)
		print path, paths
		if paths[0] == '':
			raise FuseOSError(EPERM)

		# search available fd
		fd = None
		fdNum = -1
		for i in range(0, self.maxFiles):
			fd = self.files[i]
			print i
			if fd['path'] == None:
#				print "MATCH!!!"
#				print fdNum
				fdNum = i
				break

		if fd == None:
			raise FuseOSError(ENOENT)

		fd['path'] = path
		fd['dirty'] = True
		fd['data'] = ''

		paths = splitPath(path)
		self.conn.push(paths[0], paths[1], fd['data'])

		return fdNum
	
	def getattr(self, path, fh=None):
		now = time()
		paths = splitPath(path)
		# if root?
		if paths[0] == '':
			return dict(st_mode=(S_IFDIR | 0755), st_ctime=now, st_mtime=now, st_atime=now, st_nlink=2)

		attr = self.conn.getAttr(paths[0], paths[1])
		if attr != None:
			return attr
		else:
			raise FuseOSError(ENOENT)
	
	def getxattr(self, path, name, position=0):
		return ''

	def listxattr(self, path):
		raise FuseOSError(EPERM)
	
	def mkdir(self, path, mode):
		paths = splitPath(path)
		# mkdir is not allowed under root dir
		if paths[1] == '':
			raise FuseOSError(EPERM)
		if self.conn.mkdir(paths[0], paths[1]) != True:
			raise FuseOSError(EPERM)
	
	def open(self, path, flags):
		paths = splitPath(path)
		# cannot open files under root dir
		print path, paths
		if paths[0] == '':
			raise FuseOSError(EPERM)

		# cache file content from storage
		content = self.conn.pull(paths[0], paths[1])
		if paths[0] == None:
			raise FuseOSError(ENOENT)

		# search available file
		fd = None
		fdNum = -1		
		for i in range(0, self.maxFiles):
			fd = self.files[i]
			if fd['path'] == None:
				fdNum = i
				break

		if fd == None:
			raise FuseOSError(ENOENT)

		fd['path'] = path
		fd['dirty'] = False
		fd['data'] = content

		return fdNum
	
	def read(self, path, size, offset, fh):
		if self.files[fh]['path'] == None:
			raise FuseOSError(ENOENT)

		return self.files[fh]['data'][offset:offset + size]
	
	def readdir(self, path, fh):
		paths = splitPath(path)

		if paths[0] == '':
			dents = self.conn.getConns()
		else:
			dents = self.conn.getDents(paths[0], paths[1])

		return ['.', '..'] + dents
	
	def readlink(self, path):
		# readlink is not allowed
		raise FuseOSError(EPERM)
	
	def removexattr(self, path, name):
		raise FuseOSError(EPERM)
	
	def rename(self, old, new):
		# rename is not allowed
		raise FuseOSError(EPERM)
	
	def rmdir(self, path):
		paths = splitPath(path)

		# cannot remove mounted dir
		if paths[1] == '':
			raise FuseOSError(EPERM)
		if self.conn.rm(paths[0], paths[1]) != True:
			raise FuseOSError(ENOENT)
	
	def setxattr(self, path, name, value, options, position=0):
		raise FuseOSError(EPERM)

	def statfs(self, path):
		raise FuseOSError(EPERM)
	
	def symlink(self, target, source):
		raise FuseOSError(EPERM)
	
	def truncate(self, path, length, fh=0):
		fd = self.files[self.open(path, 0)]
		fd['dirty'] = True
		fd['data'] = fd['data'][:length]
	
	def unlink(self, path):
		paths = splitPath(path)

		# cannot remove mounted dir
		if paths[1] == '':
			raise FuseOSError(EPERM)
		if self.conn.rm(paths[0], paths[1]) != True:
			raise FuseOSError(ENOENT)
	
	def utimens(self, path, times=None):
		raise FuseOSError(EPERM)

	def write(self, path, data, offset, fh):
		fd = self.files[fh]
		if fd['path'] == None:
			raise FuseOSError(ENOENT)

		# update data and set dirty bit
		fd['data'] = fd['data'][:offset] + data
		fd['dirty'] = True
		
		return len(data)

	def release(self, path, fh):
		fd = self.files[fh]
		if fd['path'] == None:
			raise FuseOSError(ENOENT)

		# write back if dirty is set
		if fd['dirty'] == True:
			print '### UPDATE ', path
			paths = splitPath(path)
			self.conn.push(paths[0], paths[1], fd['data'])

		# reset fd
		fd['path'] = None
		fd['dirty'] = False
		fd['data'] = None