mirror of
https://gitee.com/xmz7891/ykxmz.git
synced 2026-10-18 10:10:43 +00:00
修 devssh:定义了 HOST_FALLBACKS 却从来没用过
随身 WiFi 跟着教室网络走,地址会在 192.168.2.156 和
192.168.10.105 之间变。devssh.py 里明明定义了 HOST_FALLBACKS,
但 run / upload / download 三个函数**全都直接用 HOST** ——
于是设备一换网段就全部连不上,而且报的是连接超时,
看起来像设备挂了。
现在改成按候选列表顺序试:
环境变量 YKXMZ_DEV_HOST 优先
-> 192.168.2.156(当前)
-> 192.168.10.105(换网前用过)
并记住上次通的那个,后续调用不用每次从头试。
连上时打一行 `[devssh] 连上 x.x.x.x`,免得以后又搞不清连的是哪台。
还加了 `--probe` 子命令,一句话看现在哪个地址能用:
python _build/devssh.py --probe
实测:192.168.2.156 通、192.168.10.105 不通,自动选中前者。
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
修 devssh:定义了 HOST_FALLBACKS 却从来没用过
|
||||
|
||||
随身 WiFi 跟着教室网络走,地址会在 192.168.2.156 和
|
||||
192.168.10.105 之间变。devssh.py 里明明定义了 HOST_FALLBACKS,
|
||||
但 run / upload / download 三个函数**全都直接用 HOST** ——
|
||||
于是设备一换网段就全部连不上,而且报的是连接超时,
|
||||
看起来像设备挂了。
|
||||
|
||||
现在改成按候选列表顺序试:
|
||||
环境变量 YKXMZ_DEV_HOST 优先
|
||||
-> 192.168.2.156(当前)
|
||||
-> 192.168.10.105(换网前用过)
|
||||
并记住上次通的那个,后续调用不用每次从头试。
|
||||
连上时打一行 `[devssh] 连上 x.x.x.x`,免得以后又搞不清连的是哪台。
|
||||
|
||||
还加了 `--probe` 子命令,一句话看现在哪个地址能用:
|
||||
|
||||
python _build/devssh.py --probe
|
||||
|
||||
实测:192.168.2.156 通、192.168.10.105 不通,自动选中前者。
|
||||
+89
-27
@@ -4,38 +4,100 @@
|
||||
用法:
|
||||
python _build/devssh.py "命令" # 跑一条命令
|
||||
python _build/devssh.py --script 文件 # 跑一段脚本
|
||||
|
||||
== 地址会自动试 ==
|
||||
|
||||
这台设备跟着教室网络走,地址会变:
|
||||
192.168.2.156 <-> 192.168.10.105
|
||||
所以这里**按顺序试多个地址**,谁先连通就用谁,不用改代码。
|
||||
|
||||
想强制指定就用环境变量:
|
||||
$env:YKXMZ_DEV_HOST = "192.168.10.105"
|
||||
|
||||
⚠ 以前的坑:定义了 HOST_FALLBACKS 但**三个函数都直接用 HOST**,
|
||||
那个常量根本没被用过。于是设备一换网段就全部连不上,
|
||||
而且报的是「Connection refused / timed out」,看起来像设备挂了。
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
import paramiko
|
||||
|
||||
# 随身 WiFi(Debian)的地址。
|
||||
#
|
||||
# 这台设备跟着教室网络走,地址会变:
|
||||
# 192.168.2.156 -> 192.168.10.105(换网络了)
|
||||
# 所以优先读环境变量 YKXMZ_DEV_HOST,没有才用下面的默认值。
|
||||
# 换网络时不用改代码:
|
||||
# $env:YKXMZ_DEV_HOST = "192.168.10.105"
|
||||
import os
|
||||
|
||||
HOST = os.environ.get("YKXMZ_DEV_HOST", "192.168.10.105")
|
||||
USER = "root"
|
||||
PASSWORD = os.environ.get("YKXMZ_DEV_PASS", "1313144")
|
||||
|
||||
# 旧地址留一份,方便回退或同时探测
|
||||
HOST_FALLBACKS = ("192.168.10.105", "192.168.2.156")
|
||||
# 候选地址,按顺序试。
|
||||
# 环境变量优先(想锁定时用),然后是最近见过的两个地址。
|
||||
_CANDIDATES: list[str] = []
|
||||
|
||||
|
||||
def _build_candidates() -> list[str]:
|
||||
out = []
|
||||
env_host = (os.environ.get("YKXMZ_DEV_HOST") or "").strip()
|
||||
if env_host:
|
||||
out.append(env_host)
|
||||
for host in ("192.168.2.156", # 当前地址
|
||||
"192.168.10.105"): # 换网络前用过
|
||||
if host not in out:
|
||||
out.append(host)
|
||||
return out
|
||||
|
||||
|
||||
CANDIDATES = _build_candidates()
|
||||
HOST = CANDIDATES[0] # 兼容老代码:默认取第一个
|
||||
HOST_FALLBACKS = tuple(CANDIDATES[1:])
|
||||
|
||||
# 记住这次连通的是哪个,后续调用不用每次从头试
|
||||
_CONNECTED: str | None = None
|
||||
|
||||
|
||||
def _connect(timeout: int = 15):
|
||||
"""按候选顺序连,返回 (client, host)。全都不通才抛异常。"""
|
||||
global _CONNECTED
|
||||
order = list(CANDIDATES)
|
||||
if _CONNECTED and _CONNECTED in order:
|
||||
# 上次通的那个排最前,省一次失败尝试
|
||||
order.remove(_CONNECTED)
|
||||
order.insert(0, _CONNECTED)
|
||||
|
||||
errors = []
|
||||
for host in order:
|
||||
client = paramiko.SSHClient()
|
||||
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
try:
|
||||
client.connect(host, username=USER, password=PASSWORD,
|
||||
timeout=timeout, banner_timeout=20,
|
||||
auth_timeout=20, look_for_keys=False,
|
||||
allow_agent=False)
|
||||
if _CONNECTED != host:
|
||||
print(f" [devssh] 连上 {host}")
|
||||
_CONNECTED = host
|
||||
return client, host
|
||||
except Exception as exc: # noqa: BLE001
|
||||
errors.append(f"{host}: {type(exc).__name__} {exc}")
|
||||
try:
|
||||
client.close()
|
||||
except Exception: # noqa: BLE001
|
||||
pass
|
||||
raise RuntimeError("所有候选地址都连不上:\n " + "\n ".join(errors))
|
||||
|
||||
|
||||
def probe() -> str | None:
|
||||
"""探一下现在哪个地址能用(不抛异常)。"""
|
||||
try:
|
||||
client, host = _connect(timeout=8)
|
||||
client.close()
|
||||
return host
|
||||
except Exception: # noqa: BLE001
|
||||
return None
|
||||
|
||||
|
||||
def run(command: str, timeout: int = 600, quiet: bool = False) -> tuple:
|
||||
client = paramiko.SSHClient()
|
||||
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
client.connect(HOST, username=USER, password=PASSWORD, timeout=15,
|
||||
banner_timeout=20, auth_timeout=20,
|
||||
look_for_keys=False, allow_agent=False)
|
||||
client, _host = _connect()
|
||||
try:
|
||||
_stdin, stdout, stderr = client.exec_command(command, timeout=timeout)
|
||||
out = stdout.read().decode("utf-8", "replace")
|
||||
@@ -52,10 +114,7 @@ def run(command: str, timeout: int = 600, quiet: bool = False) -> tuple:
|
||||
|
||||
|
||||
def upload(local: str, remote: str, mode: int = 0o644) -> None:
|
||||
client = paramiko.SSHClient()
|
||||
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
client.connect(HOST, username=USER, password=PASSWORD, timeout=15,
|
||||
look_for_keys=False, allow_agent=False)
|
||||
client, _host = _connect()
|
||||
try:
|
||||
sftp = client.open_sftp()
|
||||
sftp.put(local, remote)
|
||||
@@ -67,10 +126,7 @@ def upload(local: str, remote: str, mode: int = 0o644) -> None:
|
||||
|
||||
|
||||
def download(remote: str, local: str) -> None:
|
||||
client = paramiko.SSHClient()
|
||||
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
client.connect(HOST, username=USER, password=PASSWORD, timeout=15,
|
||||
look_for_keys=False, allow_agent=False)
|
||||
client, _host = _connect()
|
||||
try:
|
||||
sftp = client.open_sftp()
|
||||
sftp.get(remote, local)
|
||||
@@ -83,13 +139,19 @@ def download(remote: str, local: str) -> None:
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) < 2:
|
||||
print(__doc__)
|
||||
print(" 候选地址: %s" % ", ".join(CANDIDATES))
|
||||
print(" 现在能连的: %s" % (probe() or "(一个都不通)"))
|
||||
sys.exit(1)
|
||||
if sys.argv[1] == "--script":
|
||||
run(Path(sys.argv[2]).read_text(encoding="utf-8"), timeout=600)
|
||||
elif sys.argv[1] == "--probe":
|
||||
got = probe()
|
||||
print(" 能连的地址: %s" % (got or "(一个都不通)"))
|
||||
sys.exit(0 if got else 1)
|
||||
else:
|
||||
args = sys.argv[1:]
|
||||
timeout = 600
|
||||
if args and args[0] == '--timeout':
|
||||
if args and args[0] == "--timeout":
|
||||
timeout = int(args[1])
|
||||
args = args[2:]
|
||||
run(" ".join(args), timeout=timeout)
|
||||
sys.exit(run(" ".join(args), timeout=timeout)[0])
|
||||
|
||||
@@ -309,3 +309,24 @@ time code ms
|
||||
2026-10-07 19:00:44 200 1199
|
||||
2026-10-07 19:01:00 200 1335
|
||||
2026-10-07 19:01:17 200 1437
|
||||
2026-10-07 19:01:33 200 1430
|
||||
2026-10-07 19:01:50 200 1414
|
||||
2026-10-07 19:02:06 200 1146
|
||||
2026-10-07 19:02:22 200 1079
|
||||
2026-10-07 19:02:38 200 1429
|
||||
2026-10-07 19:02:54 200 1057
|
||||
2026-10-07 19:03:11 200 1479
|
||||
2026-10-07 19:03:27 200 1129
|
||||
2026-10-07 19:03:44 200 1790
|
||||
2026-10-07 19:04:00 200 1420
|
||||
2026-10-07 19:04:18 200 2459
|
||||
2026-10-07 19:04:34 200 1148
|
||||
2026-10-07 19:04:50 200 1420
|
||||
2026-10-07 19:05:06 200 1085
|
||||
2026-10-07 19:05:23 200 1428
|
||||
2026-10-07 19:05:39 200 1017
|
||||
2026-10-07 19:05:55 200 1427
|
||||
2026-10-07 19:06:11 200 1085
|
||||
2026-10-07 19:06:27 200 1139
|
||||
2026-10-07 19:06:44 200 1036
|
||||
2026-10-07 19:06:59 200 833
|
||||
|
||||
|
@@ -0,0 +1,39 @@
|
||||
#!/bin/bash
|
||||
# relay-stability 停了,看它留下了什么
|
||||
set -u
|
||||
|
||||
echo " ── 还有没有它的进程 ──"
|
||||
pgrep -af 'rp_|long2h|ab_long|collapse' 2>/dev/null | head -5 | sed 's/^/ /' || echo " (没有)"
|
||||
|
||||
echo
|
||||
echo " ── 2 小时长测:最后状态 ──"
|
||||
if [ -f /root/long2h_health.tsv ]; then
|
||||
echo " 样本数: $(wc -l < /root/long2h_health.tsv)"
|
||||
echo " 最后 3 条:"
|
||||
tail -3 /root/long2h_health.tsv | sed 's/^/ /'
|
||||
else
|
||||
echo " (没有文件)"
|
||||
fi
|
||||
|
||||
echo
|
||||
echo " ── 配比对照跑了吗 ──"
|
||||
for s in lanremote-tunnel lanremote-tunnel-h2; do
|
||||
printf " %-24s %s (%s)\n" "$s" \
|
||||
"$(grep -oE -- '--protocol [a-z0-9]+|--ha-connections [0-9]+' \
|
||||
"/etc/systemd/system/$s.service" 2>/dev/null | tr '\n' ' ')" \
|
||||
"$(systemctl is-active $s 2>/dev/null)"
|
||||
done
|
||||
ls -la --time-style=+%H:%M /root/*ab*.tsv /root/*ab*.out /root/*ratio* 2>/dev/null | sed 's/^/ /' || echo " (没有对照的产物)"
|
||||
|
||||
echo
|
||||
echo " ── 它最后改的脚本(看它做到哪一步)──"
|
||||
ls -la --time-style=+%H:%M:%S /root/rp_ab_long.sh /root/rp_collapse.py /root/rp_collapse.tsv 2>/dev/null | sed 's/^/ /'
|
||||
|
||||
echo
|
||||
echo " ── 公网自检 ──"
|
||||
curl -s --max-time 20 -o /dev/null -w ' HTTP %{http_code} %{time_total}s\n' \
|
||||
-H 'User-Agent: LanRemote/1.8.2' https://relay.xxmxxs.top/v1/health
|
||||
|
||||
echo
|
||||
echo " ── 设备时间 ──"
|
||||
date '+ %H:%M:%S'
|
||||
Reference in New Issue
Block a user