chore: initial project import

This commit is contained in:
justme committed 2026-10-04 21:46:39 +08:00
commit 3fc4e5ca53
347 files changed
+56172

No files matched your search

+77
View File
@@ -0,0 +1,77 @@
"""跨机器的真实链路验证:Windows 上的 Probe(NativeAOT exe)→ WSL2 里的 Agent 和 Backend(真实的虚拟网络、不同的单调时钟原点)。
前提:WSL 里有 Debian(root)、tc(netem 注入丢包/延迟/黑洞用);已经用 scripts/publish.sh 发布了 linux-x64 的 agent、backend、fleet-enroll,
并且 Windows 上发布了 probe(dotnet publish backend/probe/src/Monitor.Probe -c Release -r win-x64 -p:PublishAot=true -o backend/artifacts/aot-probe)。
把 linux-x64 的产物复制到 WSL 的 /root/mon/,在 WSL 里用 setsid -f nohup 启动 monitor-backend(监听 0.0.0.0:29181),再运行本脚本。
故障注入见 docs/deployment.md 第 3 节。
"""
import json, os, subprocess, sys, time, urllib.request, urllib.error
# 要连的是本机的虚拟网络(WSL),不能走环境变量里的 HTTP(S)_PROXY
OPENER = urllib.request.build_opener(urllib.request.ProxyHandler({}))
ROOT = r"C:\Users\JustMe\Desktop\monitor-proj"
PROBE_EXE = os.path.join(ROOT, "backend", "artifacts", "aot-probe", "monitor-probe.exe")
WORK = r"C:\Users\JustMe\AppData\Local\Temp\realnet"
PORT = 29181
def wsl(cmd, check=True):
r = subprocess.run(["wsl", "-d", "Debian", "-u", "root", "-e", "bash", "-c", cmd], capture_output=True, text=True)
if check and r.returncode != 0:
print("WSL FAILED:", cmd, r.stdout, r.stderr)
raise SystemExit(1)
return r.stdout.strip()
WSLIP = wsl("ip -4 addr show eth0 | grep -oP '(?<=inet )[0-9.]+'")
BASE = f"http://{WSLIP}:{PORT}"
def req(method, path, body=None, headers=None, ctype="application/json"):
data = None if body is None else json.dumps(body).encode()
h = {"Content-Type": ctype}
h.update(headers or {})
r = urllib.request.Request(BASE + path, data=data, method=method, headers=h)
try:
with OPENER.open(r, timeout=30) as resp:
text = resp.read().decode()
return resp, (json.loads(text) if text else None)
except urllib.error.HTTPError as e:
print("HTTP", e.code, e.read().decode())
raise
def main():
os.makedirs(WORK, exist_ok=True)
print("wsl ip", WSLIP)
resp, login = req("POST", "/api/admin/auth/login", {"username": "admin", "password": os.environ.get("MONITOR_ADMIN_PASSWORD", "correct horse battery")})
cookie = resp.headers["Set-Cookie"].split(";")[0]
_, tok = req("POST", "/api/admin/api-tokens", {"name": "net", "scope": "admin"}, {"Cookie": cookie, "X-CSRF-Token": login["csrf_token"]})
auth = {"Authorization": "Bearer " + tok["plaintext"]}
json.dump({"base": BASE, "token": tok["plaintext"], "wslip": WSLIP}, open(WORK + r"\state.json", "w"))
_, join = req("POST", "/api/admin/join-tokens", {"auto_approve": True, "max_uses": 1, "expires_in_hours": 1}, auth)
wsl("pkill monitor-agent; cd /root/mon && rm -rf id agent.json")
print(wsl(f"cd /root/mon && ./fleet-enroll --server http://127.0.0.1:{PORT} --join {join['plaintext']} --name wsl-agent --identity-dir /root/mon/id"))
cfg = {"fleet": {"server": f"http://127.0.0.1:{PORT}", "identity_dir": "/root/mon/id"}, "listen": {"bind": "0.0.0.0"}}
wsl("cat > /root/mon/agent.json <<'EOF'\n" + json.dumps(cfg) + "\nEOF")
wsl("cd /root/mon && (setsid nohup ./monitor-agent --config /root/mon/agent.json > agent.log 2>&1 < /dev/null &)")
time.sleep(3)
_, agents = req("GET", "/api/admin/agents", None, auth)
agent = agents["items"][0]
print("agent", agent["id"], agent["status"], "online", agent.get("online"))
# the backend only sees 127.0.0.1 as the agent's address: the panel needs the address the probe can reach
req("PATCH", "/api/admin/agents/" + agent["id"], {"public_host": WSLIP}, auth, "application/merge-patch+json")
_, ident = req("POST", "/api/admin/probes", {"name": "home"}, auth)
print("bootstrap", ident["bootstrap"])
os.makedirs(WORK + r"\probe", exist_ok=True)
json.dump(ident, open(WORK + r"\probe\probe.json", "w"))
json.dump({"base": BASE, "token": tok["plaintext"], "wslip": WSLIP, "agent_id": agent["id"]}, open(WORK + r"\state.json", "w"))
log = open(WORK + r"\probe.log", "w")
p = subprocess.Popen([PROBE_EXE, "--config", WORK + r"\probe\probe.json"], stdout=log, stderr=subprocess.STDOUT)
open(WORK + r"\probe.pid", "w").write(str(p.pid))
print("probe pid", p.pid)
main()