Feat: add new image

This commit is contained in:
Lazy 2023-10-19 15:59:18 +08:00
parent b91d455e7a
commit c1b8343a93
4 changed files with 244 additions and 8 deletions

View File

@ -1,13 +1,18 @@
import { useDefineApi } from "@/stores/useDefineApi";
import type { ImageInfo, DockerNetworkModes, ContainerInfo } from "@/types";
// 获取镜像列表
// 镜像相关
export const imageList = useDefineApi<
{
params: {
remote_uuid: string;
imageId?: string;
};
data?: {
dockerFile: string;
name: string;
tag: string;
};
method: string;
},
ImageInfo[]

View File

@ -20,3 +20,63 @@ export const INSTANCE_STATUS = {
"2": t("正在启动"),
"3": t("正在运行")
};
export const defaultDockerFile = `FROM ubuntu:latest\nRUN mkdir -p /workspace\nWORKDIR /workspace\n`;
export const openjdk8 = `FROM openjdk:8-jre
RUN apt update && apt install -y locales
RUN mkdir -p /workspace
WORKDIR /workspace
`;
export const openjdk16 = `FROM openjdk:16.0.2
RUN mkdir -p /workspace
WORKDIR /workspace
`;
export const ubuntu22 = `FROM ubuntu:22.04
RUN apt update && apt -y install libcurl4 && DEBIAN_FRONTEND="noninteractive" apt -y install tzdata
RUN mkdir -p /workspace
WORKDIR /workspace
`;
export const openjdk17 = `FROM openjdk:17
RUN mkdir -p /workspace
WORKDIR /workspace
`;
export const openjdk8CN = `FROM openjdk:8-jre
RUN sed -i -E 's/http:\\/\\/(deb|security).debian.org/http:\\/\\/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list
RUN apt update && apt install -y locales
RUN echo "zh_CN.UTF-8 UTF-8">/etc/locale.gen && locale-gen
ENV LANG=zh_CN.UTF-8
ENV LANGUAGE=zh_CN.UTF-8
ENV LC_ALL=zh_CN.UTF-8
ENV TZ=Asia/Shanghai
RUN mkdir -p /workspace
WORKDIR /workspace
`;
export const openjdk16CN = `FROM openjdk:16.0.2
RUN mkdir -p /workspace
ENV TZ=Asia/Shanghai
WORKDIR /workspace
`;
export const ubuntu22CN = `FROM ubuntu:22.04
ENV TZ=Asia/Shanghai
RUN sed -i -E 's/http:\\/\\/(archive|security).ubuntu.com/http:\\/\\/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list
RUN apt update && apt -y install libcurl4 && DEBIAN_FRONTEND="noninteractive" apt -y install tzdata
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN mkdir -p /workspace
WORKDIR /workspace
`;
export const openjdk17CN = `FROM openjdk:17
RUN mkdir -p /workspace
ENV LANG=zh_CN.UTF-8
ENV LANGUAGE=zh_CN.UTF-8
ENV LC_ALL=zh_CN.UTF-8
ENV TZ=Asia/Shanghai
WORKDIR /workspace
`;

View File

@ -0,0 +1,92 @@
<script setup lang="ts">
import { ref, reactive, onMounted } from "vue";
import { t } from "@/lang/i18n";
import { message, notification } from "ant-design-vue";
import { imageList } from "@/services/apis/envImage";
const props = defineProps<{
dockerFile: string;
name: string;
version: string;
daemonId: string;
}>();
const emit = defineEmits(["close"]);
const options = reactive({
dockerFile: "",
name: "",
version: ""
});
const { execute } = imageList();
const submit = async () => {
try {
if (!options.dockerFile || !options.name || !options.version)
return message.error(t("请填写表单完整"));
await execute({
params: {
remote_uuid: props.daemonId
},
data: {
dockerFile: options.dockerFile,
name: options.name,
tag: options.version
},
method: "POST"
});
notification["info"]({
message: t("创建镜像任务已经开始"),
description: t("请耐心等待")
});
emit("close");
} catch (err: any) {
console.error(err.message);
return message.error(err.message);
}
};
onMounted(() => {
options.dockerFile = props.dockerFile;
options.name = props.name;
options.version = props.version;
});
</script>
<template>
<a-typography>
<a-typography-paragraph>
<a-typography-title :level="5">{{ t("关于 DockerFile 文件") }}</a-typography-title>
<a-typography-text>
{{ t("官方参考文档https://docs.docker.com/engine/reference/builder/") }}
</a-typography-text>
</a-typography-paragraph>
<a-typography-paragraph>
<a-typography-title :level="5">{{ t("注意事项") }}</a-typography-title>
<a-typography-text>
{{ t("必须创建 /workspace 目录,此目录将自动挂载到实例的文件根目录") }}
</a-typography-text>
</a-typography-paragraph>
</a-typography>
<a-form-item>
<a-textarea v-model:value="options.dockerFile" placeholder="必填,请输入内容" :rows="8" />
</a-form-item>
<a-form-item>
<a-typography-text>
{{ t("创建后的镜像名与版本标识") }}
</a-typography-text>
<a-input-group compact>
<a-input v-model:value="options.name" style="width: 65%" />
<a-input v-model:value="options.version" style="width: 35%" />
</a-input-group>
</a-form-item>
<a-popconfirm
:title="t('此构建过程可能需要几分钟时间,请确保网络畅通,是否继续?')"
@confirm="submit"
>
<a-button type="primary">{{ t("创建镜像") }}</a-button>
</a-popconfirm>
</template>

