+ # create all accounts with gid=1001 - i.e. 'slices' like it is in the root context
+ slices_gid = 1001
+ logger.log("adding user {name} id {uid} gid {slices_gid} to {etcpasswd}"
+ .format(**(locals())))
+ try:
+ with open(etcpasswd, 'a') as passwdfile:
+ passwdfile.write("{name}:x:{uid}:{slices_gid}::/home/{name}:/bin/bash\n"
+ .format(**locals()))
+ except:
+ logger.log_exc("exception while updating {}".format(etcpasswd))
+ logger.log("adding group slices with gid {slices_gid} to {etcgroup}"
+ .format(**locals()))
+ try:
+ with open(etcgroup, 'a') as groupfile:
+ groupfile.write("slices:x:{slices_gid}\n"
+ .format(**locals()))
+ except:
+ logger.log_exc("exception while updating {}".format(etcgroup))
+ sudoers = os.path.join(containerDir, 'etc/sudoers')
+ if os.path.exists(sudoers):
+ try:
+ with open(sudoers, 'a') as f:
+ f.write("{} ALL=(ALL) NOPASSWD: ALL\n".format(name))
+ except:
+ logger.log_exc("exception while updating /etc/sudoers")
+
+ # customizations for the user environment - root or slice uid
+ # we save the whole business in /etc/planetlab.profile
+ # and source this file for both root and the slice uid's .profile
+ # prompt for slice owner, + LD_PRELOAD for transparently wrap bind
+ pl_profile = os.path.join(containerDir, "etc/planetlab.profile")
+ ld_preload_text = """# by default, we define this setting so that calls to bind(2),
+# when invoked on 0.0.0.0, get transparently redirected to the public interface of this node
+# see https://svn.planet-lab.org/wiki/LxcPortForwarding"""
+ usrmove_path_text = """# VM's before Features/UsrMove need /bin and /sbin in their PATH"""
+ usrmove_path_code = """
+pathmunge () {
+ if ! echo $PATH | /bin/egrep -q "(^|:)$1($|:)" ; then
+ if [ "$2" = "after" ] ; then
+ PATH=$PATH:$1
+ else
+ PATH=$1:$PATH
+ fi
+ fi
+}
+pathmunge /bin after
+pathmunge /sbin after
+unset pathmunge
+"""
+ with open(pl_profile, 'w') as f:
+ f.write("export PS1='{}@\H \$ '\n".format(name))
+ f.write("{}\n".format(ld_preload_text))
+ f.write("export LD_PRELOAD=/etc/planetlab/lib/bind_public.so\n")
+ f.write("{}\n".format(usrmove_path_text))
+ f.write("{}\n".format(usrmove_path_code))
+
+ # make sure this file is sourced from both root's and slice's .profile
+ enforced_line = "[ -f /etc/planetlab.profile ] && source /etc/planetlab.profile\n"
+ for path in [ 'root/.profile', 'home/{}/.profile'.format(name) ]:
+ from_root = os.path.join(containerDir, path)
+ # if dir is not yet existing let's forget it for now
+ if not os.path.isdir(os.path.dirname(from_root)): continue
+ found = False
+ try:
+ with open(from_root) as f:
+ contents = f.readlines()
+ for content in contents:
+ if content == enforced_line:
+ found = True
+ except IOError:
+ pass
+ if not found:
+ with open(from_root, "a") as user_profile:
+ user_profile.write(enforced_line)
+ # in case we create the slice's .profile when writing
+ if from_root.find("/home") >= 0:
+ command = ['chown', '{}:slices'.format(name), from_root]
+ logger.log_call(command)