fix(system-update): 用 compose label 查询容器,修复 isRunning 和自更新助手镜像

- isRunning() 改用 docker ps --filter label=com.docker.compose.service
  兼容 Compose v1 (xuqm_svc_1) 和 v2 (xuqm-svc-1) 命名格式
- 自更新助手镜像改用 getCurrentImage() 从运行中容器的 label 获取,
  不再依赖容器环境变量 REGISTRY/IMAGE_TAG(容器内未注入这两个变量)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
这个提交包含在:
XuqmGroup 2026-05-21 15:46:39 +08:00
父节点 cc132c7ce7
当前提交 aece1fd08d

查看文件

@ -51,9 +51,14 @@ public class SystemUpdateService {
// 解决方案先用 docker run -d 启动一个独立助手容器它不依附于 tenant-service
// 能在 tenant-service 停止后继续完成重建
emit.accept(">>> 启动自更新助手容器...");
String registry = System.getenv().getOrDefault("REGISTRY", "");
String imageTag = System.getenv().getOrDefault("IMAGE_TAG", "latest");
String selfImage = registry.isEmpty() ? "alpine" : (registry + "/tenant-service:" + imageTag);
// Resolve the image by inspecting the running container via compose labels,
// so we don't depend on REGISTRY/IMAGE_TAG being present in the container env.
String selfImage = getCurrentImage();
if (selfImage == null) {
emit.accept(">>> [错误] 无法获取当前 tenant-service 镜像名,请检查容器标签或手动执行更新。");
emit.accept("DONE");
return;
}
boolean helperStarted = spawnSelfUpdater(composeFile, selfImage);
if (helperStarted) {
@ -100,19 +105,39 @@ public class SystemUpdateService {
}
}
// Use compose labels instead of container name works with both Compose v1 (xuqm_svc_1)
// and Compose v2 (xuqm-svc-1) naming conventions.
private boolean isRunning(String service) {
String containerName = "xuqm-" + service;
try {
Process p = new ProcessBuilder("docker", "inspect", "--type=container", containerName)
.redirectErrorStream(true)
.start();
p.getInputStream().transferTo(java.io.OutputStream.nullOutputStream());
return p.waitFor() == 0;
Process p = new ProcessBuilder(
"docker", "ps", "-q",
"--filter", "label=com.docker.compose.project=xuqm",
"--filter", "label=com.docker.compose.service=" + service
).redirectErrorStream(true).start();
String out = new String(p.getInputStream().readAllBytes()).trim();
p.waitFor();
return !out.isEmpty();
} catch (Exception e) {
return false;
}
}
private String getCurrentImage() {
try {
Process p = new ProcessBuilder(
"docker", "ps",
"--filter", "label=com.docker.compose.project=xuqm",
"--filter", "label=com.docker.compose.service=tenant-service",
"--format", "{{.Image}}"
).redirectErrorStream(true).start();
String out = new String(p.getInputStream().readAllBytes()).trim();
p.waitFor();
return out.isEmpty() ? null : out;
} catch (Exception e) {
return null;
}
}
private void exec(Consumer<String> emit, String... cmd) {
try {
Process p = new ProcessBuilder(cmd)