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

« back to all changes in this revision

Viewing changes to scripts/usrmgt-server

  • Committer: mattgiuca
  • Date: 2008-07-15 07:19:34 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:875
Added "migrations" directory, which contains incremental database update
    scripts.
Updated users.sql, uniqueness key on offering table.
Added migration matching this update to the migrations directory. Mm handy!

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
import urllib
8
8
from functools import partial
9
9
import traceback
 
10
import logging
 
11
import errno
10
12
 
11
13
import conf
12
14
import common.db
33
35
#   - Rebuild svn auth file
34
36
#   - Rebuild passwd + push to nodes.
35
37
 
36
 
DEBUG_PRINT = True
37
 
 
38
38
def create_user(props):
39
39
    """Create the database record for the given user.
40
40
       Expected properties:
98
98
    db.update_user(**update)
99
99
    db.close()
100
100
 
101
 
def get_login(login, passwd, _realm, _login, _may_save):
 
101
def get_login(login, passwd, realm, existing_login, _may_save):
102
102
    """Callback function used by pysvn for authentication.
 
103
    login, passwd: Credentials of the user attempting to log in.
 
104
        passwd in clear (this should be the user's svn_pass, a
 
105
        randomly-generated permanent password for this user, not their main
 
106
        IVLE password).
 
107
    realm, existing_login, _may_save: The 3 arguments passed by pysvn to
 
108
        callback_get_login.
 
109
        The following has been determined empirically, not from docs:
 
110
        existing_login will be the name of the user who owns the process on
 
111
        the first attempt, "" on subsequent attempts. We use this fact.
103
112
    """
104
 
    log("Getting password for %s (realm %s)" % (login, _realm))
105
 
    return (True, login, passwd, False)
 
113
    logging.debug("Getting password for %s (realm %s)" % (login, realm))
 
114
    # Only provide credentials on the _first_ attempt.
 
115
    # If we're being asked again, then it means the credentials failed for
 
116
    # some reason and we should just fail. (This is not desirable, but it's
 
117
    # better than being asked an infinite number of times).
 
118
    if existing_login == "":
 
119
        logging.warning("Could not authenticate SVN for %s" % login)
 
120
        return (False, login, passwd, False)
 
121
    else:
 
122
        return (True, login, passwd, False)
106
123
 
107
124
def activate_user(props):
108
125
    """Create the on-disk stuff for the given user.
113
130
       Return Value: None
114
131
    """
115
132
 
 
133
    os.umask(0022) # Bad, but start_server sets it worse.
 
134
 
116
135
    login = props['login']
117
136
 
118
137
    db = common.db.DB()
125
144
 
126
145
        # make svn config/auth
127
146
 
128
 
        log("Creating repo")
 
147
        logging.debug("Creating repo")
129
148
        common.makeuser.make_svn_repo(login, throw_on_error=False)
130
 
        log("Creating svn config")
 
149
        logging.debug("Creating svn config")
131
150
        common.makeuser.make_svn_config(login, throw_on_error=False)
132
 
        log("Creating svn auth")
 
151
        logging.debug("Creating svn auth")
133
152
        passwd = common.makeuser.make_svn_auth(login, throw_on_error=False)
134
 
        log("passwd: %s" % passwd)
 
153
        logging.debug("passwd: %s" % passwd)
135
154
 
136
155
        svn = pysvn.Client()
137
156
        svn.callback_get_login = partial(get_login, login, passwd)
145
164
        #        offerings.
146
165
        #        Instead, we're just going to use a single offering with
147
166
        #        a "short" name of "info1".
148
 
        log("Creating /info1")
 
167
        logging.debug("Creating /info1")
149
168
        try:
150
169
            svn.mkdir(conf.svn_addr + login + "/info1",
151
170
                      "Initial creation of work directory for Informatics 1")
152
171
        except Exception, exc:
153
 
            log("While mkdiring info1: %s" % str(exc))
154
 
            pass
155
 
        log("Creating /submissions")
156
 
        try:
157
 
            svn.mkdir(conf.svn_addr + login + "/submissions",
158
 
                      "Initial creation of submissions directory")
159
 
        except Exception, exc:
160
 
            log("While mkdiring submissions: %s" % str(exc))
161
 
            pass
162
 
        log("Creating /stuff")
 
172
            logging.warning("While mkdiring info1: %s" % str(exc))
 
173
            pass
 
174
        logging.debug("Creating /stuff")
163
175
        try:
164
176
            svn.mkdir(conf.svn_addr + login + "/stuff",
165
177
                      "Initial creation of directory for miscellania")
166
178
        except Exception, exc:
167
 
            log("While mkdiring stuff: %s" % str(exc))
168
 
            pass
169
 
 
170
 
        log("Creating jail")
171
 
        common.makeuser.make_jail(login, details.unixid)
172
 
 
173
 
        # FIXME: <hack>
174
 
 
175
 
        tcf_path = os.path.join(conf.jail_base, 'template/opt/ivle/lib/conf/conf.py')
176
 
        cf_path = os.path.join(conf.jail_base, login, 'opt/ivle/lib/conf/conf.py')
177
 
 
178
 
        os.remove(cf_path)
179
 
        cf = open(cf_path, "w")
180
 
        cf.write(open(tcf_path, "r").read())
181
 
        cf.write("# The login name for the owner of the jail\n")
182
 
        cf.write("login = %s\n" % repr(login))
183
 
        cf.write("\n")
184
 
        cf.write("# The subversion-only password for the owner of the jail\n")
185
 
        cf.write("svn_pass = %s\n" % repr(passwd))
186
 
        cf.close()
187
 
 
188
 
        # FIXME: </hack>
189
 
 
190
 
        log("Checking out directories in the jail")
191
 
        try:
192
 
            svn.checkout(conf.svn_addr + login + "/stuff",
193
 
                         common.studpath.url_to_local(login + "/stuff")[1])
194
 
        except Exception, exc:
195
 
            log("While mkdiring stuff: %s" % str(exc))
196
 
            pass
197
 
        try:
198
 
            svn.checkout(conf.svn_addr + login + "/submissions",
199
 
                         common.studpath.url_to_local(login + "/submissions")[1])
200
 
        except Exception, exc:
201
 
            log("While mkdiring submissions: %s" % str(exc))
202
 
            pass
203
 
        try:
204
 
            svn.checkout(conf.svn_addr + login + "/info1",
205
 
                         common.studpath.url_to_local(login + "/info1")[1])
206
 
        except Exception, exc:
207
 
            log("While mkdiring info1: %s" % str(exc))
208
 
            pass
 
179
            logging.warning("While mkdiring stuff: %s" % str(exc))
 
180
            pass
 
181
 
 
182
        logging.debug("Creating jail")
 
183
        common.makeuser.make_jail(login, details.unixid, svn_pass=passwd)
 
184
 
 
185
        common.makeuser.mount_jail(login)
 
186
 
 
187
        do_checkout(props, svn_pass=passwd)
209
188
 
210
189
        # FIXME: should this be nicer?
211
190
        os.system("chown -R %d:%d %s" \
212
191
                % (details.unixid, details.unixid,
213
192
                   common.studpath.url_to_local(login)[1]))
214
193
 
215
 
 
216
 
        log("Enabling user")
 
194
        logging.info("Enabling user")
217
195
        db.update_user(login, state='enabled')
218
196
 
219
197
        return {"response": "okay"}
221
199
    finally:
222
200
        db.close()
223
201
 
 
202
def do_checkout(props, svn_pass=None):
 
203
    """Create the default contents of a user's jail by checking out from the
 
