From f7fbc054df19012d864d5c64374d61ea32c169e4 Mon Sep 17 00:00:00 2001 From: lianlonggang Date: Wed, 9 Sep 2026 14:32:29 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=8D=87=E7=BA=A7=E4=B8=8B=E8=BD=BD=20?= =?UTF-8?q?zip=20=E5=90=8E=E8=A7=A3=E5=8E=8B=E8=BF=98=E5=8E=9F=20jar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 上传端为绕过中间设备对 jar 的拦截,升级包以 zip 下发;Agent 下载 zip 并 sha256 校验后,解压取内层 jar 再走替换/重启/回滚。 Co-Authored-By: Claude Code --- agent/upgrade.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/agent/upgrade.py b/agent/upgrade.py index 8767553..bb00717 100644 --- a/agent/upgrade.py +++ b/agent/upgrade.py @@ -21,6 +21,7 @@ import shutil import subprocess import threading import time +import zipfile import requests @@ -118,6 +119,18 @@ class UpgradeCommand: return self._fail(version, f"SHA-256 校验失败:expected={sha256}, actual={actual}") log.info("SHA-256 校验通过") + # ===== 2.5 解压 zip 得到内层 jar(上传端为绕过中间设备拦截,jar 被打成 zip) ===== + extracted_jar = os.path.join("tmp", f"upgrade-{version}.jar.extracted") + try: + result = extract_jar_from_zip(tmp_jar, extracted_jar) + if result is None: + os.remove(tmp_jar) + return self._fail(version, "zip 包内未找到 jar 文件") + os.remove(tmp_jar) # 删除临时 zip + tmp_jar = extracted_jar # 后续替换使用解压出的真 jar + except Exception as e: + return self._fail(version, f"解压 zip 失败:{e}") + # ===== 3. 备份 ===== # jar 路径来自配置(main.jar.path),适配不同部署结构 #(如 Agent 与主程序分目录、jar 文件名带版本号等) @@ -333,6 +346,19 @@ def copy_with_retry(src: str, dst: str, retries: int): ) from last_error +def extract_jar_from_zip(zip_path: str, dst_jar: str) -> str | None: + """从 zip 中取出第一个 .jar 文件写到 dst_jar,返回 dst_jar;找不到返回 None。""" + with zipfile.ZipFile(zip_path) as z: + jars = [n for n in z.namelist() + if n.lower().endswith(".jar") and not n.endswith("/")] + if not jars: + return None + with z.open(jars[0]) as src, open(dst_jar, "wb") as dst: + shutil.copyfileobj(src, dst) + log.info("解压 zip 得到 jar:%s → %s", jars[0], os.path.basename(dst_jar)) + return dst_jar + + def sha256_file(path: str) -> str: """文件 SHA-256(分块读取,支持大文件)。""" digest = hashlib.sha256()