mirror of
https://github.com/MCSManager/MCSManager.git
synced 2025-01-24 15:14:01 +08:00
Feat: add new image
This commit is contained in:
parent
b91d455e7a
commit
c1b8343a93
@ -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[]
|
||||
|
@ -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
|
||||
`;
|
||||
|
92
frontend/src/widgets/imageManager/DockerFileForm.vue
Normal file
92
frontend/src/widgets/imageManager/DockerFileForm.vue
Normal 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>
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user