diff --git a/.hub/jupyter_config_backup.py b/.hub/jupyter_config_backup.py new file mode 100644 index 0000000..a909055 --- /dev/null +++ b/.hub/jupyter_config_backup.py @@ -0,0 +1,84 @@ +import os, grp, shutil, subprocess, configparser +from pathlib import Path +from jupyterhub.spawner import Spawner + +# host端的仓库目录 +SHARED_ROOT = Path("/home/zhangyi/jupyter-collection") +# jyputerhub用户home目录 +USER_HOME = Path("/home/jupyter-{username}") +# 分组信息路径 +CTRL_FILE = SHARED_ROOT / ".hub" / "resource_map.ini" + +# ========== 2. 读控制表 ========== +def load_ctrl(): + """返回 组->资源 和 组->用户 两个字典""" + cfg = configparser.ConfigParser() + cfg.read(CTRL_FILE) + res_map = {g: [r.strip() for r in v.split(",")] + for g, v in cfg.items("map")} + usr_map = {g: [u.strip() for u in v.split(",")] + for g, v in cfg.items("users")} + return res_map, usr_map + +# ========== 3. post_auth_hook:自动建用户+加组 ========== +def ensure_user_and_groups(authenticator, handler, authentication): + username = authentication['name'] + res_map, usr_map = load_ctrl() + + # 该用户应属的组 + wanted_groups = [g for g, users in usr_map.items() if username in users] + if not wanted_groups: # 控制文件里没写就什么都不做 + return authentication + + # 确保组存在 + for g in wanted_groups: + subprocess.run(["groupadd", "-f", g], check=False) + + # 若系统账号不存在则创建(Hub 自己会创 home,这里确保 shell 账号) + #if subprocess.run(["id", "-u", username], capture_output=True).returncode != 0: + # subprocess.run([ + # "useradd", "-m", "-s", "/bin/bash", + # "-d", str(USER_HOME).format(username=username), username + # ], check=False) + + # 加组(幂等) + for g in wanted_groups: + subprocess.run(["usermod", "-aG", g, username], check=False) + + return authentication + +c.Authenticator.post_auth_hook = ensure_user_and_groups + +# ========== 4. pre_spawn_hook:重建干净 home + 只读挂 Git 资源 ========== +def prepare_user(spawner: Spawner): + username = spawner.user.name + user_dir = Path(str(USER_HOME).format(username=username)) + + # 1. 重建空 home(保证无残留) + if user_dir.exists(): + shutil.rmtree(user_dir) + user_dir.mkdir(mode=0o700, parents=True, exist_ok=True) + + # 2. 读控制表 + res_map, _ = load_ctrl() + + # 3. 取系统组 + try: + gid_list = os.getgrouplist(username, grp.getpwnam(username).pw_gid) + except (KeyError, OSError): + return + user_groups = {grp.getgrgid(g).gr_name for g in gid_list} + + # 4. 挂载该用户该看的资源(只读) + shared = user_dir / "shared" + shared.mkdir(exist_ok=True) + for grp_name in user_groups: + for res in res_map.get(grp_name, []): + res_path = SHARED_ROOT / res + if res_path.is_dir(): + spawner.volumes[str(res_path)] = { + 'bind': str(shared / res), + 'mode': 'ro' # 重启即还原 + } + +c.Spawner.pre_spawn_hook = prepare_user \ No newline at end of file diff --git a/.hub/readme.md b/.hub/readme.md new file mode 100644 index 0000000..594ce4b --- /dev/null +++ b/.hub/readme.md @@ -0,0 +1,12 @@ +# jupyterhub相关配置说明 + +此文件夹包含了与jupyterhub有关的配置文件,其中: +1. **jupyter_config_backup.py** jupyterhub配置文件拷贝,使用时将此文件拷贝至host端相应路径后重启hub即可。 + +```shell +sudo cp jupyter_config_backup.py /opt/tljh/config/jupyter_config.d/99-group-template.py +``` + +相关的配置说明见文件内注释。 + +2. **resource_map.ini** 对不同组别可获取资源与各组别内用户组成进行配置。 \ No newline at end of file diff --git a/.hub/resource_map.ini b/.hub/resource_map.ini new file mode 100644 index 0000000..947116c --- /dev/null +++ b/.hub/resource_map.ini @@ -0,0 +1,10 @@ +# 第一个表定义了不同的组别可读取的资源路径名称 +# <组名> = <路径名>, <路径名> +[map] +PrincipleOfGeophysics = geophysics_basic +GeophysicalInversion = geophysics_basic, geophysics_advanced + +# 第二个表定义了每个组内的用户 用逗号区分 +[users] +PrincipleOfGeophysics = student1, student2, student3 +GeophysicalInversion = student4, student5 \ No newline at end of file diff --git a/geophysical_tutorials/gmsh_visualization.ipynb b/geophysics_advanced/gmsh_visualization.ipynb similarity index 100% rename from geophysical_tutorials/gmsh_visualization.ipynb rename to geophysics_advanced/gmsh_visualization.ipynb diff --git a/geophysical_tutorials/tri_mesh_ex.msh b/geophysics_advanced/tri_mesh_ex.msh similarity index 100% rename from geophysical_tutorials/tri_mesh_ex.msh rename to geophysics_advanced/tri_mesh_ex.msh diff --git a/geophysical_tutorials/vtk_visualization.ipynb b/geophysics_advanced/vtk_visualization.ipynb similarity index 100% rename from geophysical_tutorials/vtk_visualization.ipynb rename to geophysics_advanced/vtk_visualization.ipynb diff --git a/geophysical_tutorials/forward_sphere.ipynb b/geophysics_basic/forward_sphere.ipynb similarity index 100% rename from geophysical_tutorials/forward_sphere.ipynb rename to geophysics_basic/forward_sphere.ipynb