mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-03-13 17:24:44 +08:00
feat: 运行环境支持增加挂载 (#6662)
Refs https://github.com/1Panel-dev/1Panel/issues/5837
This commit is contained in:
parent
e359e1c544
commit
958993f81f
@ -30,12 +30,17 @@ type NodeConfig struct {
|
||||
Port int `json:"port"`
|
||||
ExposedPorts []ExposedPort `json:"exposedPorts"`
|
||||
Environments []Environment `json:"environments"`
|
||||
Volumes []Volume `json:"volumes"`
|
||||
}
|
||||
|
||||
type Environment struct {
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
type Volume struct {
|
||||
Source string `json:"source"`
|
||||
Target string `json:"target"`
|
||||
}
|
||||
|
||||
type ExposedPort struct {
|
||||
HostPort int `json:"hostPort"`
|
||||
|
@ -27,6 +27,7 @@ type RuntimeDTO struct {
|
||||
Path string `json:"path"`
|
||||
ExposedPorts []request.ExposedPort `json:"exposedPorts"`
|
||||
Environments []request.Environment `json:"environments"`
|
||||
Volumes []request.Volume `json:"volumes"`
|
||||
}
|
||||
|
||||
type PackageScripts struct {
|
||||
|
@ -387,6 +387,32 @@ func (r *RuntimeService) Get(id uint) (*response.RuntimeDTO, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
volumes, err := getDockerComposeVolumes(composeByte)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defaultVolumes := make(map[string]string)
|
||||
switch runtime.Type {
|
||||
case constant.RuntimeNode:
|
||||
defaultVolumes = constant.RuntimeDefaultVolumes
|
||||
case constant.RuntimeJava:
|
||||
defaultVolumes = constant.RuntimeDefaultVolumes
|
||||
case constant.RuntimeGo:
|
||||
defaultVolumes = constant.GoDefaultVolumes
|
||||
}
|
||||
for _, volume := range volumes {
|
||||
exist := false
|
||||
for key, value := range defaultVolumes {
|
||||
if key == volume.Source && value == volume.Target {
|
||||
exist = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !exist {
|
||||
res.Volumes = append(res.Volumes, volume)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
@ -461,6 +487,7 @@ func (r *RuntimeService) Update(req request.RuntimeUpdate) error {
|
||||
Install: true,
|
||||
ExposedPorts: req.ExposedPorts,
|
||||
Environments: req.Environments,
|
||||
Volumes: req.Volumes,
|
||||
},
|
||||
}
|
||||
composeContent, envContent, _, err := handleParams(create, projectDir)
|
||||
|
@ -474,9 +474,27 @@ func handleCompose(env gotenv.Env, composeContent []byte, create request.Runtime
|
||||
for _, e := range create.Environments {
|
||||
environments = append(environments, fmt.Sprintf("%s:%s", e.Key, e.Value))
|
||||
}
|
||||
delete(serviceValue, "environment")
|
||||
if len(environments) > 0 {
|
||||
serviceValue["environment"] = environments
|
||||
}
|
||||
var volumes []interface{}
|
||||
defaultVolumes := make(map[string]string)
|
||||
switch create.Type {
|
||||
case constant.RuntimeNode:
|
||||
defaultVolumes = constant.RuntimeDefaultVolumes
|
||||
case constant.RuntimeJava:
|
||||
defaultVolumes = constant.RuntimeDefaultVolumes
|
||||
case constant.RuntimeGo:
|
||||
defaultVolumes = constant.GoDefaultVolumes
|
||||
}
|
||||
for k, v := range defaultVolumes {
|
||||
volumes = append(volumes, fmt.Sprintf("%s:%s", k, v))
|
||||
}
|
||||
for _, volume := range create.Volumes {
|
||||
volumes = append(volumes, fmt.Sprintf("%s:%s", volume.Source, volume.Target))
|
||||
}
|
||||
serviceValue["volumes"] = volumes
|
||||
break
|
||||
}
|
||||
for k := range env {
|
||||
@ -648,3 +666,30 @@ func getDockerComposeEnvironments(yml []byte) ([]request.Environment, error) {
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func getDockerComposeVolumes(yml []byte) ([]request.Volume, error) {
|
||||
var (
|
||||
composeProject docker.ComposeProject
|
||||
err error
|
||||
)
|
||||
err = yaml.Unmarshal(yml, &composeProject)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var res []request.Volume
|
||||
for _, service := range composeProject.Services {
|
||||
for _, volume := range service.Volumes {
|
||||
envArray := strings.Split(volume, ":")
|
||||
source := envArray[0]
|
||||
target := ""
|
||||
if len(envArray) > 1 {
|
||||
target = envArray[1]
|
||||
}
|
||||
res = append(res, request.Volume{
|
||||
Source: source,
|
||||
Target: target,
|
||||
})
|
||||
}
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
@ -34,3 +34,16 @@ const (
|
||||
RuntimeNpm = "npm"
|
||||
RuntimeYarn = "yarn"
|
||||
)
|
||||
|
||||
var GoDefaultVolumes = map[string]string{
|
||||
"${CODE_DIR}": "/app",
|
||||
"./run.sh": "/run.sh",
|
||||
"./.env": "/.env",
|
||||
"./mod": "/go/pkg/mod",
|
||||
}
|
||||
|
||||
var RuntimeDefaultVolumes = map[string]string{
|
||||
"./run.sh": "/run.sh",
|
||||
"./.env": "/.env",
|
||||
"./mod": "/go/pkg/mod",
|
||||
}
|
||||
|
@ -55,6 +55,7 @@ type ComposeProject struct {
|
||||
type Service struct {
|
||||
Image string `yaml:"image"`
|
||||
Environment []string `yaml:"environment"`
|
||||
Volumes []string `json:"volumes"`
|
||||
}
|
||||
|
||||
func replaceEnvVariables(input string, envVars map[string]string) string {
|
||||
|
@ -234,11 +234,13 @@ func (l *Location) AddSubFilter(subFilters map[string]string) {
|
||||
}
|
||||
l.UpdateDirective("proxy_set_header", []string{"Accept-Encoding", `""`})
|
||||
l.UpdateDirective("sub_filter_once", []string{"off"})
|
||||
l.UpdateDirective("sub_filter_types", []string{"*"})
|
||||
}
|
||||
|
||||
func (l *Location) RemoveSubFilter() {
|
||||
l.RemoveDirective("sub_filter", []string{})
|
||||
l.RemoveDirective("proxy_set_header", []string{"Accept-Encoding", `""`})
|
||||
l.RemoveDirective("sub_filter_once", []string{"off"})
|
||||
l.RemoveDirective("sub_filter_types", []string{"*"})
|
||||
l.Replaces = nil
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ export namespace Runtime {
|
||||
path?: string;
|
||||
exposedPorts?: ExposedPort[];
|
||||
environments?: Environment[];
|
||||
volumes?: Volume[];
|
||||
}
|
||||
|
||||
export interface RuntimeCreate {
|
||||
@ -58,6 +59,7 @@ export namespace Runtime {
|
||||
port?: number;
|
||||
exposedPorts?: ExposedPort[];
|
||||
environments?: Environment[];
|
||||
volumes?: Volume[];
|
||||
}
|
||||
|
||||
export interface ExposedPort {
|
||||
@ -69,6 +71,10 @@ export namespace Runtime {
|
||||
key: string;
|
||||
value: string;
|
||||
}
|
||||
export interface Volume {
|
||||
source: string;
|
||||
target: string;
|
||||
}
|
||||
|
||||
export interface RuntimeUpdate {
|
||||
name: string;
|
||||
|
@ -1,37 +1,22 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<el-drawer
|
||||
v-model="drawerVisible"
|
||||
:destroy-on-close="true"
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="false"
|
||||
size="30%"
|
||||
>
|
||||
<template #header>
|
||||
<DrawerHeader :header="$t('terminal.groupChange')" :back="handleClose" />
|
||||
</template>
|
||||
<el-row type="flex" justify="center">
|
||||
<el-col :span="22">
|
||||
<el-form @submit.prevent ref="hostInfoRef" label-position="top" :model="dialogData" :rules="rules">
|
||||
<el-form-item :label="$t('commons.table.group')" prop="group">
|
||||
<el-select filterable v-model="dialogData.groupID" clearable style="width: 100%">
|
||||
<div v-for="item in groupList" :key="item.id">
|
||||
<el-option :label="item.name" :value="item.id" />
|
||||
</div>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<DrawerPro v-model="drawerVisible" :header="$t('terminal.groupChange')" :back="handleClose" size="small">
|
||||
<el-form @submit.prevent ref="hostInfoRef" label-position="top" :model="dialogData" :rules="rules">
|
||||
<el-form-item :label="$t('commons.table.group')" prop="group">
|
||||
<el-select filterable v-model="dialogData.groupID" clearable style="width: 100%">
|
||||
<div v-for="item in groupList" :key="item.id">
|
||||
<el-option :label="item.name" :value="item.id" />
|
||||
</div>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="onSubmit(hostInfoRef)">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</span>
|
||||
<el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="onSubmit(hostInfoRef)">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-drawer>
|
||||
</DrawerPro>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -40,7 +25,6 @@ import { ref, reactive } from 'vue';
|
||||
import type { ElForm } from 'element-plus';
|
||||
import { Rules } from '@/global/form-rules';
|
||||
import { GetGroupList } from '@/api/modules/group';
|
||||
import DrawerHeader from '@/components/drawer-header/index.vue';
|
||||
|
||||
const loading = ref();
|
||||
interface DialogProps {
|
||||
|
@ -62,7 +62,7 @@
|
||||
</template>
|
||||
<template #main>
|
||||
<div>
|
||||
<MainDiv :heightDiff="mode === 'upgrade' ? 280 : 380">
|
||||
<MainDiv :heightDiff="mode === 'upgrade' ? 320 : 350">
|
||||
<el-alert
|
||||
type="info"
|
||||
:title="$t('app.upgradeHelper')"
|
||||
|
@ -1,52 +1,37 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-drawer
|
||||
v-model="deleteVisible"
|
||||
:destroy-on-close="true"
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="false"
|
||||
size="30%"
|
||||
>
|
||||
<template #header>
|
||||
<DrawerHeader :header="$t('container.imageDelete')" :back="handleClose" />
|
||||
</template>
|
||||
<DrawerPro v-model="deleteVisible" :header="$t('container.imageDelete')" :back="handleClose" size="small">
|
||||
<el-form @submit.prevent :model="form" label-position="top">
|
||||
<el-row type="flex" justify="center">
|
||||
<el-col :span="22">
|
||||
<el-form-item :label="$t('container.tag')" prop="tagName">
|
||||
<div style="width: 100%">
|
||||
<el-checkbox
|
||||
v-model="deleteAll"
|
||||
:indeterminate="isIndeterminate"
|
||||
@change="handleCheckAllChange"
|
||||
>
|
||||
{{ $t('container.removeAll') }}
|
||||
</el-checkbox>
|
||||
</div>
|
||||
<el-checkbox-group v-model="form.deleteTags" @change="handleCheckedChange">
|
||||
<div>
|
||||
<el-checkbox
|
||||
style="width: 100%"
|
||||
v-for="item in form.tags"
|
||||
:key="item"
|
||||
:value="item"
|
||||
:label="item"
|
||||
/>
|
||||
</div>
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item :label="$t('container.tag')" prop="tagName">
|
||||
<div style="width: 100%">
|
||||
<el-checkbox
|
||||
v-model="deleteAll"
|
||||
:indeterminate="isIndeterminate"
|
||||
@change="handleCheckAllChange"
|
||||
>
|
||||
{{ $t('container.removeAll') }}
|
||||
</el-checkbox>
|
||||
</div>
|
||||
<el-checkbox-group v-model="form.deleteTags" @change="handleCheckedChange">
|
||||
<div>
|
||||
<el-checkbox
|
||||
style="width: 100%"
|
||||
v-for="item in form.tags"
|
||||
:key="item"
|
||||
:value="item"
|
||||
:label="item"
|
||||
/>
|
||||
</div>
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="deleteVisible = false">{{ $t('commons.button.cancel') }}</el-button>
|
||||
<el-button type="primary" :disabled="form.deleteTags.length === 0" @click="batchDelete()">
|
||||
{{ $t('commons.button.delete') }}
|
||||
</el-button>
|
||||
</span>
|
||||
<el-button @click="deleteVisible = false">{{ $t('commons.button.cancel') }}</el-button>
|
||||
<el-button type="primary" :disabled="form.deleteTags.length === 0" @click="batchDelete()">
|
||||
{{ $t('commons.button.delete') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-drawer>
|
||||
</DrawerPro>
|
||||
|
||||
<OpDialog ref="opRef" @search="onSearch" @cancel="handleClose" />
|
||||
</div>
|
||||
@ -55,7 +40,6 @@
|
||||
import { reactive, ref } from 'vue';
|
||||
import { ElForm } from 'element-plus';
|
||||
import { imageRemove } from '@/api/modules/container';
|
||||
import DrawerHeader from '@/components/drawer-header/index.vue';
|
||||
import i18n from '@/lang';
|
||||
|
||||
const deleteVisible = ref(false);
|
||||
|
@ -1,55 +1,39 @@
|
||||
<template>
|
||||
<el-drawer
|
||||
v-model="drawerVisible"
|
||||
:destroy-on-close="true"
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="false"
|
||||
size="30%"
|
||||
>
|
||||
<template #header>
|
||||
<DrawerHeader :header="$t('container.exportImage')" :back="handleClose" />
|
||||
</template>
|
||||
<DrawerPro v-model="drawerVisible" :header="$t('terminal.exportImage')" :back="handleClose" size="small">
|
||||
<el-form v-loading="loading" label-position="top" ref="formRef" :model="form" label-width="80px">
|
||||
<el-row type="flex" justify="center">
|
||||
<el-col :span="22">
|
||||
<el-form-item :label="$t('container.tag')" :rules="Rules.requiredSelect" prop="tagName">
|
||||
<el-select filterable v-model="form.tagName">
|
||||
<el-option
|
||||
:disabled="item.indexOf(':<none>') !== -1"
|
||||
v-for="item in form.tags"
|
||||
:key="item"
|
||||
:value="item"
|
||||
:label="item"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('container.path')" :rules="Rules.requiredInput" prop="path">
|
||||
<el-input v-model="form.path">
|
||||
<template #prepend>
|
||||
<FileList @choose="loadSaveDir" :dir="true"></FileList>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('container.fileName')" :rules="Rules.requiredInput" prop="name">
|
||||
<el-input v-model="form.name">
|
||||
<template #append>.tar</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item :label="$t('container.tag')" :rules="Rules.requiredSelect" prop="tagName">
|
||||
<el-select filterable v-model="form.tagName">
|
||||
<el-option
|
||||
:disabled="item.indexOf(':<none>') !== -1"
|
||||
v-for="item in form.tags"
|
||||
:key="item"
|
||||
:value="item"
|
||||
:label="item"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('container.path')" :rules="Rules.requiredInput" prop="path">
|
||||
<el-input v-model="form.path">
|
||||
<template #prepend>
|
||||
<FileList @choose="loadSaveDir" :dir="true"></FileList>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('container.fileName')" :rules="Rules.requiredInput" prop="name">
|
||||
<el-input v-model="form.name">
|
||||
<template #append>.tar</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button :disabled="loading" @click="drawerVisible = false">
|
||||
{{ $t('commons.button.cancel') }}
|
||||
</el-button>
|
||||
<el-button :disabled="loading" type="primary" @click="onSubmit(formRef)">
|
||||
{{ $t('container.export') }}
|
||||
</el-button>
|
||||
</span>
|
||||
<el-button :disabled="loading" @click="drawerVisible = false">
|
||||
{{ $t('commons.button.cancel') }}
|
||||
</el-button>
|
||||
<el-button :disabled="loading" type="primary" @click="onSubmit(formRef)">
|
||||
{{ $t('container.export') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-drawer>
|
||||
</DrawerPro>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
@ -60,7 +44,6 @@ import i18n from '@/lang';
|
||||
import { ElForm } from 'element-plus';
|
||||
import { imageSave } from '@/api/modules/container';
|
||||
import { Container } from '@/api/interface/container';
|
||||
import DrawerHeader from '@/components/drawer-header/index.vue';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
|
||||
const loading = ref(false);
|
||||
|
@ -1,16 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-drawer
|
||||
v-model="drawerVisible"
|
||||
:destroy-on-close="true"
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="false"
|
||||
@close="handleClose"
|
||||
size="30%"
|
||||
>
|
||||
<template #header>
|
||||
<DrawerHeader header="IPv6" :back="handleClose" />
|
||||
</template>
|
||||
<DrawerPro v-model="drawerVisible" header="IPv6" :back="handleClose" size="small">
|
||||
<el-alert class="common-prompt" :closable="false" type="warning">
|
||||
<template #default>
|
||||
<span class="input-help">
|
||||
@ -28,37 +18,31 @@
|
||||
</el-alert>
|
||||
|
||||
<el-form :model="form" ref="formRef" :rules="rules" v-loading="loading" label-position="top">
|
||||
<el-row type="flex" justify="center">
|
||||
<el-col :span="22">
|
||||
<el-form-item prop="fixedCidrV6" :label="$t('container.subnet')">
|
||||
<el-input v-model="form.fixedCidrV6" />
|
||||
<span class="input-help">{{ $t('container.ipv6CidrHelper') }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-checkbox v-model="showMore" :label="$t('app.advanced')" />
|
||||
</el-form-item>
|
||||
<div v-if="showMore">
|
||||
<el-form-item prop="ip6Tables" label="ip6tables">
|
||||
<el-switch v-model="form.ip6Tables"></el-switch>
|
||||
<span class="input-help">{{ $t('container.ipv6TablesHelper') }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item prop="experimental" label="experimental">
|
||||
<el-switch v-model="form.experimental"></el-switch>
|
||||
<span class="input-help">{{ $t('container.experimentalHelper') }}</span>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item prop="fixedCidrV6" :label="$t('container.subnet')">
|
||||
<el-input v-model="form.fixedCidrV6" />
|
||||
<span class="input-help">{{ $t('container.ipv6CidrHelper') }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-checkbox v-model="showMore" :label="$t('app.advanced')" />
|
||||
</el-form-item>
|
||||
<div v-if="showMore">
|
||||
<el-form-item prop="ip6Tables" label="ip6tables">
|
||||
<el-switch v-model="form.ip6Tables"></el-switch>
|
||||
<span class="input-help">{{ $t('container.ipv6TablesHelper') }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item prop="experimental" label="experimental">
|
||||
<el-switch v-model="form.experimental"></el-switch>
|
||||
<span class="input-help">{{ $t('container.experimentalHelper') }}</span>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="handleClose">{{ $t('commons.button.cancel') }}</el-button>
|
||||
<el-button :disabled="loading" type="primary" @click="onSave(formRef)">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</span>
|
||||
<el-button @click="handleClose">{{ $t('commons.button.cancel') }}</el-button>
|
||||
<el-button :disabled="loading" type="primary" @click="onSave(formRef)">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-drawer>
|
||||
</DrawerPro>
|
||||
|
||||
<ConfirmDialog ref="confirmDialogRef" @confirm="onSubmitSave"></ConfirmDialog>
|
||||
</div>
|
||||
@ -69,7 +53,6 @@ import i18n from '@/lang';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { FormInstance } from 'element-plus';
|
||||
import { updateIpv6Option } from '@/api/modules/container';
|
||||
import DrawerHeader from '@/components/drawer-header/index.vue';
|
||||
import { checkIpV6 } from '@/utils/util';
|
||||
|
||||
const loading = ref();
|
||||
|
@ -1,16 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-drawer
|
||||
v-model="drawerVisible"
|
||||
:destroy-on-close="true"
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="false"
|
||||
@close="handleClose"
|
||||
size="30%"
|
||||
>
|
||||
<template #header>
|
||||
<DrawerHeader :header="$t('container.cutLog')" :back="handleClose" />
|
||||
</template>
|
||||
<DrawerPro v-model="drawerVisible" :header="$t('container.cutLog')" :back="handleClose" size="small">
|
||||
<el-alert class="common-prompt" :closable="false" type="warning">
|
||||
<template #default>
|
||||
<ul style="margin-left: -20px">
|
||||
@ -21,36 +11,29 @@
|
||||
</template>
|
||||
</el-alert>
|
||||
<el-form :model="form" ref="formRef" :rules="rules" v-loading="loading" label-position="top">
|
||||
<el-row type="flex" justify="center">
|
||||
<el-col :span="22">
|
||||
<el-form-item prop="logMaxSize" :label="$t('container.maxSize')">
|
||||
<el-input v-model.number="form.logMaxSize">
|
||||
<template #append>
|
||||
<el-select v-model="form.sizeUnit" style="width: 70px">
|
||||
<el-option label="Byte" value="b"></el-option>
|
||||
<el-option label="KB" value="k"></el-option>
|
||||
<el-option label="MB" value="m"></el-option>
|
||||
<el-option label="GB" value="g"></el-option>
|
||||
</el-select>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="logMaxFile" :label="$t('container.maxFile')">
|
||||
<el-input v-model.number="form.logMaxFile" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item prop="logMaxSize" :label="$t('container.maxSize')">
|
||||
<el-input v-model.number="form.logMaxSize">
|
||||
<template #append>
|
||||
<el-select v-model="form.sizeUnit" style="width: 70px">
|
||||
<el-option label="Byte" value="b"></el-option>
|
||||
<el-option label="KB" value="k"></el-option>
|
||||
<el-option label="MB" value="m"></el-option>
|
||||
<el-option label="GB" value="g"></el-option>
|
||||
</el-select>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="logMaxFile" :label="$t('container.maxFile')">
|
||||
<el-input v-model.number="form.logMaxFile" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="handleClose">{{ $t('commons.button.cancel') }}</el-button>
|
||||
<el-button :disabled="loading" type="primary" @click="onSave(formRef)">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</span>
|
||||
<el-button @click="handleClose">{{ $t('commons.button.cancel') }}</el-button>
|
||||
<el-button :disabled="loading" type="primary" @click="onSave(formRef)">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-drawer>
|
||||
|
||||
</DrawerPro>
|
||||
<ConfirmDialog ref="confirmDialogRef" @confirm="onSubmitSave"></ConfirmDialog>
|
||||
</div>
|
||||
</template>
|
||||
@ -61,7 +44,6 @@ import i18n from '@/lang';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { FormInstance } from 'element-plus';
|
||||
import { updateLogOption } from '@/api/modules/container';
|
||||
import DrawerHeader from '@/components/drawer-header/index.vue';
|
||||
|
||||
const loading = ref();
|
||||
const drawerVisible = ref();
|
||||
|
@ -1,15 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-drawer
|
||||
v-model="drawerVisible"
|
||||
:destroy-on-close="true"
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="false"
|
||||
size="30%"
|
||||
>
|
||||
<template #header>
|
||||
<DrawerHeader :header="$t('container.mirrors')" :back="handleClose" />
|
||||
</template>
|
||||
<DrawerPro v-model="drawerVisible" :header="$t('container.mirrors')" :back="handleClose" size="small">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
label-position="top"
|
||||
@ -18,28 +9,22 @@
|
||||
:rules="rules"
|
||||
v-loading="loading"
|
||||
>
|
||||
<el-row type="flex" justify="center">
|
||||
<el-col :span="22">
|
||||
<el-form-item :label="$t('container.mirrors')" prop="mirrors">
|
||||
<el-input
|
||||
type="textarea"
|
||||
:placeholder="$t('container.mirrorHelper')"
|
||||
:rows="5"
|
||||
v-model="form.mirrors"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item :label="$t('container.mirrors')" prop="mirrors">
|
||||
<el-input
|
||||
type="textarea"
|
||||
:placeholder="$t('container.mirrorHelper')"
|
||||
:rows="5"
|
||||
v-model="form.mirrors"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button>
|
||||
<el-button :disabled="loading" type="primary" @click="onSave(formRef)">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</span>
|
||||
<el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button>
|
||||
<el-button :disabled="loading" type="primary" @click="onSave(formRef)">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-drawer>
|
||||
</DrawerPro>
|
||||
|
||||
<ConfirmDialog ref="confirmDialogRef" @confirm="onSubmit" />
|
||||
</div>
|
||||
@ -50,7 +35,6 @@ import i18n from '@/lang';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import ConfirmDialog from '@/components/confirm-dialog/index.vue';
|
||||
import { updateDaemonJson } from '@/api/modules/container';
|
||||
import DrawerHeader from '@/components/drawer-header/index.vue';
|
||||
import { FormInstance } from 'element-plus';
|
||||
import { emptyLineFilter } from '@/utils/util';
|
||||
|
||||
|
@ -1,15 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-drawer
|
||||
v-model="drawerVisible"
|
||||
:destroy-on-close="true"
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="false"
|
||||
size="30%"
|
||||
>
|
||||
<template #header>
|
||||
<DrawerHeader :header="$t('container.registries')" :back="handleClose" />
|
||||
</template>
|
||||
<DrawerPro v-model="drawerVisible" :header="$t('container.registries')" :back="handleClose" size="small">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
label-position="top"
|
||||
@ -18,29 +9,22 @@
|
||||
@submit.prevent
|
||||
v-loading="loading"
|
||||
>
|
||||
<el-row type="flex" justify="center">
|
||||
<el-col :span="22">
|
||||
<el-form-item :label="$t('container.registries')" prop="registries">
|
||||
<el-input
|
||||
type="textarea"
|
||||
:placeholder="$t('container.registrieHelper')"
|
||||
:rows="5"
|
||||
v-model="form.registries"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item :label="$t('container.registries')" prop="registries">
|
||||
<el-input
|
||||
type="textarea"
|
||||
:placeholder="$t('container.registrieHelper')"
|
||||
:rows="5"
|
||||
v-model="form.registries"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button>
|
||||
<el-button :disabled="loading" type="primary" @click="onSave">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</span>
|
||||
<el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button>
|
||||
<el-button :disabled="loading" type="primary" @click="onSave">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-drawer>
|
||||
|
||||
</DrawerPro>
|
||||
<ConfirmDialog ref="confirmDialogRef" @confirm="onSubmit" />
|
||||
</div>
|
||||
</template>
|
||||
@ -50,7 +34,6 @@ import i18n from '@/lang';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import ConfirmDialog from '@/components/confirm-dialog/index.vue';
|
||||
import { updateDaemonJson } from '@/api/modules/container';
|
||||
import DrawerHeader from '@/components/drawer-header/index.vue';
|
||||
import { FormInstance } from 'element-plus';
|
||||
import { emptyLineFilter } from '@/utils/util';
|
||||
|
||||
|
@ -1,15 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-drawer
|
||||
v-model="drawerVisible"
|
||||
:destroy-on-close="true"
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="false"
|
||||
size="30%"
|
||||
>
|
||||
<template #header>
|
||||
<DrawerHeader :header="$t('container.sockPath')" :back="handleClose" />
|
||||
</template>
|
||||
<DrawerPro v-model="drawerVisible" :header="$t('container.sockPath')" :back="handleClose" size="small">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
label-position="top"
|
||||
@ -18,29 +9,23 @@
|
||||
@submit.prevent
|
||||
v-loading="loading"
|
||||
>
|
||||
<el-row type="flex" justify="center">
|
||||
<el-col :span="22">
|
||||
<el-form-item :label="$t('container.sockPath')" prop="dockerSockPath">
|
||||
<el-input v-model="form.dockerSockPath">
|
||||
<template #prepend>unix://</template>
|
||||
<template #append>
|
||||
<FileList @choose="loadBuildDir"></FileList>
|
||||
</template>
|
||||
</el-input>
|
||||
<span class="input-help">{{ $t('container.sockPathHelper1') }}</span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item :label="$t('container.sockPath')" prop="dockerSockPath">
|
||||
<el-input v-model="form.dockerSockPath">
|
||||
<template #prepend>unix://</template>
|
||||
<template #append>
|
||||
<FileList @choose="loadBuildDir"></FileList>
|
||||
</template>
|
||||
</el-input>
|
||||
<span class="input-help">{{ $t('container.sockPathHelper1') }}</span>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button>
|
||||
<el-button :disabled="loading" type="primary" @click="onSubmit(formRef)">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</span>
|
||||
<el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button>
|
||||
<el-button :disabled="loading" type="primary" @click="onSubmit(formRef)">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-drawer>
|
||||
</DrawerPro>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
@ -48,7 +33,6 @@ import { reactive, ref } from 'vue';
|
||||
import i18n from '@/lang';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { updateSetting } from '@/api/modules/setting';
|
||||
import DrawerHeader from '@/components/drawer-header/index.vue';
|
||||
import { ElMessageBox, FormInstance } from 'element-plus';
|
||||
|
||||
const emit = defineEmits<{ (e: 'search'): void }>();
|
||||
|
@ -1,40 +1,31 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-drawer
|
||||
<DrawerPro
|
||||
v-model="changeVisible"
|
||||
:destroy-on-close="true"
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="false"
|
||||
width="30%"
|
||||
:header="$t('database.permission')"
|
||||
:resource="form.name"
|
||||
:back="handleClose"
|
||||
size="small"
|
||||
>
|
||||
<template #header>
|
||||
<DrawerHeader :header="$t('database.permission')" :resource="form.name" :back="handleClose" />
|
||||
</template>
|
||||
<el-form v-loading="loading" :model="form" label-position="top">
|
||||
<el-row type="flex" justify="center">
|
||||
<el-col :span="22">
|
||||
<el-form-item :label="$t('database.userBind')">
|
||||
<el-tag>
|
||||
{{ form.username }}
|
||||
</el-tag>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('database.permission')" prop="superUser">
|
||||
<el-checkbox v-model="form.superUser">{{ $t('database.pgSuperUser') }}</el-checkbox>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item :label="$t('database.userBind')">
|
||||
<el-tag>
|
||||
{{ form.username }}
|
||||
</el-tag>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('database.permission')" prop="superUser">
|
||||
<el-checkbox v-model="form.superUser">{{ $t('database.pgSuperUser') }}</el-checkbox>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button :disabled="loading" @click="changeVisible = false">
|
||||
{{ $t('commons.button.cancel') }}
|
||||
</el-button>
|
||||
<el-button :disabled="loading" type="primary" @click="onSubmit()">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</span>
|
||||
<el-button :disabled="loading" @click="changeVisible = false">
|
||||
{{ $t('commons.button.cancel') }}
|
||||
</el-button>
|
||||
<el-button :disabled="loading" type="primary" @click="onSubmit()">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-drawer>
|
||||
</DrawerPro>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
@ -42,7 +33,6 @@ import { reactive, ref } from 'vue';
|
||||
import i18n from '@/lang';
|
||||
import { ElForm } from 'element-plus';
|
||||
import { changePrivileges } from '@/api/modules/database';
|
||||
import DrawerHeader from '@/components/drawer-header/index.vue';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
|
||||
const loading = ref();
|
||||
|
@ -1,29 +1,32 @@
|
||||
<template>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="4">
|
||||
<el-button @click="addEnv">{{ $t('commons.button.add') }}{{ $t('runtime.environment') }}</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<div class="mt-1.5">
|
||||
<el-row :gutter="20" v-for="(env, index) in environments" :key="index">
|
||||
<el-col :span="7">
|
||||
<el-form-item :prop="`environments.${index}.key`" :rules="rules.value">
|
||||
<el-input v-model="env.key" :placeholder="$t('runtime.envKey')" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="7">
|
||||
<el-form-item :prop="`environments.${index}.value`" :rules="rules.value">
|
||||
<el-input v-model="env.value" :placeholder="$t('runtime.envValue')" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="removeEnv(index)" link>
|
||||
{{ $t('commons.button.delete') }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-text>{{ $t('runtime.environment') }}</el-text>
|
||||
<div class="mt-1.5">
|
||||
<el-row :gutter="20" v-for="(env, index) in environments" :key="index">
|
||||
<el-col :span="7">
|
||||
<el-form-item :prop="`environments.${index}.key`" :rules="rules.value">
|
||||
<el-input v-model="env.key" :placeholder="$t('runtime.envKey')" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="7">
|
||||
<el-form-item :prop="`environments.${index}.value`" :rules="rules.value">
|
||||
<el-input v-model="env.value" :placeholder="$t('runtime.envValue')" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="removeEnv(index)" link>
|
||||
{{ $t('commons.button.delete') }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="4">
|
||||
<el-button @click="addEnv">{{ $t('commons.button.add') }}{{ $t('runtime.environment') }}</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -79,6 +79,7 @@
|
||||
</el-row>
|
||||
<PortConfig :params="runtime.params" :exposedPorts="runtime.exposedPorts" :rules="rules" />
|
||||
<Environment :environments="runtime.environments" />
|
||||
<Volumes :volumes="runtime.volumes" />
|
||||
<el-form-item :label="$t('app.containerName')" prop="params.CONTAINER_NAME">
|
||||
<el-input v-model.trim="runtime.params['CONTAINER_NAME']"></el-input>
|
||||
</el-form-item>
|
||||
@ -105,6 +106,7 @@ import { FormInstance } from 'element-plus';
|
||||
import { reactive, ref, watch } from 'vue';
|
||||
import PortConfig from '@/views/website/runtime/port/index.vue';
|
||||
import Environment from '@/views/website/runtime/environment/index.vue';
|
||||
import Volumes from '@/views/website/runtime/volume/index.vue';
|
||||
|
||||
interface OperateRrops {
|
||||
id?: number;
|
||||
@ -139,6 +141,7 @@ const initData = (type: string) => ({
|
||||
port: 8080,
|
||||
exposedPorts: [],
|
||||
environments: [],
|
||||
volumes: [],
|
||||
});
|
||||
let runtime = reactive<Runtime.RuntimeCreate>(initData('go'));
|
||||
const rules = ref<any>({
|
||||
@ -307,6 +310,7 @@ const getRuntime = async (id: number) => {
|
||||
});
|
||||
runtime.exposedPorts = data.exposedPorts || [];
|
||||
runtime.environments = data.environments || [];
|
||||
runtime.volumes = data.volumes || [];
|
||||
editParams.value = data.appParams;
|
||||
searchApp(data.appID);
|
||||
open.value = true;
|
||||
|
60
frontend/src/views/website/runtime/volume/index.vue
Normal file
60
frontend/src/views/website/runtime/volume/index.vue
Normal file
@ -0,0 +1,60 @@
|
||||
<template>
|
||||
<div class="mt-1.5">
|
||||
<el-text>{{ $t('container.mount') }}</el-text>
|
||||
<div class="mt-1.5">
|
||||
<el-row :gutter="20" v-for="(volume, index) in volumes" :key="index">
|
||||
<el-col :span="7">
|
||||
<el-form-item :prop="`volumes.${index}.source`" :rules="rules.value">
|
||||
<el-input v-model="volume.source" :placeholder="$t('container.hostOption')" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="7">
|
||||
<el-form-item :prop="`volumes.${index}.target`" :rules="rules.value">
|
||||
<el-input v-model="volume.target" :placeholder="$t('container.containerDir')" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="removeEnv(index)" link>
|
||||
{{ $t('commons.button.delete') }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="4">
|
||||
<el-button @click="addEnv">{{ $t('commons.button.add') }}{{ $t('container.mount') }}</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { defineProps, reactive } from 'vue';
|
||||
import { FormRules } from 'element-plus';
|
||||
import { Rules } from '@/global/form-rules';
|
||||
import { Runtime } from '@/api/interface/runtime';
|
||||
|
||||
const props = defineProps({
|
||||
volumes: {
|
||||
type: Array<Runtime.Volume>,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
const rules = reactive<FormRules>({
|
||||
value: [Rules.requiredInput],
|
||||
});
|
||||
|
||||
const addEnv = () => {
|
||||
props.volumes.push({
|
||||
source: '',
|
||||
target: '',
|
||||
});
|
||||
};
|
||||
|
||||
const removeEnv = (index: number) => {
|
||||
props.volumes.splice(index, 1);
|
||||
};
|
||||
</script>
|
@ -97,7 +97,6 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import DrawerHeader from '@/components/drawer-header/index.vue';
|
||||
import { OperateProxyConfig } from '@/api/modules/website';
|
||||
import { checkNumberRange, Rules } from '@/global/form-rules';
|
||||
import i18n from '@/lang';
|
||||
|
Loading…
x
Reference in New Issue
Block a user