On Friday, July 21, 2017 at 9:16:06 AM UTC-4, Min RK wrote: > > On Thu, Jul 20, 2017 at 9:46 PM, Mike Bopf <mike...@gmail.com > <javascript:>> wrote: > > I have JupyterHub working for a individual users using SystemUserSpawner >> via a PAMAuthentication. However, I'd like to be able to share certain >> Jupyter Notebooks between different users, realizing that we could step on >> each other. One solution would be to enable UNIX groups inside Jupyterhub, >> but the "load_group" configuration item isn't working as I'd expect. This >> is what I have in the jupyterhub_config.py: >> >> c.JupyterHub.load_groups = { 'ourgroup': [ 'mike', 'dave', 'tom' ] } >> >> "ourgroup" is an existing UNIX group on the server and mike, dave and tom >> are existing users with access to that group. If I bring up a Terminal >> inside Jupyter, the "whoami" command returns "mike", but the "groups" >> command also returns "mike". I'd like my group to be "ourgroup", instead, >> or at least add "ourgroup" to my list of groups. I can create and edit >> files owned by mike, but not 775 files with group "ourgroup". >> Unsurprisingly, an "ls -l" of a file with group "ourgroup" just lists the >> groupId number, not "ourgroup". >> > JupyterHub groups are an internal concept, and probably aren’t relevant to > you if you already have unix groups and permissions set up. I think the > main missing thing is setting the group or groups of the process spawned in > docker. > > The LocalProcessSpawner sets the groups of the process with os.setgroups() > <https://github.com/jupyterhub/jupyterhub/blob/0.7.2/jupyterhub/spawner.py#L652-L663>. > > SystemUserSpawner lacks this logic. You can tell docker to launch a > container with a specific user id and gid via the user argument. The > docker-stacks also support setting UID and GID at runtime, but doing so > requires that the container initially start as root. Here’s how to set up > uid + gid, assuming your image is based on one of the docker-stacks > <https://github.com/jupyter/docker-stacks>: > > import pwdimport grp > from dockerspawner import SystemUserSpawner > class SystemGroupSpawner(SystemUserSpawner): > > # local unix groups a user might be a member of > groups = ['admin'] > > def get_env(self): > env = super().get_env() > # don't set USER env, which SystemUserSpawner uses. > env.pop('USER', None) > # set notebook UID > env['NB_UID'] = self.user_id > for groupname in self.groups: > group = grp.getgrnam(groupname) > # find the first group in our group list that the user is a > member of, > # and set the group id > if self.user.name in group.gr_mem: > env['NB_GID'] = group.gr_gid > return env > # Select our custom Spawner > c.JupyterHub.spawner_class = SystemGroupSpawner# Select one of the > docker-stacks (https://github.com/jupyter/docker-stacks) > c.SystemGroupSpawner.container_image = 'jupyter/base-notebook' > # must start container as root in order for docker-stacks to set up NB_UID / > NB_GID correctly > c.SystemGroupSpawner.extra_create_kwargs = {'user': 'root'} > # This line should be redundant with above,# but there's a bug in > docker-stacks assuming $UID is the user id# BUG: > https://github.com/jupyter/docker-stacks/pull/420 > c.SystemGroupSpawner.environment = {'UID': '0'} > > as a gist <https://gist.github.com/minrk/b9103e935052a70ba00dc93e06be6636> > > -Min > Thanks so much for the quick reply! However, it's still not doing what I want. When I run it with my group name ('ceb'), I end up being logged in as user "jovyan" and group "users". I also end up in an empty, jupyter-local version of /home/{username} instead of my home directory on the host. That's how it works with the default
I'm not sure if it matters, but I had to modify the networking stuff, including using port 8443 for the SSL to work on our server. I'm also using PAM authentication instead of GitHub. Here's my config (same as attached file): jupyterhub_configMWB.py as gist <https://gist.github.com/mbopf/0464e407de7e6bbbaf9097f3db631fce#file-jupyterhub_configmwb-py> I'm relatively new to Python, but maybe popping off the entire USER env causes problems especially given my authentication method. Would it make more sense for me to create a custom Dockerfile that handles the group permissions differently (i.e., doesn't create "jovyan" and "users")? Thanks again for all your help, mike > -- You received this message because you are subscribed to the Google Groups "Project Jupyter" group. To unsubscribe from this group and stop receiving emails from it, send an email to jupyter+unsubscr...@googlegroups.com. To post to this group, send email to jupyter@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/jupyter/b9f80194-b888-42f8-88a9-34da8886d907%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
# Configuration file for jupyterhub. ## From MinRK - see: https://gist.github.com/minrk/b9103e935052a70ba00dc93e06be6636 #------------------------------------------------------ import pwd import grp from dockerspawner import SystemUserSpawner class SystemGroupSpawner(SystemUserSpawner): # local unix groups a user might be a member of groups = ['ceb'] def get_env(self): env = super().get_env() # don't set USER env, which SystemUserSpawner uses. env.pop('USER', None) # set notebook UID env['NB_UID'] = self.user_id for groupname in self.groups: group = grp.getgrnam(groupname) # find the first group in our group list that the user is a member of, # and set the group id if self.user.name in group.gr_mem: env['NB_GID'] = group.gr_gid return env # Select our custom Spawner c.JupyterHub.spawner_class = SystemGroupSpawner # Select one of the docker-stacks (https://github.com/jupyter/docker-stacks) c.SystemGroupSpawner.container_image = 'jupyter/base-notebook' # must start container as root in order for docker-stacks to set up NB_UID / NB_GID correctly c.SystemGroupSpawner.extra_create_kwargs = {'user': 'root'} # This line should be redundant with above, # but there's a bug in docker-stacks assuming $UID is the user id # BUG: https://github.com/jupyter/docker-stacks/pull/420 c.SystemGroupSpawner.environment = {'UID': '0'} ## The public facing port of the proxy c.JupyterHub.port = 8443 # networking stuff below here (yours may differ) #import netifaces #docker_ip = netifaces.ifaddresses('en0')[netifaces.AF_INET][0]['addr'] #c.JupyterHub.hub_ip = docker_ip #c.SystemGroupSpawner.hub_connect_ip = docker_ip # c.SystemGroupSpawner.host_homedir_format_string = '/tmp/{username}' #------------------------------------------------------ import netifaces docker0 = netifaces.ifaddresses('docker0') docker0_ipv4 = docker0[netifaces.AF_INET][0] c.JupyterHub.hub_ip = docker0_ipv4['addr'] c.SystemGroupSpawner.hub_connect_ip = docker0_ipv4['addr'] ## The config file to load c.JupyterHub.config_file = '/opt/jupyterhub/jupyterhub_config.py' # Loaded from the CONFIGPROXY_AUTH_TOKEN env variable by default. c.JupyterHub.proxy_auth_token = '<redacted>' ## Path to SSL certificate file for the public facing interface of the proxy c.JupyterHub.ssl_key = '<redacted>' ## Path to SSL key file for the public facing interface of the proxy c.JupyterHub.ssl_cert = '<redacted>' ## The name of the PAM service to use for authentication c.PAMAuthenticator.service = 'sshd' ## Whitelist of usernames that are allowed to log in. c.Authenticator.whitelist = {'mbopf', 'rlong'} # Defaults to an empty set, in which case no user has admin access. c.Authenticator.admin_users = {'mbopf'}