Skip to content

Commit

Permalink
fix(ai): Containerd运行时下大镜像推送失败 (#1181)
Browse files Browse the repository at this point in the history
**改动**
1.此pr在` containerd `运行时的 `nerdctl push `命令中追加
`--all-platforms`运行参数,避免可能由于基础镜像为多平台的大镜像在推送到镜像仓库中推送失败的问题
2.在创建镜像与编辑镜像时追加后台详细错误信息展示

**修改后**
1.不影响docker运行时的命令执行,本地创建和远程镜像创建均可成功
2.不影响containerd运行时普通镜像上传,本地创建和远程镜像创建均可成功
3.创建后本地拉取及制作的镜像正常删除

![image](https://github.com/PKUHPC/SCOW/assets/43978285/70ce73cf-244e-49ce-8dd7-eb7d52a460de)

![image](https://github.com/PKUHPC/SCOW/assets/43978285/ec808e35-a9a9-4a8f-99a6-66786d5a1178)

![image](https://github.com/PKUHPC/SCOW/assets/43978285/816fd767-581f-4908-ac8c-4744860329ef)

4.创建/编辑时错误信息补充完整

![image](https://github.com/PKUHPC/SCOW/assets/43978285/6a0cf21e-6ae2-4235-bd3f-ff8989ea9eca)
  • Loading branch information
piccaSun committed Mar 28, 2024
1 parent 8dd8c0e commit 3c5c8a6
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 31 deletions.
5 changes: 5 additions & 0 deletions .changeset/cuddly-frogs-rest.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@scow/ai": patch
---

修复大镜像在 Containerd 运行时推送失败的问题
4 changes: 2 additions & 2 deletions apps/ai/src/app/(auth)/image/CreateEditImageModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export const CreateEditImageModal: React.FC<Props> = (
]);
return;
}
message.error("添加镜像失败");
message.error(`添加镜像失败, ${err.message}`);
},
});

Expand All @@ -101,7 +101,7 @@ export const CreateEditImageModal: React.FC<Props> = (
if (data?.code === "NOT_FOUND") {
message.error("镜像不存在");
} else {
message.error("编辑镜像失败");
message.error(`编辑镜像失败,${e.message}`);
}
},
});
Expand Down
18 changes: 0 additions & 18 deletions apps/ai/src/server/trpc/route/image/image.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,6 @@ import { z } from "zod";
import { clusters } from "../config";
import { clusterExist } from "../utils";

// class NotTarError extends TRPCError {
// constructor(name: string, tag: string) {
// super({
// code: "UNPROCESSABLE_CONTENT",
// message: `Image ${name}:${tag} create failed: image is not a tar file`,
// });
// }
// };

class NoClusterError extends TRPCError {
constructor(name: string, tag: string) {
super({
Expand All @@ -49,15 +40,6 @@ class NoClusterError extends TRPCError {
}
};

// class NoLocalImageError extends TRPCError {
// constructor(name: string, tag: string) {
// super({
// code: "NOT_FOUND",
// message: `Image ${name}:${tag} create failed: localImage not found`,
// });
// }
// }

class InternalServerError extends TRPCError {
constructor(errMessage: string, process: "Create" | "Copy") {
super({
Expand Down
33 changes: 22 additions & 11 deletions apps/ai/src/server/utils/image.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,17 @@ const runtimeContainerIdPrefix = {
[k8sRuntime.containerd]: "containerd",
};

export function getRuntimeCommand(clusterId: string): string {
export function getK8sRuntime(clusterId: string): k8sRuntime {
const runtime = clusters[clusterId].k8s?.runtime;
return runtimeCommands[runtime ?? k8sRuntime.docker];
return runtime ?? k8sRuntime.docker;
}

function getContainerIdPrefix(clusterId: string): string {
const runtime = clusters[clusterId].k8s?.runtime;
return runtimeContainerIdPrefix[runtime ?? k8sRuntime.docker];
export function getRuntimeCommand(runtime: k8sRuntime): string {
return runtimeCommands[runtime];
}

function getContainerIdPrefix(runtime: k8sRuntime): string {
return runtimeContainerIdPrefix[runtime];
}

// 加载本地镜像
Expand All @@ -69,7 +72,8 @@ export async function getLoadedImage({
clusterId: string,
}): Promise<string | undefined> {

const command = getRuntimeCommand(clusterId);
const runtime = getK8sRuntime(clusterId);
const command = getRuntimeCommand(runtime);

const loadedResp = await loggedExec(ssh, logger, true, command, ["load", "-i", sourcePath]);
const match = loadedResp.stdout.match(loadedImageRegex);
Expand All @@ -89,7 +93,8 @@ export async function getPulledImage({
clusterId: string,
}): Promise<string | undefined> {

const command = getRuntimeCommand(clusterId);
const runtime = getK8sRuntime(clusterId);
const command = getRuntimeCommand(runtime);

const pulledResp = await loggedExec(ssh, logger, true, command, ["pull", sourcePath]);

Expand All @@ -111,7 +116,8 @@ export async function pushImageToHarbor({
clusterId: string,
}): Promise<void> {

const command = getRuntimeCommand(clusterId);
const runtime = getK8sRuntime(clusterId);
const command = getRuntimeCommand(runtime);

// login harbor
await loggedExec(ssh, logger, true, command, ["login", harborUrl, "-u", harborUser, "-p", password]);
Expand All @@ -120,7 +126,10 @@ export async function pushImageToHarbor({
await loggedExec(ssh, logger, true, command, ["tag", localImageUrl, harborImageUrl]);

// push 镜像至harbor
await loggedExec(ssh, logger, true, command, ["push", harborImageUrl]);
// 运行时为 containerd 时,需添加 --all-platforms 确保多平台镜像可以正确推送
await loggedExec(ssh, logger, true, command,
runtime === k8sRuntime.containerd ?
["push", "--all-platforms", harborImageUrl] : ["push", harborImageUrl]);

// 清除本地镜像
await loggedExec(ssh, logger, true, command, ["rmi", harborImageUrl]);
Expand All @@ -144,7 +153,8 @@ export async function commitContainerImage({
clusterId: string,
}): Promise<void> {

const command = getRuntimeCommand(clusterId);
const runtime = getK8sRuntime(clusterId);
const command = getRuntimeCommand(runtime);
const resp = await loggedExec(ssh, logger, true, "sh",
["-c", `${command} ps --no-trunc | grep ${formateContainerId}`]);
if (!resp.stdout) {
Expand All @@ -161,6 +171,7 @@ export async function commitContainerImage({


export const formatContainerId = (clusterId: string, containerId: string) => {
const prefix = getContainerIdPrefix(clusterId);
const runtime = getK8sRuntime(clusterId);
const prefix = getContainerIdPrefix(runtime);
return containerId.replace(`${prefix}://`, "");
};

0 comments on commit 3c5c8a6

Please sign in to comment.