上传文件至「full」

This commit is contained in:
2026-08-18 08:14:03 +00:00
parent 9eed3fd1f0
commit eaea693a82
2 changed files with 208 additions and 0 deletions
+129
View File
@@ -0,0 +1,129 @@
# -*- coding: utf-8 -*-
"""
RRPP 发布上传脚本
负责把 PyInstaller 打包好的 EXE 上传到服务器,并更新 latest_version.json,
使客户端启动时能检测并下载新版本。
## 服务器连接信息
主机: 172.207.81.145
端口: 22
用户: RRRosmontis
密码: ftA406u@all#2309
服务器可能启用了键盘交互认证,sshpass 等非交互式工具会报 Permission denied,
因此使用 .venv 中的 paramiko 进行 SSH/SFTP。
## 完整发布流程
1. 修改 proxy.py 与本脚本中的 VERSION 为当前年月日时分(例如 202607022100)。
2. 重新打包 EXE:
.venv/Scripts/python.exe -m PyInstaller RRPP.spec --noconfirm
或双击运行 build.bat,输出统一在 dist/ 目录。
3. 运行本脚本上传并更新服务器版本信息:
.venv/Scripts/python.exe upload_to_server.py
脚本执行步骤:
- SSH 连接到 172.207.81.145
- 把 dist/Royirin Rosmontis Private Proxy.exe 上传到 /tmp/proxy.exe
- 用 sudo 创建 /var/www/html/release/<VERSION>/ 并移动 EXE
- 用 sudo 写入 /var/www/html/latest_version.json(https 下载链接)
- 回显服务器上的 latest_version.json 内容用于验证
## 注意事项
- 上传前请确保 dist/ 下的 EXE 已重新打包,且版本号与 VERSION 一致。
- 若服务器连接信息或证书有变,请修改下方的 HOST / PORT / USER / PASSWORD。
"""
import shlex
import sys
from pathlib import Path
import paramiko
# ── 服务器连接与版本配置 ───────────────────────────────
HOST = "172.207.81.145"
PORT = 22
USER = "RRRosmontis"
PASSWORD = "ftA406u@all#2309"
VERSION = "202607192300"
# ── 本地 / 远程路径 ────────────────────────────────────
LOCAL_EXE = Path("dist/Royirin Rosmontis Private Proxy.exe")
REMOTE_DIR = f"/var/www/html/release/{VERSION}"
REMOTE_EXE_NAME = "Royirin Rosmontis Private Proxy.exe"
REMOTE_JSON = "/var/www/html/latest_version.json"
def sudo_exec(client, command, password, timeout=30):
"""通过 sudo -S 执行远程命令,并从 stdin 传入密码。"""
cmd = f"sudo -S bash -c {shlex.quote(command)}"
stdin, stdout, stderr = client.exec_command(cmd, timeout=timeout)
stdin.write(password + "\n")
stdin.flush()
stdin.channel.shutdown_write()
exit_status = stdout.channel.recv_exit_status()
out = stdout.read().decode("utf-8", errors="replace")
err = stderr.read().decode("utf-8", errors="replace")
return exit_status, out, err
def main():
"""主流程:上传 EXE 并更新服务器 latest_version.json。"""
if not LOCAL_EXE.exists():
print(f"错误:本地文件不存在: {LOCAL_EXE}", file=sys.stderr)
sys.exit(1)
print(f"连接 {HOST}:{PORT} ...")
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(HOST, port=PORT, username=USER, password=PASSWORD)
print("SSH 连接成功")
try:
# 1. 上传 EXE 到 /tmp
remote_tmp = "/tmp/proxy.exe"
print(f"上传 {LOCAL_EXE} -> {remote_tmp} ...")
sftp = client.open_sftp()
sftp.put(str(LOCAL_EXE), remote_tmp)
sftp.close()
print("上传完成")
# 2. 创建发布目录并移动文件到最终位置
print(f"创建目录 {REMOTE_DIR} 并移动 EXE ...")
cmd = f"mkdir -p {REMOTE_DIR} && mv {remote_tmp} '{REMOTE_DIR}/{REMOTE_EXE_NAME}'"
status, out, err = sudo_exec(client, cmd, PASSWORD)
if status != 0:
print(f"移动文件失败: {err}", file=sys.stderr)
sys.exit(1)
print("文件已移动到发布目录")
# 3. 更新 latest_version.json,客户端据此检测新版本
json_content = (
'{"latest_version":"' + VERSION + '",'
'"download_url":"https://tunnel.rrrosmontis.icu/release/'
+ VERSION + '/Royirin%20Rosmontis%20Private%20Proxy.exe"}'
)
print(f"更新 {REMOTE_JSON} ...")
cmd = f"echo '{json_content}' | tee {REMOTE_JSON}"
status, out, err = sudo_exec(client, cmd, PASSWORD)
if status != 0:
print(f"更新 JSON 失败: {err}", file=sys.stderr)
sys.exit(1)
print("latest_version.json 已更新")
print(f"服务器返回: {out.strip()}")
# 4. 验证远程 JSON 内容
print("验证远程文件...")
stdin, stdout, stderr = client.exec_command(f"cat {REMOTE_JSON}")
print(stdout.read().decode("utf-8").strip())
finally:
client.close()
print("连接已关闭")
if __name__ == "__main__":
main()