feat: 多租户隔离-技能运行时目录改机构工作目录(ensure_org_skills从全局模板复制)

This commit is contained in:
yumoqing 2026-08-16 15:51:32 +08:00
parent 69184cb4a5
commit 5ff1358116
2 changed files with 39 additions and 4 deletions

View File

@ -31,7 +31,36 @@ def get_skills_base():
SKILLS_BASE = get_skills_base()
PACKS_DIR = os.path.join(SKILLS_BASE, "packs")
ALL_DIR = os.path.join(SKILLS_BASE, "global") # 公共技能 = 选装的技能源头
ALL_DIR = os.path.join(SKILLS_BASE, "global") # 公共技能 = 全局模板(源头)
def get_org_skills_dir(workspace_base, org_id):
"""机构工作目录下的技能根目录(多租户隔离)。
workspace_base: 机构工作目录根 /d/pipeline/workspaces params workspace_base
org_id: 机构 ID
返回 <workspace_base>/<org_id>/skills
"""
return os.path.normpath(os.path.join(workspace_base, str(org_id or '0'), "skills"))
def ensure_org_skills(workspace_base, org_id):
"""确保机构工作目录的 skills/ 已初始化(首次从全局模板复制公共技能 + 技能集清单)。
多租户隔离运行时技能必须落在机构工作目录不能读全局应用目录的 skills/
返回机构技能根目录
"""
org_skills = get_org_skills_dir(workspace_base, org_id)
os.makedirs(org_skills, exist_ok=True)
# 复制公共技能global
if not os.path.isdir(os.path.join(org_skills, "global")):
if os.path.isdir(ALL_DIR):
shutil.copytree(ALL_DIR, os.path.join(org_skills, "global"))
# 复制技能集清单packs
if not os.path.isdir(os.path.join(org_skills, "packs")):
if os.path.isdir(PACKS_DIR):
shutil.copytree(PACKS_DIR, os.path.join(org_skills, "packs"))
return org_skills
def list_packs():

View File

@ -33,10 +33,16 @@ except Exception:
if not org_id:
return json.dumps({"success": False, "error": "用户未关联机构"}, ensure_ascii=False)
# 技能根目录skill_loader 的 base_dir相对进程 cwd
base_dir = os.environ.get("PIPELINE_SKILLS_BASE", "skills")
from pipeline_core.skill_pack import list_packs, install_pack, uninstall_pack, installed_packs, ensure_org_skills
from pipeline_service.workspace import get_workspace_base
from pipeline_core.skill_pack import list_packs, install_pack, uninstall_pack, installed_packs
# 机构技能根目录(多租户隔离:机构工作目录/skills/,不在全局应用目录)
try:
async with DBPools().sqlorContext(dbname) as sor:
ws_base = await get_workspace_base(sor)
base_dir = ensure_org_skills(ws_base, org_id)
except Exception:
base_dir = os.environ.get("PIPELINE_SKILLS_BASE", "skills")
if action == 'list':
return json.dumps({"success": True, "is_admin": is_admin, "packs": list_packs()},