source: trunk/packages/invirt-remote-server/files/usr/sbin/invirt-remconffs @ 1743

Last change on this file since 1743 was 1728, checked in by quentin, 16 years ago

Switched from caching ORM to direct database queries; now uncached queries are almost as fast as the cached queries used to be, and we don't have any cache coherency problems

  • Property svn:executable set to *
File size: 2.9 KB
Line 
1#!/usr/bin/python
2
3import routefs
4from routes import Mapper
5
6from syslog import *
7from time import time
8import sqlalchemy as sa
9
10from invirt import database
11from invirt.config import structs as config
12
13class RemConfFS(routefs.RouteFS):
14    """
15    RemConfFS creates a filesytem for configuring remctl, like this:
16    /
17    |-- acl
18    |   |-- machine1
19    |   ...
20    |   `-- machinen
21    `-- conf
22   
23    The machine list and the acls are drawn from a database.
24    """
25   
26    def __init__(self, *args, **kw):
27        """Initialize the filesystem and set it to allow_other access besides
28        the user who mounts the filesystem (i.e. root)
29        """
30        super(RemConfFS, self).__init__(*args, **kw)
31        self.fuse_args.add("allow_other", True)
32       
33        openlog('invirt-remconffs ', LOG_PID, LOG_DAEMON)
34       
35        syslog(LOG_DEBUG, 'Init complete.')
36   
37    def make_map(self):
38        m = Mapper()
39        m.connect('', controller='getroot')
40        m.connect('acl', controller='getmachines')
41        m.connect('acl/:machine', controller='getacl')
42        m.connect('conf', controller='getconf')
43        return m
44   
45    def getroot(self, **kw):
46        return ['acl', 'conf']
47   
48    def getacl(self, machine, **kw):
49        """Build the ACL file for a machine
50        """
51        s = sa.sql.select([database.machine_access_table.c.user], # Field to select from
52                          sa.sql.and_( # where clause
53                database.machine_table.c.machine_id==database.machine_access_table.c.machine_id, # join field
54                database.machine_table.c.name == machine), # filter field
55                          from_obj=[database.machine_access_table, database.machine_table]) # from tables
56        users = [self.userToPrinc(acl[0]) for acl in
57                 database.session.execute(s)]
58        return "\n".join(users
59                 + ['include /etc/remctl/acl/web',
60                    ''])
61   
62    def getconf(self, **kw):
63        """Build the master conf file, with all machines
64        """
65        return '\n'.join("control %s /usr/sbin/invirt-remote-proxy-control"
66                 " /etc/remctl/remconffs/acl/%s"
67                 % (machine_name, machine_name)
68                 for machine_name in self.getmachines())+'\n'
69   
70    def getmachines(self, **kw):
71        """Get the list of VMs in the database. Does not cache to prevent race conditions."""
72        return list(row[0] for row in database.session.execute(sa.sql.select([database.Machine.c.name])))
73   
74    def userToPrinc(self, user):
75        """Convert Kerberos v4-style names to v5-style and append a default
76        realm if none is specified
77        """
78        if '@' in user:
79            (princ, realm) = user.split('@')
80        else:
81            princ = user
82            realm = config.authn[0].realm
83       
84        return princ.replace('.', '/') + '@' + realm
85
86if __name__ == '__main__':
87    database.connect()
88    routefs.main(RemConfFS)
Note: See TracBrowser for help on using the repository browser.