def launch_user_instance(user, config): """ Launches an IPython Notebook for a specified user in an environment defined by config. Parameters ---------- user: `dict` A dictionary as parsed from the database describing a user. config: `dict` A dictionary as parsed from the configuration file. """ # must not fail, should have been taken care of by setup script pw_entry = pwd.getpwnam(user["username"]) # assume student user status and launch notebook # because the notebook kernel runs inside of screen we cannot catch errors # (unless we pipe the output into a file or we could pipe the commands and # then detach, TODO) args = ["screen", "-dmS", user["username"], "ipython", "notebook", "--ip", "'*'", "--port", user["port"], "--certfile", config["certificate"], "--profile", config["profile"], # "--pylab", "inline", "--no-browser"] cwd = os.path.join(pw_entry.pw_dir, config["launch dir"]) # should not fail gutil.launch_as(pw_entry, args, cwd)
def create_user_environment(user, config): """ Sets up the user working directories as needed. Creates a user account if necessary, creates a password for it, adds it to a general usergroup, creates an IPython profile, and makes the user the owner of those files and directories. Parameters ---------- user: `dict` A dictionary as parsed from the database describing a user. config: `dict` A dictionary as parsed from the configuration file. """ # check for existance of user try: pw_entry = pwd.getpwnam(user["username"]) except KeyError: # add a new user rc = usrt.add_user(user["username"], [config["group"]]) if rc != 0: return rc # set the (weak) password using numbers, letters, and the exclamation # mark if not user["sys-pass"]: user["sys-pass"] = u"".join(random.choice(config["passwd selection"])\ for x in range(config["passwd length"])) rc = usrt.add_password(user["username"], user["sys-pass"]) if rc != 0: return rc # should not fail now pw_entry = pwd.getpwnam(user["username"]) # potentially add the user to the desired (supplementary) group grp_entry = grp.getgrnam(config["group"]) if not user["nb-pass"]: user["nb-pass"] = u"".join(random.choice(config["passwd selection"])\ for x in range(config["passwd length"])) if not user["username"] in grp_entry.gr_mem: usrt.append_to_group(config["group"], user["username"]) # create the ipython config cmd = ["ipython", "profile", "create", config["profile"]] try: gutil.launch_as(pw_entry, cmd, pw_entry.pw_dir) except subprocess.CalledProcessError as err: LOGGER.debug(u"pssst:", exc_info=True) LOGGER.warn(err.output.strip()) return err.returncode # location of the ipython directory created with the profile # get_ipython_dir currently returns different results for other users :S cmd = ["ipython_dir"] user_ipython_dir = gutil.launch_as(pw_entry, cmd, os.getcwd()).strip() # if the specified profile exists we copy the contents profile = "profile_{0}".format(config["profile"]) prfl_loc = os.path.join(get_ipython_dir(), profile) usr_prfl_loc = os.path.join(user_ipython_dir, profile) if os.path.exists(prfl_loc): # copy profile files for filename in glob(os.path.join(prfl_loc, "*.py")): shutil.copy2(filename, usr_prfl_loc) dst_file = os.path.join(usr_prfl_loc, os.path.basename(filename)) os.chown(dst_file, pw_entry.pw_uid, pw_entry.pw_gid) # copy startup files for filename in glob(os.path.join(prfl_loc, "startup", "*.py")): shutil.copy2(filename, usr_prfl_loc) dst_file = os.path.join(usr_prfl_loc, os.path.basename(filename)) os.chown(dst_file, pw_entry.pw_uid, pw_entry.pw_gid) password = passwd(user["nb-pass"]) location = os.path.join(usr_prfl_loc, u"ipython_notebook_config.py") with codecs.open(location, "rb", encoding="utf-8") as file_handle: content = file_handle.readlines() if content: i = 0 for (i, line) in enumerate(content): if line.find(u"c.NotebookApp.password") > -1: break content[i] = u"c.NotebookApp.password = u'{0}'".format(password) with codecs.open(location, "wb", encoding="utf-8") as file_handle: file_handle.writelines(content)