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

« back to all changes in this revision

Viewing changes to lib/common/makeuser.py

  • Committer: dcoles
  • Date: 2008-05-26 01:44:57 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:755
Added support for an incremental rebuild of all the users jails.
It can be run by `./remakeallusers -i`

Show diffs side-by-side

added added

removed removed

Lines of Context:
38
38
import time
39
39
import uuid
40
40
import warnings
41
 
 
 
41
import filecmp
42
42
import conf
43
43
import db
44
44
 
122
122
 
123
123
    return passwd
124
124
 
125
 
def make_jail(username, uid, force=True):
 
125
def generate_manifest(basedir, targetdir, parent=''):
 
126
    """ From a basedir and a targetdir work out which files are missing or out 
 
127
    of date and need to be added/updated and which files are redundant and need 
 
128
    to be removed.
 
129
    
 
130
    parent: This is used for the recursive call to track the relative paths 
 
131
    that we have decended.
 
132
    """
 
133
    
 
134
    cmp = filecmp.dircmp(basedir, targetdir)
 
135
 
 
136
    # Add all new files and files that have changed
 
137
    to_add = [os.path.join(parent,x) for x in (cmp.left_only + cmp.diff_files)]
 
138
 
 
139
    # Remove files that are redundant
 
140
    to_remove = [os.path.join(parent,x) for x in cmp.right_only]
 
141
    
 
142
    # Recurse
 
143
    for d in cmp.common_dirs:
 
144
        newbasedir = os.path.join(basedir, d)
 
145
        newtargetdir = os.path.join(targetdir, d)
 
146
        newparent = os.path.join(parent, d)
 
147
        (sadd,sremove) = generate_manifest(newbasedir, newtargetdir, newparent)
 
148
        to_add += sadd
 
149
        to_remove += sremove
 
150
 
 
151
    return (to_add, to_remove)
 
152
 
 
153
 
 
154
def make_jail(username, uid, force=True, manifest=None):
126
155
    """Creates a new user's jail space, in the jail directory as configured in
127
156
    conf.py.
128
157
 
129
 
    This expects there to be a "template" directory within the jail root which
 
158
    This expects there to be a "staging" directory within the jail root which
130
159
    contains all the files for a sample student jail. It creates the student's
131
160
    directory in the jail root, by making a hard-link copy of every file in the
132
 
    template directory, recursively.
 
161
    staging directory, recursively.
133
162
 
134
163
    Returns the path to the user's home directory.
135
164
 
142
171
 
143
172
    force: If false, exception if jail already exists for this user.
144
173
    If true (default), overwrites it, but preserves home directory.
 
174
 
 
175
    manifest: If provided this will be a tupple (to_add, to_remove) of files or 
 
176
    directories to add or remove from the jail.
145
177
    """
146
178
    # MUST run as root or some of this may fail
147
179
    if os.getuid() != 0:
148
180
        raise Exception("Must run make_jail as root")
149
181
    
150
 
    templatedir = os.path.join(conf.jail_base, 'template')
151
 
    if not os.path.isdir(templatedir):
152
 
        raise Exception("Template jail directory does not exist: " +
153
 
            templatedir)
 
182
    stagingdir = os.path.join(conf.jail_base, '__staging__')
 
183
    if not os.path.isdir(stagingdir):
 
184
        raise Exception("Staging jail directory does not exist: " +
 
185
            stagingdir)
154
186
    # tempdir is for putting backup homes in
155
 
    tempdir = os.path.join(conf.jail_base, 'temp')
 
187
    tempdir = os.path.join(conf.jail_base, '__temp__')
156
188
    if not os.path.exists(tempdir):
157
189
        os.makedirs(tempdir)
158
190
    elif not os.path.isdir(tempdir):
179
211
            # the backup will be un-made.
180
212
            # XXX This will still leave the user's jail in an unusable state,
181
213
            # but at least they won't lose their files.
182
 
            shutil.rmtree(userdir)
183
 
 
184
 
            # Hard-link (copy aliasing) the entire tree over
185
 
            linktree(templatedir, userdir)
 
214
            if manifest:
 
215
                (to_add, to_remove) = manifest
 
216
                # Remove redundant files and directories
 
217
                for d in to_remove:
 
218
                    dst = os.path.join(userdir, d)
 
219
                    src = os.path.join(stagingdir, d)
 
220
                    if os.path.isdir(dst):
 
221
                        shutil.rmtree(dst)
 
222
                    elif os.path.isfile(dst):
 
223
                        os.remove(dst)
 
224
                # Add new files
 
225
                for d in to_add:
 
226
                    dst = os.path.join(userdir, d)
 
227
                    src = os.path.join(stagingdir, d)
 
228
                    # Clear the previous file/dir
 
229
                    if os.path.isdir(dst):
 
230
                        shutil.rmtree(dst)
 
231
                    elif os.path.isfile(dst):
 
232
                        os.remove(dst)
 
233
                    # Link the file/dirs
 
234
                    if os.path.isdir(src):
 
235
                        linktree(src, dst)
 
236
                    elif os.path.isfile(src):
 
237
                        os.link(src, dst)
 
238
                    
 
239
            else:
 
240
                # No manifest, do a full rebuild
 
241
                shutil.rmtree(userdir)
 
242
                # Hard-link (copy aliasing) the entire tree over
 
243
                linktree(stagingdir, userdir)
186
244
        finally:
187
245
            # Set up the user's home directory (restore backup)
188
246
            # First make sure the directory is empty and its parent exists
198
256
    else:
199
257
        # No user jail exists
200
258
        # Hard-link (copy aliasing) the entire tree over
201
 
        linktree(templatedir, userdir)
 
259
        linktree(stagingdir, userdir)
202
260
 
203
261
        # Set up the user's home directory
204
262
        userhomedir = os.path.join(homedir, username)