fix(tenant-service): check-update nginx 版本读取报错
从运行容器的真实镜像读取版本标签,而非构造 registry/nginx:latest。 nginx 使用官方镜像(nginx:1.27-alpine),构造路径本地不存在导致 "no such object" 错误。 同时修复 docker inspect 错误退出码未判断的问题,避免将错误信息写入版本号字段。 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
这个提交包含在:
父节点
93b1b41ede
当前提交
821745de6b
@ -173,30 +173,58 @@ public class SystemUpdateService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 读取本地各服务的版本号(从 Docker 镜像 LABEL 中读取)。
|
* 读取本地各服务的版本号(从 Docker 镜像 LABEL 中读取)。
|
||||||
|
* 优先从运行中容器的真实镜像读取(避免 nginx 等使用官方镜像的服务构造出不存在的 registry 路径),
|
||||||
|
* 容器不存在时回退到 resolveServiceImageName 构造的路径。
|
||||||
*/
|
*/
|
||||||
public Map<String, String> readLocalServiceVersions() {
|
public Map<String, String> readLocalServiceVersions() {
|
||||||
Map<String, String> versions = new LinkedHashMap<>();
|
Map<String, String> versions = new LinkedHashMap<>();
|
||||||
List<String> allServices = new ArrayList<>(OTHER_SERVICES);
|
List<String> allServices = new ArrayList<>(OTHER_SERVICES);
|
||||||
allServices.add("tenant-service");
|
allServices.add("tenant-service");
|
||||||
for (String svc : allServices) {
|
for (String svc : allServices) {
|
||||||
String imageName = resolveServiceImageName(svc);
|
versions.put(svc, readServiceVersion(svc));
|
||||||
if (imageName == null) { versions.put(svc, "unknown"); continue; }
|
|
||||||
try {
|
|
||||||
Process p = new ProcessBuilder(
|
|
||||||
"docker", "inspect", "--format",
|
|
||||||
"{{index .Config.Labels \"com.xuqm.version\"}}",
|
|
||||||
imageName
|
|
||||||
).redirectErrorStream(true).start();
|
|
||||||
String out = new String(p.getInputStream().readAllBytes(), StandardCharsets.UTF_8).trim();
|
|
||||||
p.waitFor();
|
|
||||||
versions.put(svc, out.isEmpty() ? "unknown" : out);
|
|
||||||
} catch (Exception e) {
|
|
||||||
versions.put(svc, "unknown");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return versions;
|
return versions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String readServiceVersion(String service) {
|
||||||
|
// 优先:从运行中容器的真实镜像读取
|
||||||
|
try {
|
||||||
|
Process ps = new ProcessBuilder(
|
||||||
|
"docker", "ps",
|
||||||
|
"--filter", "label=com.docker.compose.service=" + service,
|
||||||
|
"--format", "{{.Image}}"
|
||||||
|
).redirectErrorStream(true).start();
|
||||||
|
String imageRef = new String(ps.getInputStream().readAllBytes(), StandardCharsets.UTF_8).trim();
|
||||||
|
ps.waitFor();
|
||||||
|
if (!imageRef.isEmpty()) {
|
||||||
|
String version = readVersionLabel(imageRef.split("\n")[0].trim());
|
||||||
|
if (version != null) return version;
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {}
|
||||||
|
|
||||||
|
// 回退:构造期望镜像名(服务未运行时)
|
||||||
|
String imageName = resolveServiceImageName(service);
|
||||||
|
if (imageName == null) return "unknown";
|
||||||
|
String version = readVersionLabel(imageName);
|
||||||
|
return version != null ? version : "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
private String readVersionLabel(String imageName) {
|
||||||
|
try {
|
||||||
|
Process p = new ProcessBuilder(
|
||||||
|
"docker", "inspect", "--format",
|
||||||
|
"{{index .Config.Labels \"com.xuqm.version\"}}",
|
||||||
|
imageName
|
||||||
|
).redirectErrorStream(true).start();
|
||||||
|
String out = new String(p.getInputStream().readAllBytes(), StandardCharsets.UTF_8).trim();
|
||||||
|
int code = p.waitFor();
|
||||||
|
if (code != 0 || out.isBlank()) return null;
|
||||||
|
return out;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 读取版本清单(versions.json)。
|
* 读取版本清单(versions.json)。
|
||||||
*
|
*
|
||||||
|
|||||||
正在加载...
在新工单中引用
屏蔽一个用户