View File

@ -1,13 +1,26 @@
<script setup lang="ts">
import { ref, computed, onMounted, h } from "vue";
import { ref, onMounted } from "vue";
import { t } from "@/lang/i18n";
import { Modal, message, notification } from "ant-design-vue";
import { message } from "ant-design-vue";
import CardPanel from "@/components/CardPanel.vue";
import BetweenMenus from "@/components/BetweenMenus.vue";
import { useScreen } from "@/hooks/useScreen";
import { useLayoutCardTools } from "@/hooks/useCardTools";
import { useAppRouters } from "@/hooks/useAppRouters";
import type { LayoutCard } from "@/types";
import {
defaultDockerFile,
openjdk16,
openjdk16CN,
openjdk17,
openjdk17CN,
openjdk8,
openjdk8CN,
ubuntu22,
ubuntu22CN
} from "@/types/const";
import { getCurrentLang } from "@/lang/i18n";
import DockerFileForm from "./DockerFileForm.vue";
const props = defineProps<{
card: LayoutCard;
@ -17,13 +30,11 @@ const { toPage } = useAppRouters();
const { getMetaOrRouteValue } = useLayoutCardTools(props.card);
const daemonId: string | undefined = getMetaOrRouteValue("daemonId");
const screen = useScreen();
const dockerFileDrawer = ref(false);
const imageList = [
{
title: t("创建 OpenJDK 8 环境镜像"),
description: t(
"适用于需要 Java 8 的服务端软件,属于经典的 Java 运行时版本,适用于 Minecraft 1.17 以下的所有版本"
),
description: t("内置 Java 16 运行时环境,适用于 Minecraft 1.7 ~ 1.16 版本的服务端"),
type: 1
},
{
@ -48,6 +59,43 @@ const imageList = [
}
];
const dockerFile = ref("");
const name = ref("");
const version = ref("");
const isZH = getCurrentLang() === "zh_CN" ? true : false;
const selectType = (type: number) => {
switch (type) {
case 1:
dockerFile.value = isZH ? openjdk8CN : openjdk8;
name.value = "mcsm-openjdk";
version.value = "8";
break;
case 2:
dockerFile.value = isZH ? openjdk16CN : openjdk16;
name.value = "mcsm-openjdk";
version.value = "16";
break;
case 3:
dockerFile.value = isZH ? openjdk17CN : openjdk17;
name.value = "mcsm-openjdk";
version.value = "17";
break;
case 4:
dockerFile.value = isZH ? ubuntu22CN : ubuntu22;
name.value = "mcsm-ubuntu";
version.value = "22.04";
break;
case 5:
dockerFile.value = defaultDockerFile;
name.value = "mcsm-custom";
version.value = "lasted";
break;
default:
return message.error(t("未知的环境类型"));
}
dockerFileDrawer.value = true;
};
const toImageListPage = () => {
toPage({
path: "/node/image",
@ -113,7 +161,7 @@ onMounted(async () => {});
</a-col>
<a-col v-for="i in imageList" :key="i" :span="24" :lg="6" :md="8" :sm="12">
<CardPanel>
<CardPanel class="images-card" @click="selectType(i.type)">
<template #title>{{ i.title }}</template>
<template #body>
<a-typography-text>
@ -124,4 +172,35 @@ onMounted(async () => {});
</a-col>
</a-row>
</div>
<a-drawer
v-model:open="dockerFileDrawer"
:width="screen.isPhone.value ? 'auto' : '768px'"
title="DockerFile"
placement="right"
destroy-on-close
>
<DockerFileForm
:docker-file="dockerFile"
:name="name"
:version="version"
:daemon-id="daemonId ?? ''"
@close="dockerFileDrawer = false"
/>
</a-drawer>
</template>
<style lang="scss" scoped>
.images-card {
cursor: pointer;
&:hover {
border: 1px solid var(--color-gray-8);
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.16);
}
}
.drawer {
width: 500px;
}
</style>