mirror of
https://github.com/MCSManager/MCSManager.git
synced 2024-11-27 06:59:54 +08:00
Feat: docker env & docker workspace config
This commit is contained in:
parent
6b0f0ea57e
commit
4aa94256d5
1
common/global.d.ts
vendored
1
common/global.d.ts
vendored
@ -72,6 +72,7 @@ export interface IGlobalInstanceDockerConfig {
|
||||
cpusetCpus?: string;
|
||||
cpuUsage?: number;
|
||||
workingDir?: string;
|
||||
env?: string[];
|
||||
}
|
||||
|
||||
export interface IPanelResponseProtocol {
|
||||
|
@ -33,15 +33,6 @@ export function configureEntityParams(self: any, args: any, key: string, typeFn?
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeFn === Array) {
|
||||
if (v == null) return (self[key] = null);
|
||||
if (!(v instanceof Array))
|
||||
throw new Error(
|
||||
`ConfigureEntityParams Error: Expected type to be Array, but got ${typeof v}`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeFn) {
|
||||
self[key] = typeFn(v);
|
||||
} else {
|
||||
|
@ -8,6 +8,7 @@ import { IInstanceProcess } from "../../instance/interface";
|
||||
import fs from "fs-extra";
|
||||
import { commandStringToArray } from "../base/command_parser";
|
||||
import path from "path";
|
||||
import { t } from "i18next";
|
||||
|
||||
// user identity function
|
||||
const processUserUid = process.getuid ? process.getuid : () => 0;
|
||||
@ -121,13 +122,14 @@ export default class DockerStartCommand extends InstanceCommand {
|
||||
const publicPortArray: any = {};
|
||||
const exposedPorts: any = {};
|
||||
for (const iterator of portMap) {
|
||||
const elemt = iterator.split("/");
|
||||
if (elemt.length != 2) continue;
|
||||
const ports = elemt[0];
|
||||
const protocol = elemt[1];
|
||||
const elem = iterator.split("/");
|
||||
if (elem.length != 2) throw new Error(t("此容器的开放端口配置有误!"));
|
||||
const ports = elem[0];
|
||||
const protocol = elem[1];
|
||||
//Host (host) port: container port
|
||||
const publicAndPrivatePort = ports.split(":");
|
||||
if (publicAndPrivatePort.length != 2) continue;
|
||||
if (publicAndPrivatePort.length != 2)
|
||||
throw new Error(t("此容器的开放端口配置有误,分隔符号左右两边不存在值!"));
|
||||
publicPortArray[`${publicAndPrivatePort[1]}/${protocol}`] = [
|
||||
{ HostPort: publicAndPrivatePort[0] }
|
||||
];
|
||||
@ -138,9 +140,9 @@ export default class DockerStartCommand extends InstanceCommand {
|
||||
const extraVolumes = instance.config.docker.extraVolumes;
|
||||
const extraBinds = [];
|
||||
for (const item of extraVolumes) {
|
||||
if (!item) continue;
|
||||
if (!item) throw new Error("实例容器额外挂载路径配置错误!请检查!");
|
||||
const paths = item.split(":");
|
||||
if (paths.length < 2) continue;
|
||||
if (paths.length < 2) throw new Error("实例容器额外挂载路径配置错误!请检查!");
|
||||
const hostPath = path.normalize(paths[0]);
|
||||
const containerPath = path.normalize(paths.slice(1).join(":"));
|
||||
extraBinds.push(`${hostPath}:${containerPath}`);
|
||||
@ -170,7 +172,8 @@ export default class DockerStartCommand extends InstanceCommand {
|
||||
}
|
||||
|
||||
// container name check
|
||||
let containerName = instance.config.docker.containerName;
|
||||
let containerName =
|
||||
instance.config.docker.containerName || `MCSM-${instance.instanceUuid.slice(0, 6)}`;
|
||||
if (containerName && (containerName.length > 64 || containerName.length < 2)) {
|
||||
throw new Error($t("TXT_CODE_instance.invalidContainerName", { v: containerName }));
|
||||
}
|
||||
@ -185,7 +188,7 @@ export default class DockerStartCommand extends InstanceCommand {
|
||||
logger.info(`UUID: [${instance.instanceUuid}] [${instance.config.nickname}]`);
|
||||
logger.info(`NAME: [${containerName}]`);
|
||||
logger.info(`COMMAND: ${commandList.join(" ")}`);
|
||||
logger.info(`CWD: ${cwd}`);
|
||||
logger.info(`CWD: ${cwd}, WORKING_DIR: ${workingDir}`);
|
||||
logger.info(`NET_MODE: ${instance.config.docker.networkMode}`);
|
||||
logger.info(`OPEN_PORT: ${JSON.stringify(publicPortArray)}`);
|
||||
logger.info(`BINDS: ${JSON.stringify([`${cwd}:${workingDir}`, ...extraBinds])}`);
|
||||
@ -210,6 +213,7 @@ export default class DockerStartCommand extends InstanceCommand {
|
||||
OpenStdin: true,
|
||||
StdinOnce: false,
|
||||
ExposedPorts: exposedPorts,
|
||||
Env: instance.config.docker?.env || [],
|
||||
HostConfig: {
|
||||
Memory: maxMemory,
|
||||
Binds: [`${cwd}:${workingDir}`, ...extraBinds],
|
||||
@ -237,6 +241,7 @@ export default class DockerStartCommand extends InstanceCommand {
|
||||
h: instance.config.terminalOption.ptyWindowCol
|
||||
});
|
||||
|
||||
instance.println("Container", t("已挂载工作目录:") + workingDir);
|
||||
instance.started(processAdapter);
|
||||
logger.info(
|
||||
$t("TXT_CODE_instance.successful", {
|
||||
|
@ -64,7 +64,8 @@ export default class InstanceConfig implements IGlobalInstanceConfig {
|
||||
maxSpace: null,
|
||||
io: null,
|
||||
network: null,
|
||||
workingDir: "/workspace/"
|
||||
workingDir: "/workspace/",
|
||||
env: []
|
||||
};
|
||||
|
||||
public pingConfig = {
|
||||
|
@ -92,8 +92,7 @@ export default class Instance extends EventEmitter {
|
||||
}
|
||||
|
||||
if (cfg?.enableRcon != null && cfg?.enableRcon !== this.config.enableRcon) {
|
||||
if (this.status() != Instance.STATUS_STOP)
|
||||
throw new Error($t("TXT_CODE_bdfa3457"));
|
||||
if (this.status() != Instance.STATUS_STOP) throw new Error($t("TXT_CODE_bdfa3457"));
|
||||
configureEntityParams(this.config, cfg, "enableRcon", Boolean);
|
||||
this.forceExec(new FunctionDispatcher());
|
||||
}
|
||||
@ -170,6 +169,8 @@ export default class Instance extends EventEmitter {
|
||||
configureEntityParams(this.config.docker, cfg.docker, "networkAliases");
|
||||
configureEntityParams(this.config.docker, cfg.docker, "cpusetCpus", String);
|
||||
configureEntityParams(this.config.docker, cfg.docker, "cpuUsage", Number);
|
||||
configureEntityParams(this.config.docker, cfg.docker, "env");
|
||||
configureEntityParams(this.config.docker, cfg.docker, "workingDir", String);
|
||||
}
|
||||
if (cfg.pingConfig) {
|
||||
configureEntityParams(this.config.pingConfig, cfg.pingConfig, "ip", String);
|
||||
|
@ -17,6 +17,11 @@ interface PortConfigItem extends DockerConfigItem {
|
||||
protocol: string;
|
||||
}
|
||||
|
||||
interface DockerEnvItem {
|
||||
label: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export async function useUploadFileDialog() {
|
||||
return (await useMountComponent().mount<string>(UploadFileDialogVue)) || "";
|
||||
}
|
||||
@ -92,6 +97,27 @@ export async function useVolumeEditDialog(data: DockerConfigItem[] = []) {
|
||||
);
|
||||
}
|
||||
|
||||
export async function useDockerEnvEditDialog(data: DockerEnvItem[] = []) {
|
||||
return (
|
||||
(await useMountComponent({
|
||||
data,
|
||||
title: t("容器环境变量"),
|
||||
columns: [
|
||||
{
|
||||
align: "center",
|
||||
dataIndex: "label",
|
||||
title: t("变量名")
|
||||
},
|
||||
{
|
||||
align: "center",
|
||||
dataIndex: "value",
|
||||
title: t("变量值")
|
||||
}
|
||||
] as AntColumnsType[]
|
||||
}).mount<DockerEnvItem[]>(KvOptionsDialogVue)) || []
|
||||
);
|
||||
}
|
||||
|
||||
export async function openLoadingDialog(title: string, text: string, subTitle?: string) {
|
||||
const component = (
|
||||
await useMountComponent({
|
||||
|
@ -16,7 +16,12 @@ import { Dayjs } from "dayjs";
|
||||
import _ from "lodash";
|
||||
import { GLOBAL_INSTANCE_NAME } from "../../../config/const";
|
||||
import { dayjsToTimestamp, timestampToDayjs } from "../../../tools/time";
|
||||
import { useCmdAssistantDialog, usePortEditDialog, useVolumeEditDialog } from "@/components/fc";
|
||||
import {
|
||||
useCmdAssistantDialog,
|
||||
useDockerEnvEditDialog,
|
||||
usePortEditDialog,
|
||||
useVolumeEditDialog
|
||||
} from "@/components/fc";
|
||||
import { dockerPortsArray } from "@/tools/common";
|
||||
|
||||
interface FormDetail extends InstanceDetail {
|
||||
@ -69,12 +74,14 @@ const isGlobalTerminal = computed(() => {
|
||||
|
||||
const loadImages = async () => {
|
||||
try {
|
||||
dockerImages.value = ["TEST"];
|
||||
const images = await getImageList({
|
||||
params: {
|
||||
daemonId: props.daemonId ?? ""
|
||||
},
|
||||
method: "GET"
|
||||
});
|
||||
|
||||
if (images.value) {
|
||||
dockerImages.value = [t("TXT_CODE_3362d4b7")];
|
||||
for (const iterator of images.value) {
|
||||
@ -169,7 +176,7 @@ const openCmdAssistDialog = async () => {
|
||||
const cmd = await useCmdAssistantDialog();
|
||||
if (options.value && cmd) options.value.config.startCommand = cmd;
|
||||
};
|
||||
const handleEditDockerConfig = async (type: "port" | "volume") => {
|
||||
const handleEditDockerConfig = async (type: "port" | "volume" | "env") => {
|
||||
if (type === "port" && options.value?.config) {
|
||||
// "25565:25565/tcp 8080:8080/tcp" -> Array
|
||||
const portArray = dockerPortsArray(options.value?.config.docker.ports || []);
|
||||
@ -190,6 +197,19 @@ const handleEditDockerConfig = async (type: "port" | "volume") => {
|
||||
const volumesArray = result.map((v) => `${v.host}:${v.container}`);
|
||||
options.value.config.docker.extraVolumes = volumesArray;
|
||||
}
|
||||
|
||||
if (type === "env" && options.value?.config) {
|
||||
const envs = options.value.config.docker.env?.map((v) => {
|
||||
const tmp = v.split("=");
|
||||
return {
|
||||
label: tmp[0] || "",
|
||||
value: tmp[1] || ""
|
||||
};
|
||||
});
|
||||
const result = await useDockerEnvEditDialog(envs);
|
||||
const envsArray = result.map((v) => `${v.label}=${v.value}`);
|
||||
options.value.config.docker.env = envsArray;
|
||||
}
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
@ -218,6 +238,7 @@ defineExpose({
|
||||
autocomplete="off"
|
||||
>
|
||||
<a-row :gutter="20">
|
||||
AAAAA: {{ options?.config.docker.env }}
|
||||
<a-col :xs="24" :md="12" :offset="0">
|
||||
<a-form-item name="nickname">
|
||||
<a-typography-title :level="5" class="require-field">
|
||||
@ -424,6 +445,21 @@ defineExpose({
|
||||
</a-input-group>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :xs="24" :lg="8" :offset="0">
|
||||
<a-form-item>
|
||||
<a-typography-title :level="5">{{ t("环境变量") }}</a-typography-title>
|
||||
<a-typography-paragraph>
|
||||
<a-typography-text type="secondary">
|
||||
{{ t("为容器传递环境变量") }}
|
||||
</a-typography-text>
|
||||
</a-typography-paragraph>
|
||||
<a-input-group compact>
|
||||
<a-button type="default" @click="() => handleEditDockerConfig('env')">
|
||||
{{ t("TXT_CODE_ad207008") }}
|
||||
</a-button>
|
||||
</a-input-group>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :xs="24" :lg="8" :offset="0">
|
||||
<a-form-item>
|
||||
<a-typography-title :level="5">{{ t("TXT_CODE_3e68ca00") }}</a-typography-title>
|
||||
|
Loading…
Reference in New Issue
Block a user