mirror of
https://gitee.com/xmz7891/ykxmz.git
synced 2026-10-18 14:50:45 +00:00
用户要求:服务器端文件里放一个 .sh,双击就能检查 cloudflared 装没装、
自动部署、配好公网,以后全自动。
== 新增 ==
relay/deploy.sh 一键部署主脚本,7 步全自动:
环境检查 -> 装 cloudflared -> 部署程序 -> 网络调优
-> 写 4 个 systemd 服务 -> 配隧道 -> 启动自检打公网地址
relay/deploy-tune.sh 网络调优,可单独重跑:
keepalive 30/10/3 + 路径 MTU 探测 + MSS 1360
+ 接口 MTU 1400 + mask networkd-wait-online
每一项都写明了实测依据
用法:
bash deploy.sh 复用已有凭据,全自动
TUNNEL_TOKEN=eyJh... bash deploy.sh Token 模式
bash deploy.sh --hostname relay.你的域名 换域名
bash deploy.sh --skip-tunnel 只装中转
bash deploy.sh --help 全部参数
重跑 = 升级;已有数据/配对码/管理密码/凭据/手改过的 config.yml 都不动。
== 自动化到什么程度 ==
* cloudflared 不在就自动下载装上(并校验能执行)
* 隧道支持两种模式:已有凭据文件、或 TUNNEL_TOKEN
* **不传 --hostname 且没有 Token 时明确提示要填**,不会静默用一个写死的值
(用户明确说过:这个中转站是他自己用的,不对外开放,
绝不能把私人域名烧成默认值)
* deploy-tune.sh 的 MTU 取 1400:路径 MTU 实测 1472,
而 MSS 钳制只管 TCP、QUIC 走 UDP 完全不受保护;
接口 MTU 降到 1400 后 QUIC 建齐 10 条连接从 28 秒缩到 12 秒
== 顺带修掉两个真 bug ==
1. write_tunnel_unit 写的文件名漏了 .service 后缀 ——
文件写下去了但 systemd 完全看不见,enable 还会安静地失败。
2. 发布包一直缺 site_shots/(老 bug):
package_remote.py 用 iterdir() + is_file() 收文件,目录进不去。
新机器装完官网截图全是 404。只有从 zip 解压真跑一遍才暴露。
同时把 deploy.sh 里 site_shots 的检查降级成警告(缺截图不该让部署失败)。
另外给 deploy-tune.sh 清旧 MSS 规则的循环加了 10 次上限 ——
原写法在 -D 报成功但规则仍在时会死循环把整个部署卡死。
== 验证 ==
* _build/test_deploy_sh.sh 沙箱 65 项,全通过
* _build/test_zip_deploy.sh 从发布 zip 解压再跑,30 项,全通过
* _build/test_deploy_real.sh **真机 Debian 上实测**(新增):
zip 解出 17 个文件 -> 语法/LF/无 BOM 通过
--help 退出码 0 且无副作用、未知参数退出码 2
沙箱安装成功、幂等重跑哨兵不被冲
现有三个中转服务全程 active,自检 200
83 lines
2.4 KiB
Python
83 lines
2.4 KiB
Python
# -*- coding: utf-8 -*-
|
||
r'''把新增的 .sh 规范化成「LF + UTF-8 无 BOM」,并做静态检查。
|
||
|
||
为什么必须检查:
|
||
仓库里所有 .sh 都是 LF + 无 BOM。一旦混进 CRLF,
|
||
在 Linux 上跑会报 `bash: $'\r': command not found`,
|
||
而且报错位置会很莫名(通常是 `#!/bin/bash\r` 那一行)。
|
||
.bat 才用 GBK+CRLF,别搞混。
|
||
|
||
用法:
|
||
python _build/fix_sh_format.py # 检查并修
|
||
python _build/fix_sh_format.py --check # 只检查不改
|
||
'''
|
||
from __future__ import annotations
|
||
|
||
import subprocess
|
||
import sys
|
||
from pathlib import Path
|
||
|
||
ROOT = Path(r"C:\Users\shu\Desktop\deepseekagent\LanRemote")
|
||
TARGETS = [
|
||
ROOT / "relay" / "deploy.sh",
|
||
ROOT / "relay" / "deploy-tune.sh",
|
||
]
|
||
BASH = r"C:\Program Files\Git\bin\bash.exe"
|
||
|
||
|
||
def main() -> int:
|
||
check_only = "--check" in sys.argv
|
||
bad = 0
|
||
|
||
for path in TARGETS:
|
||
if not path.is_file():
|
||
print(" [缺] %s" % path.name)
|
||
bad += 1
|
||
continue
|
||
raw = path.read_bytes()
|
||
crlf = raw.count(b"\r\n")
|
||
lone_cr = raw.count(b"\r") - crlf
|
||
bom = raw.startswith(b"\xef\xbb\xbf")
|
||
print(" %-18s CRLF=%-4d 单独CR=%-3d BOM=%s"
|
||
% (path.name, crlf, lone_cr, "有" if bom else "无"))
|
||
|
||
if crlf or lone_cr or bom:
|
||
if check_only:
|
||
print(" -> 需要修")
|
||
bad += 1
|
||
else:
|
||
data = raw.replace(b"\r\n", b"\n").replace(b"\r", b"\n")
|
||
if bom:
|
||
data = data[3:]
|
||
path.write_bytes(data)
|
||
print(" -> 已修成 LF + 无 BOM")
|
||
else:
|
||
print(" -> 格式正确")
|
||
|
||
print()
|
||
print(" 语法检查(bash -n):")
|
||
for path in TARGETS:
|
||
if not path.is_file():
|
||
continue
|
||
proc = subprocess.run(
|
||
[BASH, "-n", str(path).replace("\\", "/")],
|
||
capture_output=True, text=True, encoding="utf-8",
|
||
errors="replace")
|
||
if proc.returncode == 0:
|
||
print(" ✓ %s" % path.name)
|
||
else:
|
||
print(" ✗ %s" % path.name)
|
||
print(" " + (proc.stderr or "").strip()[:400])
|
||
bad += 1
|
||
|
||
print()
|
||
if bad:
|
||
print(" 有 %d 个问题" % bad)
|
||
return 1
|
||
print(" 全部通过")
|
||
return 0
|
||
|
||
|
||
if __name__ == "__main__":
|
||
sys.exit(main())
|