~azzar1/unity/add-show-desktop-key

« back to all changes in this revision

Viewing changes to scripts/usrmgt-server

  • Committer: matt.giuca
  • Date: 2009-01-11 23:39:33 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:1071
Moved all script files into newly created 'bin' directory (cleanup).
Not ./setup.py -- too important.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#!/usr/bin/python
2
2
 
3
3
import os
4
 
import pysvn
5
 
import subprocess
6
4
import sys
7
 
import urllib
8
 
from functools import partial
9
 
import traceback
10
5
import logging
11
6
 
12
7
import conf
25
20
#           - create repository
26
21
#           - svn config
27
22
#           - svn auth
28
 
#       - Checkout repository as home directory
29
23
#       - /etc/passwd entry
30
24
#   - Disable a user's account
31
25
#   - Enable a user's account
34
28
#   - Rebuild svn auth file
35
29
#   - Rebuild passwd + push to nodes.
36
30
 
37
 
def create_user(props):
38
 
    """Create the database record for the given user.
39
 
       Expected properties:
40
 
        login       - used as a unix login name and svn repository name.
41
 
                      STRING REQUIRED 
42
 
        unixid      - the unix uid under which execution will take place
43
 
                      on the behalf of the user. Don't use 0! If not specified
44
 
                      or None, one will be allocated from the configured
45
 
                      numeric range.
46
 
                      INT OPTIONAL
47
 
        password    - the clear-text password for the user. If this property is
48
 
                      absent or None, this is an indication that external
49
 
                      authentication should be used (i.e. LDAP).
50
 
                      STRING OPTIONAL
51
 
        email       - the user's email address.
52
 
                      STRING OPTIONAL
53
 
        nick        - the display name to use.
54
 
                      STRING REQUIRED
55
 
        fullname    - The name of the user for results and/or other official
56
 
                      purposes.
57
 
                      STRING REQUIRED
58
 
        rolenm      - The user's role. Must be one of "anyone", "student",
59
 
                      "tutor", "lecturer", "admin".
60
 
                      STRING/ENUM REQUIRED
61
 
        studentid   - If supplied and not None, the student id of the user for
62
 
                      results and/or other official purposes.
63
 
                      STRING OPTIONAL
64
 
       Return Value: the uid associated with the user. INT
65
 
    """
66
 
 
67
 
    if 'unixid' not in props or props['unixid'] is None:
68
 
        # For the time being, just choose a random unixid.
69
 
        # This may result in duplicates, but the unixid is essentially
70
 
        # a monitoring/logging convenience only. Oh, and dups could kill
71
 
        # each other. <sigh>
72
 
        props['unixid'] = random.randrange(5000,10000)
73
 
        # raise NotImplementedError, "No algorithm for creating uids yet!"
74
 
        # unixid = invent-uid
75
 
        # props['unixid'] = unixid
76
 
 
77
 
    common.makeuser.make_user_db(**props)
78
 
 
79
 
    return int(props['unixid'])
80
 
 
81
 
def update_user(props):
82
 
    """Create the database record for the given user.
83
 
       Expected properties:
84
 
        login       - user who is making the change (not necessarily the one
85
 
                      being updated).
86
 
        update      - dict of fields to be updated. The fields are all those
87
 
                      in the login table of the db.
88
 
                      'login' required.
89
 
                      Omitted fields will not be set.
90
 
    """
91
 
    update = props['update']
92
 
    # Note: "login" is special - it is not part of the kwargs to
93
 
    # db.update_user, but the first arg - used to find the user to update.
94
 
    # However it doesn't need any special treatment here.
95
 
 
96
 
    db = common.db.DB()
97
 
    db.update_user(**update)
98
 
    db.close()
99
 
 
100
 
def get_login(login, passwd, _realm, _login, _may_save):
101
 
    """Callback function used by pysvn for authentication.
102
 
    """
103
 
    logging.debug("Getting password for %s (realm %s)" % (login, _realm))
104
 
    return (True, login, passwd, False)
105
 
 
106
31
def activate_user(props):
107
32
    """Create the on-disk stuff for the given user.
108
33
       Sets the state of the user in the db from pending to enabled.
112
37
       Return Value: None
113
38
    """
114
39
 
 
40
    os.umask(0022) # Bad, but start_server sets it worse.
 
41
 
115
42
    login = props['login']
116
43
 
117
44
    db = common.db.DB()
124
51
 
125
52
        # make svn config/auth
