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

« back to all changes in this revision

Viewing changes to scripts/usrmgt-server

  • Committer: dcoles
  • Date: 2008-05-30 00:36:54 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:756
Added SciPy install requirements

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