Files
Private-Proxy/full/upload_to_server.py
T

130 lines
4.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- 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()