126
53
 
127
 
        logging.debug("Creating repo")
128
 
        common.makeuser.make_svn_repo(login, throw_on_error=False)
129
 
        logging.debug("Creating svn config")
130
 
        common.makeuser.make_svn_config(login, throw_on_error=False)
131
 
        logging.debug("Creating svn auth")
 
54
        repopath = os.path.join(conf.svn_repo_path, 'users', login)
 
55
        logging.debug("Creating user's Subversion repository")
 
56
        common.makeuser.make_svn_repo(repopath, throw_on_error=False)
 
57
 
 
58
        rebuild_svn_config(props)
 
59
 
 
60
        logging.debug("Adding Subversion authentication")
132
61
        passwd = common.makeuser.make_svn_auth(login, throw_on_error=False)
133
62
        logging.debug("passwd: %s" % passwd)
134
63
 
135
 
        svn = pysvn.Client()
136
 
        svn.callback_get_login = partial(get_login, login, passwd)
137
 
 
138
 
        if conf.svn_addr[-1] != '/':
139
 
            conf.svn_addr = conf.svn_addr + "/"
140
 
    
141
 
        # FIXME: This should be a loop over enrolements.
142
 
        #        We're not going to fix this now because it requires
143
 
        #        a large amount of admin console work to manage subject
144
 
        #        offerings.
145
 
        #        Instead, we're just going to use a single offering with
146
 
        #        a "short" name of "info1".
147
 
        logging.debug("Creating /info1")
148
 
        try:
149
 
            svn.mkdir(conf.svn_addr + login + "/info1",
150
 
                      "Initial creation of work directory for Informatics 1")
151
 
        except Exception, exc:
152
 
            logging.warning("While mkdiring info1: %s" % str(exc))
153
 
            pass
154
 
        logging.debug("Creating /submissions")
155
 
        try:
156
 
            svn.mkdir(conf.svn_addr + login + "/submissions",
157
 
                      "Initial creation of submissions directory")
158
 
        except Exception, exc:
159
 
            logging.warning("While mkdiring submissions: %s" % str(exc))
160
 
            pass
161
 
        logging.debug("Creating /stuff")
162
 
        try:
163
 
            svn.mkdir(conf.svn_addr + login + "/stuff",
164
 
                      "Initial creation of directory for miscellania")
165
 
        except Exception, exc:
166
 
            logging.warning("While mkdiring stuff: %s" % str(exc))
167
 
            pass
168
 
 
169
64
        logging.debug("Creating jail")
170
 
        common.makeuser.make_jail(login, details.unixid)
171
 
 
172
 
        # FIXME: <hack>
173
 
 
174
 
        tcf_path = os.path.join(conf.jail_base, 'template/opt/ivle/lib/conf/conf.py')
175
 
        cf_path = os.path.join(conf.jail_base, login, 'opt/ivle/lib/conf/conf.py')
176
 
 
177
 
        os.remove(cf_path)
178
 
        cf = open(cf_path, "w")
179
 
        cf.write(open(tcf_path, "r").read())
180
 
        cf.write("# The login name for the owner of the jail\n")
181
 
        cf.write("login = %s\n" % repr(login))
182
 
        cf.write("\n")
183
 
        cf.write("# The subversion-only password for the owner of the jail\n")
184
 
        cf.write("svn_pass = %s\n" % repr(passwd))
185
 
        cf.close()
186
 
 
187
 
        # FIXME: </hack>
188
 
 
189
 
        logging.debug("Checking out directories in the jail")
190
 
        try:
191
 
            svn.checkout(conf.svn_addr + login + "/stuff",
192
 
                         common.studpath.url_to_local(login + "/stuff")[1])
193
 
        except Exception, exc:
194
 
            logging.warning("While mkdiring stuff: %s" % str(exc))
195
 
            pass
196
 
        try:
197
 
            svn.checkout(conf.svn_addr + login + "/submissions",
198
 
                         common.studpath.url_to_local(login + "/submissions")[1])
199
 
        except Exception, exc:
200
 
            logging.warning("While mkdiring submissions: %s" % str(exc))
201
 
            pass
202
 
        try:
203
 
            svn.checkout(conf.svn_addr + login + "/info1",
204
 
                         common.studpath.url_to_local(login + "/info1")[1])
205
 
        except Exception, exc:
206
 
            logging.warning("While mkdiring info1: %s" % str(exc))
207
 
            pass
208
 
 
209
 
        # FIXME: should this be nicer?
