tmp
This commit is contained in:
@@ -3,70 +3,76 @@
|
||||
资源路径 /home/zhangyi/jupyter-collection
|
||||
控制文件 /home/zhangyi/jupyter-collection/.hub/resource_map.ini
|
||||
"""
|
||||
|
||||
import os, grp, pwd, shutil, subprocess, configparser
|
||||
from pathlib import Path
|
||||
from jupyterhub.spawner import Spawner
|
||||
|
||||
# ---------- 基础路径 ----------
|
||||
SHARED_ROOT = Path("/home/zhangyi/jupyter-collection") # Git 仓库
|
||||
USER_HOME = Path("/home/jupyter-{username}")
|
||||
CTRL_FILE = SHARED_ROOT / ".hub" / "resource_map.ini"
|
||||
# ---------- 路径常量 ----------
|
||||
SHARED_ROOT = Path("/home/zhangyi/jupyter-collection") # Git 资源仓库
|
||||
USER_HOME = Path("/home/jupyter-{username}") # 用户家目录模板
|
||||
CTRL_FILE = SHARED_ROOT / ".hub" / "resource_map.ini" # 组-资源-用户映射
|
||||
|
||||
# ---------- 工具:读控制表 ----------
|
||||
def load_ctrl():
|
||||
"""返回 组->资源 和 组->用户 两个字典"""
|
||||
"""返回 (组->资源, 组->用户) 两个 dict"""
|
||||
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")}
|
||||
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
|
||||
|
||||
# ---------- post_auth_hook:自动建用户+加组 ----------
|
||||
# ========== 最早钩子:预创建家目录 ==========
|
||||
def ensure_homedir(spawner):
|
||||
"""systemd 启动前保证目录存在且属主正确"""
|
||||
username = spawner.user.name
|
||||
user_dir = Path(str(USER_HOME).format(username=username))
|
||||
if not user_dir.exists():
|
||||
user_dir.mkdir(mode=0o700, parents=True)
|
||||
shutil.chown(user_dir, user=username, group=username)
|
||||
|
||||
c.Spawner.pre_spawn_hook = ensure_homedir
|
||||
|
||||
# ========== 认证后钩子:自动建用户+加组 ==========
|
||||
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 # 控制文件里没有就什么都不做
|
||||
return authentication
|
||||
|
||||
# 确保组存在
|
||||
for g in wanted_groups:
|
||||
for g in wanted_groups: # 确保组存在
|
||||
subprocess.run(["groupadd", "-f", g], check=False)
|
||||
|
||||
# 系统账号不存在就创建(TLJH 会自己建 home,这里只确保用户存在)
|
||||
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:
|
||||
for g in wanted_groups: # 加组
|
||||
subprocess.run(["usermod", "-aG", g, username], check=False)
|
||||
|
||||
return authentication
|
||||
|
||||
c.Authenticator.post_auth_hook = ensure_user_and_groups
|
||||
|
||||
# ---------- pre_spawn_hook:只清 shared 并挂载 ----------
|
||||
def prepare_user(spawner: Spawner):
|
||||
# ========== spawn 钩子:清 shared + 只读挂载 ==========
|
||||
def prepare_user(spawner):
|
||||
username = spawner.user.name
|
||||
user_dir = Path(str(USER_HOME).format(username=username))
|
||||
|
||||
# 1. 只清 shared 目录,保留用户其它文件
|
||||
# 仅清 shared,保留用户其它文件
|
||||
shared = user_dir / "shared"
|
||||
if shared.exists():
|
||||
shutil.rmtree(shared)
|
||||
shared.mkdir(parents=True, exist_ok=True)
|
||||
shutil.chown(shared, user=username, group=username)
|
||||
|
||||
# 2. 读控制表
|
||||
# 读取控制表
|
||||
res_map, _ = load_ctrl()
|
||||
|
||||
# 3. 取系统组
|
||||
# 获取用户系统组
|
||||
try:
|
||||
pwnam = pwd.getpwnam(username)
|
||||
gid_list = os.getgrouplist(username, pwnam.pw_gid)
|
||||
@@ -74,7 +80,7 @@ def prepare_user(spawner: Spawner):
|
||||
return
|
||||
user_groups = {grp.getgrgid(g).gr_name for g in gid_list}
|
||||
|
||||
# 4. 组装 bind_mounts(SystemdSpawner 语法)
|
||||
# 组装 bind_mounts(SystemdSpawner 语法)
|
||||
bind_list = []
|
||||
for grp_name in user_groups:
|
||||
for res in res_map.get(grp_name, []):
|
||||
|
||||
Reference in New Issue
Block a user