I am running a Jupyterhub server that spawn’s docker images. Our user accounts are not local, but are authenticated through PAM/SSSD Active Directory accounts. Home directories are NFS mounts.
As a pre-spawn hook, I am creating a notebook directory in the user’s home directory on the host system:
def create_dir_hook(spawner):
username = spawner.user.name # get the username
home_path = os.path.join(‘/nfs/home/’, username)
volume_path = os.path.join(home_path, ‘notebooks’)
if not os.path.exists(volume_path):
os.mkdir(volume_path, 0o755)
And then binding volume between the docker image and the users’ actual home directory so the notebooks survive reboots:
The problem is that on the host system, the owner for that notebook directory is not correct. If I set spawner_class to be dockerspawner.DockerSpawner the user who owns the files is the local user that jupyterhub is running under, let’s call that user hubuser. And ff I set the spawner_class to be dockerspawner.SystemUserSpawner then root owns the files.
Is there a way to create the directory with the proper ownership say something like myaduser:users?
I did get this working, eventually. I had the chown in my script already but I also had to update the NBUID and NBGID values so my pre-spawn hook (for a DockerSpawner) looks like:
def create_dir_hook(spawner):
""" Create directory in users home directory if it doesn't exist
For data persistence """
username = spawner.user.name # get the username
command1 = ["id", "-u", spawner.user.name]
command2 = ["id", "-g", spawner.user.name]
result = subprocess.check_output(command1, text=True, stderr=subprocess.PIPE)
uid = int(result.strip())
result = subprocess.check_output(command2, text=True, stderr=subprocess.PIPE)
gid = int(result.strip())
spawner.environment['NB_UID'] = str(uid)
spawner.environment['NB_GID'] = str(gid)
home_path = os.path.join('/nfs/home/', username)
jupyterhub_path = os.path.join(home_path, 'jupyterhub')
notebook_path = os.path.join(jupyterhub_path, 'notebooks')
pip_path = os.path.join(jupyterhub_path, 'pip')
if not os.path.exists(jupyterhub_path):
os.mkdir(jupyterhub_path, 0o755)
os.chown(jupyterhub_path, uid, gid)
os.mkdir(notebook_path, 0o755)
os.chown(notebook_path, uid, gid)
os.mkdir(pip_path, 0o755)
os.chown(pip_path, uid, gid)
c.DockerSpawner.pre_spawn_hook = create_dir_hook
This could of course be cleaned up some to use os.mkdirs. Also, I’m using the system id command here because the users are Active Directory users and not local users so they aren’t in passwd