X-Git-Url: http://xvm.mit.edu/gitweb/invirt/packages/invirt-remote.git/blobdiff_plain/67f7ade5408dd3622f1b7a4ba7b1fd0922ee63ad..6b8f7baf1bf4aeb801eb390a1720dd32ceca96e3:/files/usr/sbin/sipb-xen-remconffs?ds=sidebyside

diff --git a/files/usr/sbin/sipb-xen-remconffs b/files/usr/sbin/sipb-xen-remconffs
index df07f54..4db1414 100755
--- a/files/usr/sbin/sipb-xen-remconffs
+++ b/files/usr/sbin/sipb-xen-remconffs
@@ -1,62 +1,15 @@
 #!/usr/bin/python
 
-import fuse
-from fuse import Fuse
-
-from time import time
-
-import stat	# for file properties
-import os	  # for filesystem modes (O_RDONLY, etc)
-import errno   # for error number codes (ENOENT, etc)
-			   # - note: these must be returned as negatives
+import routefs
+from routes import Mapper
 
 from syslog import *
+from time import time
 
-import sipb_xen_database
-
-fuse.fuse_python_api = (0, 2)
+from invirt import database
+from invirt.config import structs as config
 
-def getDepth(path):
-	"""
-	Return the depth of a given path, zero-based from root ('/')
-	"""
-	if path == '/':
-		return 0
-	else:
-		return path.count('/')
-
-def getParts(path):
-	"""
-	Return the slash-separated parts of a given path as a list
-	"""
-	# [1:] to exclude leading empty element
-	split = path.split('/')
-	if split[-1]:
-		return split[1:]
-	else:
-		return split[1:-1]
-
-def parse(path):
-	parts = getParts(path)
-	return parts, len(parts)
-
-class MyStat:
-	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
-	
-	def toTuple(self):
-		return (self.st_mode, self.st_ino, self.st_dev, self.st_nlink, self.st_uid, self.st_gid, self.st_size, self.st_atime, self.st_mtime, self.st_ctime)
-
-class RemConfFS(Fuse):
+class RemConfFS(routefs.RouteFS):
 	"""
 	RemConfFS creates a filesytem for configuring remctl, like this:
 	/
@@ -64,11 +17,8 @@ class RemConfFS(Fuse):
 	|   |-- machine1
 	|   ...
 	|   `-- machinen
-	`-- conf.d
-	    |-- machine1
-	    ...
-	    `-- machinen
-
+	`-- conf
+        
 	The machine list and the acls are drawn from a database.
 	
 	This filesystem only implements the getattr, getdir, read, and readlink
@@ -79,32 +29,34 @@ class RemConfFS(Fuse):
 		"""Initialize the filesystem and set it to allow_other access besides
 		the user who mounts the filesystem (i.e. root)
 		"""
-		Fuse.__init__(self, *args, **kw)
+		super(RemConfFS, self).__init__(*args, **kw)
 		self.lasttime = time()
-		self.allow_other = 1
+		self.fuse_args.add("allow_other", True)
 		
 		openlog('sipb-xen-remconffs ', LOG_PID, LOG_DAEMON)
 		
 		syslog(LOG_DEBUG, 'Init complete.')
-
-	def getMachines(self):
-		"""Get the list of VMs in the database, clearing the cache if it's 
-		older than 15 seconds"""
-		if time() - self.lasttime > 15:
-			self.lasttime = time()
-			sipb_xen_database.clear_cache()
-		return [machine.name for machine in sipb_xen_database.Machine.select()]
-		
-	def getacl(self, machine_name):
+        
+        def make_map(self):
+                m = Mapper()
+                m.connect('', controller='getroot')
+                m.connect('acl/:machine', controller='getacl')
+                m.connect('conf', controller='getconf')
+                return m
+        
+        def getroot(self, **kw):
+                return ['acl', 'conf']
+        
+	def getacl(self, machine, **kw):
 		"""Build the ACL file for a machine
 		"""
-		machine = sipb_xen_database.Machine.get_by(name=machine_name)
+		machine = database.Machine.get_by(name=machine)
 		users = [acl.user for acl in machine.acl]
 		return "\n".join(map(self.userToPrinc, users)
 				 + ['include /etc/remctl/acl/web',
 				    ''])
-		
-	def getconf(self):
+        
+	def getconf(self, **kw):
 		"""Build the master conf file, with all machines
 		"""
 		return '\n'.join("control %s /usr/sbin/sipb-xen-remote-proxy-control"
@@ -112,6 +64,14 @@ class RemConfFS(Fuse):
 				 % (machine_name, machine_name)
 				 for machine_name in self.getMachines())+'\n'
 	
+	def getMachines(self):
+		"""Get the list of VMs in the database, clearing the cache if it's 
+		older than 15 seconds"""
+		if time() - self.lasttime > 15:
+			self.lasttime = time()
+			database.clear_cache()
+		return [machine.name for machine in database.Machine.select()]
+        
 	def userToPrinc(self, user):
 		"""Convert Kerberos v4-style names to v5-style and append a default
 		realm if none is specified