204
    repositories.
 
205
    If any directory already exists, just fail silently (so this is not a
 
206
    "wipe-and-checkout", merely a checkout if it failed or something).
 
207
       Expected properties:
 
208
        login       - the user name for the jail
 
209
                      STRING REQUIRED
 
210
       Return Value: None
 
211
    """
 
212
    login = props['login']
 
213
 
 
214
    db = common.db.DB()
 
215
    user = db.get_user(login)
 
216
    # If svn_pass isn't supplied, grab it from the DB
 
217
    if svn_pass is None:
 
218
        svn_pass = user.svn_pass
 
219
    db.close()
 
220
 
 
221
    svn = pysvn.Client()
 
222
    svn.callback_get_login = partial(get_login, login, svn_pass)
 
223
 
 
224
    if conf.svn_addr[-1] != os.sep:
 
225
        conf.svn_addr += os.sep
 
226
 
 
227
    # FIXME: <hack>
 
228
 
 
229
    logging.debug("Checking out directories in the jail")
 
230
    try:
 
231
        svn.checkout(conf.svn_addr + login + "/stuff",
 
232
                     common.studpath.url_to_local(login + "/stuff")[1])
 
233
        os.system("chown -R %d:%d %s" \
 
234
                % (user.unixid, user.unixid,
 
235
                   common.studpath.url_to_local(login + "/stuff")[1]))
 
236
    except Exception, exc:
 
237
        logging.warning("While mkdiring stuff: %s" % str(exc))
 
238
        pass
 
239
    try:
 
240
        svn.checkout(conf.svn_addr + login + "/info1",
 
241
                     common.studpath.url_to_local(login + "/info1")[1])
 
242
        os.system("chown -R %d:%d %s" \
 
243
                % (user.unixid, user.unixid,
 
244
                   common.studpath.url_to_local(login + "/info1")[1]))
 
245
    except Exception, exc:
 
246
        logging.warning("While mkdiring info1: %s" % str(exc))
 
247
        pass
 
248
 
 
249
    # FIXME: </hack>
 
250
 
 
251
    return {"response": "okay"}
 
252
 
224
253
actions = {
225
254
        'create_user':create_user,
226
255
        'update_user':update_user,
227
256
        'activate_user':activate_user,
 
257
        'do_checkout':do_checkout,
228
258
    }
229
259
 
230
 
def log(msg):
231
 
    """Writes a message to stderr, but only if DEBUG_PRINT is True.
232
 
    """
233
 
    global DEBUG_PRINT
234
 
    if DEBUG_PRINT:
235
 
        print >>sys.stderr, msg
 
260
def initializer():
 
261
    try:
 
262
        pidfile = open('/var/run/usrmgt-server.pid', 'w')
 
263
        pidfile.write('%d\n' % os.getpid())
 
264
        pidfile.close()
 
265
    except IOError, (errno, strerror):
 
266
        print "Couldn't write PID file. IO error(%s): %s" % (errno, strerror)
 
267
        sys.exit(1)
236
268
 
237
269
def dispatch(props):
238
 
    log(repr(props))
 
270
    logging.debug(repr(props))
239
271
    action = props.keys()[0]
240
272
    return actions[action](props[action])
241
273
 
242
274
if __name__ == "__main__":
 
275
    if len(sys.argv) <3:
 
276
        print >>sys.stderr, "Usage: usrmgt-server <port> <magic>"
 
277
        sys.exit(1)
243
278
    port = int(sys.argv[1])
244
279
    magic = sys.argv[2]
245
280
 
246
 
    common.chat.start_server(port, magic, False, dispatch)
 
281
    pid = os.getpid()
 
282
 
 
283
    logging.basicConfig(filename="/var/log/usrmgt.log", level=logging.INFO)
 
284
    logging.info("Starting usrmgt server on port %d (pid = %d)" % (port, pid))
 
285
 
 
286
    common.chat.start_server(port, magic, True, dispatch, initializer)