code-server injection
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
import os, uuid, json
|
||||
from flask import Blueprint, current_app, session, redirect, url_for, render_template, request, jsonify
|
||||
from ..services.backboard_service import realtime_response
|
||||
import subprocess
|
||||
|
||||
bp = Blueprint("vscode", __name__)
|
||||
|
||||
@@ -14,7 +15,7 @@ def desktop(user_uuid, course_id, chapter_name, lesson_name):
|
||||
if "user_uuid" not in session:
|
||||
user_uuid = "user_" + str(uuid.uuid4())
|
||||
session["user_uuid"] = user_uuid
|
||||
uuid2username[user_uuid] = "guest"+str(uuid.uuid4())
|
||||
uuid2username[user_uuid] = "guest"+str(uuid.uuid4())[0:5]
|
||||
username2uuid[uuid2username[user_uuid]] = user_uuid
|
||||
|
||||
# 全局映射
|
||||
@@ -23,15 +24,55 @@ def desktop(user_uuid, course_id, chapter_name, lesson_name):
|
||||
|
||||
# 按课程/章节创建工作目录
|
||||
base_root = current_app.config["STUDENT_WORKSPACE_ROOT"]
|
||||
path_dir = os.path.join(base_root, user_id, course_id, chapter_name)
|
||||
os.makedirs(path_dir, exist_ok=True)
|
||||
|
||||
user_home = os.path.join("/home", user_id)
|
||||
try:
|
||||
subprocess.run(["sudo", "useradd", "-m", "-d", user_home, user_id]) # 创建用户
|
||||
subprocess.run(["sudo", "chown", "-R", user_id, user_home]) # 设置目录权限为新用户
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Error creating user {user_id}: {e}")
|
||||
path_dir = os.path.join("/home", user_id, course_id, chapter_name, lesson_name)
|
||||
try:
|
||||
# 使用 sudo 执行 mkdir 命令来创建目录
|
||||
subprocess.run(["sudo", "-u", user_id, "mkdir", "-p", path_dir], check=True)
|
||||
print(f"Directory {path_dir} created successfully for user {user_id}")
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Error creating directory {path_dir} details {str(e)}")
|
||||
|
||||
|
||||
|
||||
code_server_port = 10000 + int(uuid.uuid4().int % 10000)
|
||||
try:
|
||||
subprocess.Popen([
|
||||
"sudo", "-u", user_id,
|
||||
"code-server", "--bind-addr", f"0.0.0.0:{code_server_port}",
|
||||
"--auth", "none", path_dir
|
||||
])
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Error start code-server at {code_server_port} with path{path_dir} {e}")
|
||||
|
||||
|
||||
caddy_conf = f"""
|
||||
handle_path /vsc{user_uuid}/* {{
|
||||
reverse_proxy localhost:{code_server_port}
|
||||
}}
|
||||
|
||||
|
||||
"""
|
||||
caddy_config_path = "/etc/caddy/Caddyfile"
|
||||
with open(caddy_config_path, "r") as f:
|
||||
lines = f.readlines()
|
||||
insert_position = len(lines) - 2 if len(lines) >= 2 else len(lines)
|
||||
lines.insert(insert_position, caddy_conf)
|
||||
with open(caddy_config_path, "w") as f:
|
||||
f.writelines(lines)
|
||||
try:
|
||||
subprocess.run(["sudo", "caddy", "reload", "--config", "/etc/caddy/Caddyfile"])
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Error reload caddy {e}")
|
||||
|
||||
# 写 .config(并按需要转换为 WSL 路径)
|
||||
cfg = current_app.config["VSCODE_WEB_PATH"]
|
||||
path_for_vscode = path_dir
|
||||
if cfg.get("is_wsl"):
|
||||
path_for_vscode = path_for_vscode.replace("\\", "/") \
|
||||
.replace(cfg.get("windows_path", ""), cfg.get("wsl_path", ""))
|
||||
|
||||
config_path = os.path.join(path_dir, ".config")
|
||||
tmpd = {
|
||||
@@ -41,14 +82,21 @@ def desktop(user_uuid, course_id, chapter_name, lesson_name):
|
||||
"lesson_name": lesson_name,
|
||||
"path": path_for_vscode
|
||||
}
|
||||
with open(config_path, "w", encoding="utf-8") as f:
|
||||
json.dump(tmpd, f, ensure_ascii=False)
|
||||
|
||||
current_app.logger.debug("config file path: %s", config_path)
|
||||
|
||||
config_json = json.dumps(tmpd, ensure_ascii=False)
|
||||
|
||||
# 使用 sudo 和 tee 命令将 JSON 数据写入文件
|
||||
subprocess.run(
|
||||
["sudo", "-u", user_id, "bash", "-c", f"echo '{config_json}' | tee {config_path} > /dev/null"],
|
||||
check=True
|
||||
)
|
||||
# 确保文件的所有权归 user_id
|
||||
subprocess.run(
|
||||
["sudo", "chown", f"{user_id}:{user_id}", config_path],
|
||||
check=True
|
||||
)
|
||||
return render_template(
|
||||
"desktop.html",
|
||||
vscode_web_url=current_app.config["VSCODE_WEB_URL"],
|
||||
vscode_web_url=current_app.config["VSCODE_WEB_URL"]+f"/vsc{user_uuid}",
|
||||
user_uuid=session["user_uuid"], course_id=course_id, chapter_name=chapter_name, lesson_name=lesson_name,
|
||||
workspace_path=path_for_vscode,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user