@@ -120,117 +80,10 @@ class RemConfFS(Fuse):
 			(princ, realm) = user.split('@')
 		else:
 			princ = user
-			realm = "ATHENA.MIT.EDU"
+			realm = config.authn[0].realm
 		
 		return princ.replace('.', '/') + '@' + realm
-	
-	def getattr(self, path):
-		"""
-		- st_mode (protection bits)
-		- st_ino (inode number)
-		- st_dev (device)
-		- st_nlink (number of hard links)
-		- st_uid (user ID of owner)
-		- st_gid (group ID of owner)
-		- st_size (size of file, in bytes)
-		- st_atime (time of most recent access)
-		- st_mtime (time of most recent content modification)
-		- st_ctime (platform dependent; time of most recent metadata change on Unix,
-					or the time of creation on Windows).
-		"""
-		
-		syslog(LOG_DEBUG, "*** getattr: " + path)
-		
-		depth = getDepth(path)
-		parts = getParts(path)
-		
-		st = MyStat()
-		if path == '/':
-			st.st_mode = stat.S_IFDIR | 0755
-			st.st_nlink = 2
-		elif depth == 1:
-			if parts[0] == 'acl':
-				st.st_mode = stat.S_IFDIR | 0755
-				st.st_nlink = 2
-			elif parts[0] == 'conf':
-				st.st_mode = stat.S_IFREG | 0444
-				st.st_nlink = 1
-				st.st_size = len(self.getconf())
-			else:
-				return -errno.ENOENT
-		elif depth == 2:
-			if parts[0] != 'acl':
-				return -errno.ENOENT
-			if parts[1] not in self.getMachines():
-				return -errno.ENOENT
-			st.st_mode = stat.S_IFREG | 0444
-			st.st_nlink = 1
-			st.st_size = len(self.getacl(parts[1]))
-
-		return st.toTuple()
-	
-	# This call isn't actually used in the version of Fuse on console, but we
-	# wanted to leave it implemented to ease the transition in the future
-	def readdir(self, path, offset):
-		"""Return a generator with the listing for a directory
-		"""
-		syslog(LOG_DEBUG, '*** readdir %s %s' % (path, offset))
-		for (value, zero) in self.getdir(path):
-			yield fuse.Direntry(value)
-	
-	def getdir(self, path):
-		"""Return a list of tuples of the form (item, 0) with the contents of
-		the directory path
-		
-		Fuse doesn't add '.' or '..' on its own, so we have to
-		"""
-		syslog(LOG_DEBUG, '*** getdir %s' % path)
-		
-		parts, depth = parse(path)
-
-		if depth == 0:
-			contents = ('acl', 'conf')
-		elif depth == 1:
-			if parts[0] == 'acl':
-				contents = self.getMachines()
-			else:
-				return -errno.ENOENT
-		else:
-			return -errno.ENOTDIR
-
-		# Format the list the way that Fuse wants it - and don't forget to add
-		# '.' and '..'
-		return [(i, 0) for i in (list(contents) + ['.', '..'])]
-
-	def read(self, path, length, offset):
-		"""Read length bytes starting at offset of path. In most cases, this
-		just gets passed on to the OS
-		"""
-		syslog(LOG_DEBUG, '*** read %s %s %s' % (path, length, offset))
-		
-		parts, depth = parse(path)
-		
-		if depth == 0:
-			return -errno.EISDIR
-		elif parts[0] == 'conf':
-			return self.getconf()[offset:offset+length]
-		elif parts[0] == 'acl':
-			if depth == 1:
-				return -errno.EISDIR
-			if parts[1] in self.getMachines():
-				return self.getacl(parts[1])[offset:offset+length]
-		return -errno.ENOENT
-	
-	def readlink(self, path):
-		syslog(LOG_DEBUG, '*** readlink %s' % path)
-		return -errno.ENOENT
-
 
 if __name__ == '__main__':
-	sipb_xen_database.connect('postgres://sipb-xen@sipb-xen-dev.mit.edu/sipb_xen')
-	usage="""
-$0 [mount_path]
-"""
-	server = RemConfFS()
-	server.flags = 0
-	server.main()
+	database.connect()
+        routefs.main(RemConfFS)