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>
这个提交包含在:
XuqmGroup 2026-06-24 15:40:28 +08:00
父节点 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) {