fix(system-update): 修复 check-update 显示 "no such object" 及 bugcollect-service 无法被一键更新
1. readLocalServiceVersions() 改用 resolveServiceImageName() 获取完整
镜像名(含 registry 前缀),不再硬编码 "xuqmgroup/{svc}:latest"。
2. resolveServiceImageName() 通过 SERVICE_IMAGE_OVERRIDES 处理镜像名与
compose service 名不一致的例外(bugcollect-service → xuqm-bugcollect-service)。
3. 新增 SERVICE_COMPOSE_PROFILES 映射与 composeCmd() 辅助方法,为带
profile 的服务(bugcollect-service:bugcollect)自动注入 --profile 参数,
使 pull / up 命令能正常识别并更新这些服务。
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
这个提交包含在:
父节点
1131a0c614
当前提交
93b1b41ede
@ -49,6 +49,16 @@ public class SystemUpdateService {
|
||||
"file-service", "tenant-web", "im-service", "push-service", "update-service", "license-service", "bugcollect-service", "nginx"
|
||||
);
|
||||
|
||||
// 镜像名与 compose service 名不一致的例外(历史命名遗留)
|
||||
private static final Map<String, String> SERVICE_IMAGE_OVERRIDES = Map.of(
|
||||
"bugcollect-service", "xuqm-bugcollect-service"
|
||||
);
|
||||
|
||||
// 使用 docker compose profile 的服务(未声明 profile 的服务不在此表中)
|
||||
private static final Map<String, String> SERVICE_COMPOSE_PROFILES = Map.of(
|
||||
"bugcollect-service", "bugcollect"
|
||||
);
|
||||
|
||||
// 健康检查配置:新容器需在此时间内保持 running 状态才视为健康
|
||||
private static final int HEALTH_CHECK_TIMEOUT_SEC = 60;
|
||||
private static final int HEALTH_STABLE_REQUIRED_SEC = 10;
|
||||
@ -169,11 +179,13 @@ public class SystemUpdateService {
|
||||
List<String> allServices = new ArrayList<>(OTHER_SERVICES);
|
||||
allServices.add("tenant-service");
|
||||
for (String svc : allServices) {
|
||||
String imageName = resolveServiceImageName(svc);
|
||||
if (imageName == null) { versions.put(svc, "unknown"); continue; }
|
||||
try {
|
||||
Process p = new ProcessBuilder(
|
||||
"docker", "inspect", "--format",
|
||||
"{{index .Config.Labels \"com.xuqm.version\"}}",
|
||||
"xuqmgroup/" + svc + ":latest"
|
||||
imageName
|
||||
).redirectErrorStream(true).start();
|
||||
String out = new String(p.getInputStream().readAllBytes(), StandardCharsets.UTF_8).trim();
|
||||
p.waitFor();
|
||||
@ -311,10 +323,10 @@ public class SystemUpdateService {
|
||||
emit.accept(">>> 拉取镜像(" + toUpdate.size() + " 个服务)...");
|
||||
for (String svc : toUpdate) {
|
||||
emit.accept(" pulling " + svc + " ...");
|
||||
exec(emit, "docker", "compose", "-f", composeFile, "pull", "--quiet", svc);
|
||||
exec(emit, composeCmd(composeFile, svc, "pull", "--quiet", svc));
|
||||
}
|
||||
emit.accept(" pulling tenant-service ...");
|
||||
exec(emit, "docker", "compose", "-f", composeFile, "pull", "--quiet", "tenant-service");
|
||||
exec(emit, composeCmd(composeFile, "tenant-service", "pull", "--quiet", "tenant-service"));
|
||||
emit.accept(">>> 镜像拉取完成");
|
||||
|
||||
restartAndSelfUpdate(emit, composeFile, oldImageIds);
|
||||
@ -797,8 +809,7 @@ public class SystemUpdateService {
|
||||
|
||||
for (String svc : OTHER_SERVICES) {
|
||||
emit.accept(" restarting " + svc + " ...");
|
||||
exec(emit, "docker", "compose", "-f", composeFile,
|
||||
"up", "-d", "--no-deps", "--force-recreate", svc);
|
||||
exec(emit, composeCmd(composeFile, svc, "up", "-d", "--no-deps", "--force-recreate", svc));
|
||||
// 拿到 compose up 之后最新创建的容器 ID,排除旧容器干扰
|
||||
String newContainerId = getNewestContainerId(svc);
|
||||
emit.accept(" [debug] " + svc + " newContainerId=" + newContainerId);
|
||||
@ -1027,7 +1038,8 @@ public class SystemUpdateService {
|
||||
return ok;
|
||||
}
|
||||
|
||||
/** 从 .env 读取 REGISTRY 和 IMAGE_TAG,拼接服务完整镜像名(registry/service:tag)。 */
|
||||
/** 从 .env 读取 REGISTRY 和 IMAGE_TAG,拼接服务完整镜像名(registry/image:tag)。
|
||||
* 部分服务镜像名与 compose service 名不同,通过 SERVICE_IMAGE_OVERRIDES 处理。 */
|
||||
private String resolveServiceImageName(String service) {
|
||||
try {
|
||||
Path envFile = Paths.get(deployRoot, ".env");
|
||||
@ -1035,12 +1047,24 @@ public class SystemUpdateService {
|
||||
String imageTag = readEnvValue(envFile, "IMAGE_TAG");
|
||||
if (registry == null) return null;
|
||||
if (imageTag == null || imageTag.isBlank()) imageTag = "latest";
|
||||
return registry + "/" + service + ":" + imageTag;
|
||||
String imageName = SERVICE_IMAGE_OVERRIDES.getOrDefault(service, service);
|
||||
return registry + "/" + imageName + ":" + imageTag;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/** 构造 docker compose 命令,自动注入该服务所需的 --profile 参数。 */
|
||||
private String[] composeCmd(String composeFile, String service, String... subCmd) {
|
||||
List<String> cmd = new ArrayList<>();
|
||||
cmd.add("docker"); cmd.add("compose");
|
||||
String profile = SERVICE_COMPOSE_PROFILES.get(service);
|
||||
if (profile != null) { cmd.add("--profile"); cmd.add(profile); }
|
||||
cmd.add("-f"); cmd.add(composeFile);
|
||||
cmd.addAll(Arrays.asList(subCmd));
|
||||
return cmd.toArray(new String[0]);
|
||||
}
|
||||
|
||||
// ── 配置文件热修复 ──────────────────────────────────────────────────────────
|
||||
|
||||
private void patchConfigs(Consumer<String> emit) {
|
||||
|
||||
正在加载...
在新工单中引用
屏蔽一个用户