210
 
        os.system("chown -R %d:%d %s" \
211
 
                % (details.unixid, details.unixid,
212
 
                   common.studpath.url_to_local(login)[1]))
213
 
 
 
65
        common.makeuser.make_jail(login, details.unixid, svn_pass=passwd)
214
66
 
215
67
        logging.info("Enabling user")
216
68
        db.update_user(login, state='enabled')
220
72
    finally:
221
73
        db.close()
222
74
 
 
75
def rebuild_svn_config(props):
 
76
    """Rebuilds the svn config file
 
77
    Return value:
 
78
        response (okay, failure)
 
79
    """
 
80
    try:
 
81
        common.makeuser.rebuild_svn_config()
 
82
    except Exception, e:
 
83
        logging.warning('Rebuild of Subversion authorization config failed!')
 
84
        return{'response': 'failure', 'msg': repr(e)}
 
85
 
 
86
    return {'response': 'okay'}
 
87
 
 
88
def rebuild_svn_group_config(props):
 
89
    """Rebuilds the svn group config file
 
90
    Return value:
 
91
        response (okay, failure)
 
92
    """
 
93
    try:
 
94
        common.makeuser.rebuild_svn_group_config()
 
95
    except Exception, e:
 
96
        logging.warning(
 
97
            'Rebuild of Subversion group authorization config failed!')
 
98
        return{'response': 'failure', 'msg': repr(e)}
 
99
 
 
100
    return {'response': 'okay'}
 
101
 
 
102
def create_group_repository(props):
 
103
    """Creates on disk repository for the given group
 
104
    Expected properties:
 
105
        subj_short_name, year, semester, groupnm
 
106
    Return value:
 
107
        response (okay, failure)
 
108
    """
 
109
 
 
110
    subj_short_name = props['subj_short_name']
 
111
    year = props['year']
 
112
    semester = props['semester']
 
113
    groupnm = props['groupnm']
 
114
 
 
115
    namespace = "_".join([subj_short_name, year, semester, groupnm])
 
116
    repopath = os.path.join(conf.svn_repo_path, 'groups', namespace)
 
117
    logging.debug("Creating Subversion repository %s"%repopath)
 
118
    try:
 
119
        common.makeuser.make_svn_repo(repopath)
 
120
    except Exception, e:
 
121
        logging.error("Failed to create Subversion repository %s: %s"%
 
122
            (repopath,repr(e)))
 
123
        return {'response': 'failure', 'msg': repr(e)}
 
124
 
 
125
    return {'response': 'okay'}
 
126
 
223
127
actions = {
224
 
        'create_user':create_user,
225
 
        'update_user':update_user,
226
128
        'activate_user':activate_user,
 
129
        'create_group_repository':create_group_repository,
 
130
        'rebuild_svn_config':rebuild_svn_config,
 
131
        'rebuild_svn_group_config':rebuild_svn_group_config,
227
132
    }
228
133
 
 
134
def initializer():
 
135
    try:
 
136
        pidfile = open('/var/run/usrmgt-server.pid', 'w')
 
137
        pidfile.write('%d\n' % os.getpid())
 
138
        pidfile.close()
 
139
    except IOError, (errno, strerror):
 
140
        print "Couldn't write PID file. IO error(%s): %s" % (errno, strerror)
 
141
        sys.exit(1)
 
142
 
229
143
def dispatch(props):
230
144
    logging.debug(repr(props))
231
145
    action = props.keys()[0]
232
146
    return actions[action](props[action])
233
147
 
234
148
if __name__ == "__main__":
235
 
    if len(sys.argv) <3:
236
 
        print >>sys.stderr, "Usage: usrmgt-server <port> <magic>"
237
 
        sys.exit(1)
238
 
    port = int(sys.argv[1])
239
 
    magic = sys.argv[2]
240
 
 
241
149
    pid = os.getpid()
242
150
 
243
151
    logging.basicConfig(filename="/var/log/usrmgt.log", level=logging.INFO)
244
 
    logging.info("Starting usrmgt server on port %d (pid = %d)" % (port, pid))
 
152
    logging.info("Starting usrmgt server on port %d (pid = %d)" %
 
153
                 (conf.usrmgt_port, pid))
245
154
 
246
 
    common.chat.start_server(port, magic, True, dispatch)
 
155
    common.chat.start_server(conf.usrmgt_port, conf.usrmgt_magic, True, dispatch, initializer)