mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-10-06 05:24:33 +08:00
feat(runtime): Optimize Runtime Module Components (#7548)
This commit is contained in:
parent
18321d6e5a
commit
c6346b7b6f
17 changed files with 359 additions and 840 deletions
|
@ -27,7 +27,6 @@ type RuntimeCreate struct {
|
||||||
type NodeConfig struct {
|
type NodeConfig struct {
|
||||||
Install bool `json:"install"`
|
Install bool `json:"install"`
|
||||||
Clean bool `json:"clean"`
|
Clean bool `json:"clean"`
|
||||||
Port int `json:"port"`
|
|
||||||
ExposedPorts []ExposedPort `json:"exposedPorts"`
|
ExposedPorts []ExposedPort `json:"exposedPorts"`
|
||||||
Environments []Environment `json:"environments"`
|
Environments []Environment `json:"environments"`
|
||||||
Volumes []Volume `json:"volumes"`
|
Volumes []Volume `json:"volumes"`
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
type Runtime struct {
|
type Runtime struct {
|
||||||
BaseModel
|
BaseModel
|
||||||
Name string `gorm:"not null" json:"name"`
|
Name string `gorm:"not null" json:"name"`
|
||||||
AppDetailID uint `json:"appDetailId"`
|
AppDetailID uint `json:"appDetailID"`
|
||||||
Image string `json:"image"`
|
Image string `json:"image"`
|
||||||
WorkDir string `json:"workDir"`
|
WorkDir string `json:"workDir"`
|
||||||
DockerCompose string `json:"dockerCompose"`
|
DockerCompose string `json:"dockerCompose"`
|
||||||
|
|
|
@ -109,26 +109,23 @@ func (r *RuntimeService) Create(create request.RuntimeCreate) (*model.Runtime, e
|
||||||
if exist != nil {
|
if exist != nil {
|
||||||
return nil, buserr.New(constant.ErrImageExist)
|
return nil, buserr.New(constant.ErrImageExist)
|
||||||
}
|
}
|
||||||
portValue, _ := create.Params["PANEL_APP_PORT_HTTP"]
|
|
||||||
if portValue != nil {
|
|
||||||
if err := checkPortExist(int(portValue.(float64))); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo, constant.RuntimePython, constant.RuntimeDotNet:
|
case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo, constant.RuntimePython, constant.RuntimeDotNet:
|
||||||
if !fileOp.Stat(create.CodeDir) {
|
if !fileOp.Stat(create.CodeDir) {
|
||||||
return nil, buserr.New(constant.ErrPathNotFound)
|
return nil, buserr.New(constant.ErrPathNotFound)
|
||||||
}
|
}
|
||||||
create.Install = true
|
create.Install = true
|
||||||
if err := checkPortExist(create.Port); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
for _, export := range create.ExposedPorts {
|
for _, export := range create.ExposedPorts {
|
||||||
if err := checkPortExist(export.HostPort); err != nil {
|
if err := checkPortExist(export.HostPort); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
portValue, _ := create.Params["PANEL_APP_PORT_HTTP"]
|
||||||
|
if portValue != nil {
|
||||||
|
if err := checkPortExist(int(portValue.(float64))); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
containerName, ok := create.Params["CONTAINER_NAME"]
|
containerName, ok := create.Params["CONTAINER_NAME"]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, buserr.New("ErrContainerNameIsNull")
|
return nil, buserr.New("ErrContainerNameIsNull")
|
||||||
|
@ -161,17 +158,16 @@ func (r *RuntimeService) Create(create request.RuntimeCreate) (*model.Runtime, e
|
||||||
Resource: create.Resource,
|
Resource: create.Resource,
|
||||||
Version: create.Version,
|
Version: create.Version,
|
||||||
ContainerName: containerName.(string),
|
ContainerName: containerName.(string),
|
||||||
|
Port: int(portValue.(float64)),
|
||||||
}
|
}
|
||||||
|
|
||||||
switch create.Type {
|
switch create.Type {
|
||||||
case constant.RuntimePHP:
|
case constant.RuntimePHP:
|
||||||
runtime.Port = int(create.Params["PANEL_APP_PORT_HTTP"].(float64))
|
|
||||||
if err = handlePHP(create, runtime, fileOp, appVersionDir); err != nil {
|
if err = handlePHP(create, runtime, fileOp, appVersionDir); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo, constant.RuntimePython, constant.RuntimeDotNet:
|
case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo, constant.RuntimePython, constant.RuntimeDotNet:
|
||||||
runtime.Port = int(create.Params["port"].(float64))
|
if err = handleRuntime(create, runtime, fileOp, appVersionDir); err != nil {
|
||||||
if err = handleNodeAndJava(create, runtime, fileOp, appVersionDir); err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -356,7 +352,7 @@ func (r *RuntimeService) Get(id uint) (*response.RuntimeDTO, error) {
|
||||||
}
|
}
|
||||||
for k, v := range envs {
|
for k, v := range envs {
|
||||||
switch k {
|
switch k {
|
||||||
case "NODE_APP_PORT", "PANEL_APP_PORT_HTTP", "JAVA_APP_PORT", "GO_APP_PORT", "APP_PORT", "port":
|
case "APP_PORT", "PANEL_APP_PORT_HTTP":
|
||||||
port, err := strconv.Atoi(v)
|
port, err := strconv.Atoi(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -440,7 +436,7 @@ func (r *RuntimeService) Update(req request.RuntimeUpdate) error {
|
||||||
}
|
}
|
||||||
oldImage := runtime.Image
|
oldImage := runtime.Image
|
||||||
oldEnv := runtime.Env
|
oldEnv := runtime.Env
|
||||||
req.Port = int(req.Params["port"].(float64))
|
port := int(req.Params["PANEL_APP_PORT_HTTP"].(float64))
|
||||||
switch runtime.Type {
|
switch runtime.Type {
|
||||||
case constant.RuntimePHP:
|
case constant.RuntimePHP:
|
||||||
exist, _ := runtimeRepo.GetFirst(runtimeRepo.WithImage(req.Name), runtimeRepo.WithNotId(req.ID))
|
exist, _ := runtimeRepo.GetFirst(runtimeRepo.WithImage(req.Name), runtimeRepo.WithNotId(req.ID))
|
||||||
|
@ -448,11 +444,11 @@ func (r *RuntimeService) Update(req request.RuntimeUpdate) error {
|
||||||
return buserr.New(constant.ErrImageExist)
|
return buserr.New(constant.ErrImageExist)
|
||||||
}
|
}
|
||||||
case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo, constant.RuntimePython, constant.RuntimeDotNet:
|
case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo, constant.RuntimePython, constant.RuntimeDotNet:
|
||||||
if runtime.Port != req.Port {
|
if runtime.Port != port {
|
||||||
if err = checkPortExist(req.Port); err != nil {
|
if err = checkPortExist(port); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
runtime.Port = req.Port
|
runtime.Port = port
|
||||||
}
|
}
|
||||||
for _, export := range req.ExposedPorts {
|
for _, export := range req.ExposedPorts {
|
||||||
if err = checkPortExist(export.HostPort); err != nil {
|
if err = checkPortExist(export.HostPort); err != nil {
|
||||||
|
@ -494,7 +490,6 @@ func (r *RuntimeService) Update(req request.RuntimeUpdate) error {
|
||||||
CodeDir: req.CodeDir,
|
CodeDir: req.CodeDir,
|
||||||
Version: req.Version,
|
Version: req.Version,
|
||||||
NodeConfig: request.NodeConfig{
|
NodeConfig: request.NodeConfig{
|
||||||
Port: req.Port,
|
|
||||||
Install: true,
|
Install: true,
|
||||||
ExposedPorts: req.ExposedPorts,
|
ExposedPorts: req.ExposedPorts,
|
||||||
Environments: req.Environments,
|
Environments: req.Environments,
|
||||||
|
@ -526,7 +521,7 @@ func (r *RuntimeService) Update(req request.RuntimeUpdate) error {
|
||||||
case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo, constant.RuntimePython, constant.RuntimeDotNet:
|
case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo, constant.RuntimePython, constant.RuntimeDotNet:
|
||||||
runtime.Version = req.Version
|
runtime.Version = req.Version
|
||||||
runtime.CodeDir = req.CodeDir
|
runtime.CodeDir = req.CodeDir
|
||||||
runtime.Port = req.Port
|
runtime.Port = port
|
||||||
runtime.Status = constant.RuntimeReCreating
|
runtime.Status = constant.RuntimeReCreating
|
||||||
_ = runtimeRepo.Save(runtime)
|
_ = runtimeRepo.Save(runtime)
|
||||||
go reCreateRuntime(runtime)
|
go reCreateRuntime(runtime)
|
||||||
|
|
|
@ -30,7 +30,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func handleNodeAndJava(create request.RuntimeCreate, runtime *model.Runtime, fileOp files.FileOp, appVersionDir string) (err error) {
|
func handleRuntime(create request.RuntimeCreate, runtime *model.Runtime, fileOp files.FileOp, appVersionDir string) (err error) {
|
||||||
runtimeDir := path.Join(constant.RuntimeDir, create.Type)
|
runtimeDir := path.Join(constant.RuntimeDir, create.Type)
|
||||||
if err = fileOp.CopyDir(appVersionDir, runtimeDir); err != nil {
|
if err = fileOp.CopyDir(appVersionDir, runtimeDir); err != nil {
|
||||||
return
|
return
|
||||||
|
@ -356,14 +356,12 @@ func handleParams(create request.RuntimeCreate, projectDir string) (composeConte
|
||||||
case constant.RuntimeNode:
|
case constant.RuntimeNode:
|
||||||
create.Params["CODE_DIR"] = create.CodeDir
|
create.Params["CODE_DIR"] = create.CodeDir
|
||||||
create.Params["NODE_VERSION"] = create.Version
|
create.Params["NODE_VERSION"] = create.Version
|
||||||
create.Params["PANEL_APP_PORT_HTTP"] = create.Port
|
|
||||||
if create.NodeConfig.Install {
|
if create.NodeConfig.Install {
|
||||||
create.Params["RUN_INSTALL"] = "1"
|
create.Params["RUN_INSTALL"] = "1"
|
||||||
} else {
|
} else {
|
||||||
create.Params["RUN_INSTALL"] = "0"
|
create.Params["RUN_INSTALL"] = "0"
|
||||||
}
|
}
|
||||||
create.Params["CONTAINER_PACKAGE_URL"] = create.Source
|
create.Params["CONTAINER_PACKAGE_URL"] = create.Source
|
||||||
create.Params["NODE_APP_PORT"] = create.Params["APP_PORT"]
|
|
||||||
composeContent, err = handleCompose(env, composeContent, create, projectDir)
|
composeContent, err = handleCompose(env, composeContent, create, projectDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
@ -371,8 +369,6 @@ func handleParams(create request.RuntimeCreate, projectDir string) (composeConte
|
||||||
case constant.RuntimeJava:
|
case constant.RuntimeJava:
|
||||||
create.Params["CODE_DIR"] = create.CodeDir
|
create.Params["CODE_DIR"] = create.CodeDir
|
||||||
create.Params["JAVA_VERSION"] = create.Version
|
create.Params["JAVA_VERSION"] = create.Version
|
||||||
create.Params["PANEL_APP_PORT_HTTP"] = create.Port
|
|
||||||
create.Params["JAVA_APP_PORT"] = create.Params["APP_PORT"]
|
|
||||||
composeContent, err = handleCompose(env, composeContent, create, projectDir)
|
composeContent, err = handleCompose(env, composeContent, create, projectDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
@ -380,8 +376,6 @@ func handleParams(create request.RuntimeCreate, projectDir string) (composeConte
|
||||||
case constant.RuntimeGo:
|
case constant.RuntimeGo:
|
||||||
create.Params["CODE_DIR"] = create.CodeDir
|
create.Params["CODE_DIR"] = create.CodeDir
|
||||||
create.Params["GO_VERSION"] = create.Version
|
create.Params["GO_VERSION"] = create.Version
|
||||||
create.Params["PANEL_APP_PORT_HTTP"] = create.Port
|
|
||||||
create.Params["GO_APP_PORT"] = create.Params["APP_PORT"]
|
|
||||||
composeContent, err = handleCompose(env, composeContent, create, projectDir)
|
composeContent, err = handleCompose(env, composeContent, create, projectDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
@ -389,7 +383,6 @@ func handleParams(create request.RuntimeCreate, projectDir string) (composeConte
|
||||||
case constant.RuntimePython:
|
case constant.RuntimePython:
|
||||||
create.Params["CODE_DIR"] = create.CodeDir
|
create.Params["CODE_DIR"] = create.CodeDir
|
||||||
create.Params["PYTHON_VERSION"] = create.Version
|
create.Params["PYTHON_VERSION"] = create.Version
|
||||||
create.Params["PANEL_APP_PORT_HTTP"] = create.Port
|
|
||||||
composeContent, err = handleCompose(env, composeContent, create, projectDir)
|
composeContent, err = handleCompose(env, composeContent, create, projectDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
@ -397,7 +390,6 @@ func handleParams(create request.RuntimeCreate, projectDir string) (composeConte
|
||||||
case constant.RuntimeDotNet:
|
case constant.RuntimeDotNet:
|
||||||
create.Params["CODE_DIR"] = create.CodeDir
|
create.Params["CODE_DIR"] = create.CodeDir
|
||||||
create.Params["DOTNET_VERSION"] = create.Version
|
create.Params["DOTNET_VERSION"] = create.Version
|
||||||
create.Params["PANEL_APP_PORT_HTTP"] = create.Port
|
|
||||||
composeContent, err = handleCompose(env, composeContent, create, projectDir)
|
composeContent, err = handleCompose(env, composeContent, create, projectDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
@ -440,17 +432,7 @@ func handleCompose(env gotenv.Env, composeContent []byte, create request.Runtime
|
||||||
_, ok := serviceValue["ports"].([]interface{})
|
_, ok := serviceValue["ports"].([]interface{})
|
||||||
if ok {
|
if ok {
|
||||||
var ports []interface{}
|
var ports []interface{}
|
||||||
switch create.Type {
|
ports = append(ports, "${HOST_IP}:${PANEL_APP_PORT_HTTP}:${APP_PORT}")
|
||||||
case constant.RuntimeNode:
|
|
||||||
ports = append(ports, "${HOST_IP}:${PANEL_APP_PORT_HTTP}:${NODE_APP_PORT}")
|
|
||||||
case constant.RuntimeJava:
|
|
||||||
ports = append(ports, "${HOST_IP}:${PANEL_APP_PORT_HTTP}:${JAVA_APP_PORT}")
|
|
||||||
case constant.RuntimeGo:
|
|
||||||
ports = append(ports, "${HOST_IP}:${PANEL_APP_PORT_HTTP}:${GO_APP_PORT}")
|
|
||||||
case constant.RuntimePython, constant.RuntimeDotNet:
|
|
||||||
ports = append(ports, "${HOST_IP}:${PANEL_APP_PORT_HTTP}:${APP_PORT}")
|
|
||||||
|
|
||||||
}
|
|
||||||
for i, port := range create.ExposedPorts {
|
for i, port := range create.ExposedPorts {
|
||||||
containerPortStr := fmt.Sprintf("CONTAINER_PORT_%d", i)
|
containerPortStr := fmt.Sprintf("CONTAINER_PORT_%d", i)
|
||||||
hostPortStr := fmt.Sprintf("HOST_PORT_%d", i)
|
hostPortStr := fmt.Sprintf("HOST_PORT_%d", i)
|
||||||
|
|
|
@ -2374,7 +2374,7 @@ const message = {
|
||||||
appPort: '应用端口',
|
appPort: '应用端口',
|
||||||
externalPort: '外部映射端口',
|
externalPort: '外部映射端口',
|
||||||
packageManager: '包管理器',
|
packageManager: '包管理器',
|
||||||
codeDir: '源码目录',
|
codeDir: '项目目录',
|
||||||
appPortHelper: '应用端口是指容器内部的端口',
|
appPortHelper: '应用端口是指容器内部的端口',
|
||||||
externalPortHelper: '外部映射端口是指容器对外暴露的端口',
|
externalPortHelper: '外部映射端口是指容器对外暴露的端口',
|
||||||
runScript: '启动命令',
|
runScript: '启动命令',
|
||||||
|
|
119
frontend/src/views/website/runtime/app/index.vue
Normal file
119
frontend/src/views/website/runtime/app/index.vue
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
<template>
|
||||||
|
<el-form-item :label="$t('runtime.app')" prop="appID">
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-select
|
||||||
|
v-model="runtime.appID"
|
||||||
|
:disabled="mode === 'edit'"
|
||||||
|
@change="changeApp(runtime.appID)"
|
||||||
|
class="p-w-200"
|
||||||
|
>
|
||||||
|
<el-option v-for="(app, index) in apps" :key="index" :label="app.name" :value="app.id"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-select
|
||||||
|
v-model="runtime.version"
|
||||||
|
:disabled="mode === 'edit'"
|
||||||
|
@change="changeVersion()"
|
||||||
|
class="p-w-200"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="(version, index) in appVersions"
|
||||||
|
:key="index"
|
||||||
|
:label="version"
|
||||||
|
:value="version"
|
||||||
|
></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { App } from '@/api/interface/app';
|
||||||
|
import { GetApp, GetAppDetail, SearchApp } from '@/api/modules/app';
|
||||||
|
import { useVModel } from '@vueuse/core';
|
||||||
|
import { defineProps } from 'vue';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
mode: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
appKey: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
modelValue: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const apps = ref<App.App[]>([]);
|
||||||
|
const appVersions = ref<string[]>([]);
|
||||||
|
const emit = defineEmits(['update:modelValue']);
|
||||||
|
const runtime = useVModel(props, 'modelValue', emit);
|
||||||
|
const appReq = reactive({
|
||||||
|
type: props.appKey,
|
||||||
|
page: 1,
|
||||||
|
pageSize: 20,
|
||||||
|
resource: 'remote',
|
||||||
|
});
|
||||||
|
|
||||||
|
const changeApp = (appID: number) => {
|
||||||
|
for (const app of apps.value) {
|
||||||
|
if (app.id === appID) {
|
||||||
|
getApp(app.key, props.mode);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const changeVersion = async () => {
|
||||||
|
try {
|
||||||
|
const res = await GetAppDetail(runtime.value.appID, runtime.value.version, 'runtime');
|
||||||
|
runtime.value.appDetailID = res.data.id;
|
||||||
|
} catch (error) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getApp = async (appkey: string, mode: string) => {
|
||||||
|
try {
|
||||||
|
const res = await GetApp(appkey);
|
||||||
|
appVersions.value = res.data.versions || [];
|
||||||
|
if (res.data.versions.length > 0) {
|
||||||
|
if (mode === 'create') {
|
||||||
|
runtime.value.version = res.data.versions[0];
|
||||||
|
changeVersion();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
const searchApp = async (appID: number) => {
|
||||||
|
try {
|
||||||
|
const res = await SearchApp(appReq);
|
||||||
|
apps.value = res.data.items || [];
|
||||||
|
if (res.data && res.data.items && res.data.items.length > 0) {
|
||||||
|
if (appID == null) {
|
||||||
|
runtime.value.appID = res.data.items[0].id;
|
||||||
|
getApp(res.data.items[0].key, props.mode);
|
||||||
|
} else {
|
||||||
|
res.data.items.forEach((item) => {
|
||||||
|
if (item.id === appID) {
|
||||||
|
getApp(item.key, props.mode);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (props.mode === 'create') {
|
||||||
|
searchApp(null);
|
||||||
|
} else {
|
||||||
|
searchApp(runtime.value.appID);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
136
frontend/src/views/website/runtime/dir/index.vue
Normal file
136
frontend/src/views/website/runtime/dir/index.vue
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
<template>
|
||||||
|
<el-form-item :label="$t('runtime.codeDir')" prop="codeDir">
|
||||||
|
<el-input v-model.trim="runtime.codeDir" :disabled="mode === 'edit'" @blur="changeDir">
|
||||||
|
<template #prepend>
|
||||||
|
<FileList :disabled="mode === 'edit'" :path="runtime.codeDir" @choose="getPath" :dir="true"></FileList>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
<span class="input-help">
|
||||||
|
{{ dirHelper }}
|
||||||
|
</span>
|
||||||
|
</el-form-item>
|
||||||
|
<div v-if="appKey == 'node'">
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="18">
|
||||||
|
<el-form-item :label="$t('runtime.runScript')" prop="params.EXEC_SCRIPT">
|
||||||
|
<el-select v-model="runtime.params['EXEC_SCRIPT']" v-if="runtime.params['CUSTOM_SCRIPT'] == '0'">
|
||||||
|
<el-option
|
||||||
|
v-for="(script, index) in scripts"
|
||||||
|
:key="index"
|
||||||
|
:label="script.name + ' 【 ' + script.script + ' 】'"
|
||||||
|
:value="script.name"
|
||||||
|
>
|
||||||
|
<el-row :gutter="10">
|
||||||
|
<el-col :span="4">{{ script.name }}</el-col>
|
||||||
|
<el-col :span="10">{{ ' 【 ' + script.script + ' 】' }}</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
<el-input v-else v-model="runtime.params['EXEC_SCRIPT']"></el-input>
|
||||||
|
<span class="input-help" v-if="runtime.params['CUSTOM_SCRIPT'] == '0'">
|
||||||
|
{{ $t('runtime.runScriptHelper') }}
|
||||||
|
</span>
|
||||||
|
<span class="input-help" v-else>
|
||||||
|
{{ scriptHelper }}
|
||||||
|
</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item :label="$t('runtime.customScript')" prop="params.CUSTOM_SCRIPT">
|
||||||
|
<el-switch
|
||||||
|
v-model="runtime.params['CUSTOM_SCRIPT']"
|
||||||
|
:active-value="'1'"
|
||||||
|
:inactive-value="'0'"
|
||||||
|
@change="changeScriptType"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<el-form-item :label="$t('runtime.runScript')" prop="params.EXEC_SCRIPT">
|
||||||
|
<el-input v-model="runtime.params['EXEC_SCRIPT']"></el-input>
|
||||||
|
<span class="input-help">
|
||||||
|
{{ scriptHelper }}
|
||||||
|
</span>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { Runtime } from '@/api/interface/runtime';
|
||||||
|
import { GetNodeScripts } from '@/api/modules/runtime';
|
||||||
|
import { useVModel } from '@vueuse/core';
|
||||||
|
import { defineProps } from 'vue';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
mode: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
modelValue: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
dirHelper: {
|
||||||
|
type: String,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
scriptHelper: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
appKey: {
|
||||||
|
type: String,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const emit = defineEmits(['update:modelValue']);
|
||||||
|
const runtime = useVModel(props, 'modelValue', emit);
|
||||||
|
const scripts = ref<Runtime.NodeScripts[]>([]);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => runtime.value.name,
|
||||||
|
(newVal) => {
|
||||||
|
if (newVal && props.mode == 'create') {
|
||||||
|
runtime.value.params['CONTAINER_NAME'] = newVal;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ deep: true },
|
||||||
|
);
|
||||||
|
|
||||||
|
const changeDir = () => {
|
||||||
|
if (props.appKey == 'node') {
|
||||||
|
getScripts();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getPath = (codeDir: string) => {
|
||||||
|
runtime.value.codeDir = codeDir;
|
||||||
|
if (props.appKey == 'node') {
|
||||||
|
getScripts();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const changeScriptType = () => {
|
||||||
|
runtime.value.params['EXEC_SCRIPT'] = '';
|
||||||
|
if (runtime.value.params['CUSTOM_SCRIPT'] == '0') {
|
||||||
|
getScripts();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getScripts = () => {
|
||||||
|
GetNodeScripts({ codeDir: runtime.value.codeDir }).then((res) => {
|
||||||
|
scripts.value = res.data;
|
||||||
|
if (props.mode == 'create' && scripts.value.length > 0) {
|
||||||
|
runtime.value.params['EXEC_SCRIPT'] = scripts.value[0].name;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (props.mode == 'edit' && props.appKey == 'node') {
|
||||||
|
getScripts();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -15,10 +15,6 @@
|
||||||
<el-button type="primary" @click="openCreate">
|
<el-button type="primary" @click="openCreate">
|
||||||
{{ $t('runtime.create') }}
|
{{ $t('runtime.create') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
||||||
<el-button type="primary" plain @click="onOpenBuildCache()">
|
|
||||||
{{ $t('container.cleanBuildCache') }}
|
|
||||||
</el-button>
|
|
||||||
</template>
|
</template>
|
||||||
<template #main>
|
<template #main>
|
||||||
<ComplexTable :pagination-config="paginationConfig" :data="items" @search="search()">
|
<ComplexTable :pagination-config="paginationConfig" :data="items" @search="search()">
|
||||||
|
@ -117,8 +113,6 @@ import { Promotion } from '@element-plus/icons-vue';
|
||||||
import PortJumpDialog from '@/components/port-jump/index.vue';
|
import PortJumpDialog from '@/components/port-jump/index.vue';
|
||||||
import AppResources from '@/views/website/runtime/php/check/index.vue';
|
import AppResources from '@/views/website/runtime/php/check/index.vue';
|
||||||
import { ElMessageBox } from 'element-plus';
|
import { ElMessageBox } from 'element-plus';
|
||||||
import { containerPrune } from '@/api/modules/container';
|
|
||||||
import { MsgSuccess } from '@/utils/message';
|
|
||||||
import { GlobalStore } from '@/store';
|
import { GlobalStore } from '@/store';
|
||||||
|
|
||||||
let timer: NodeJS.Timer | null = null;
|
let timer: NodeJS.Timer | null = null;
|
||||||
|
@ -229,29 +223,6 @@ const openDelete = (row: Runtime.Runtime) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const onOpenBuildCache = () => {
|
|
||||||
ElMessageBox.confirm(i18n.global.t('container.delBuildCacheHelper'), i18n.global.t('container.cleanBuildCache'), {
|
|
||||||
confirmButtonText: i18n.global.t('commons.button.confirm'),
|
|
||||||
cancelButtonText: i18n.global.t('commons.button.cancel'),
|
|
||||||
type: 'info',
|
|
||||||
}).then(async () => {
|
|
||||||
loading.value = true;
|
|
||||||
let params = {
|
|
||||||
pruneType: 'buildcache',
|
|
||||||
withTagAll: false,
|
|
||||||
};
|
|
||||||
await containerPrune(params)
|
|
||||||
.then((res) => {
|
|
||||||
loading.value = false;
|
|
||||||
MsgSuccess(i18n.global.t('container.cleanSuccess', [res.data.deletedNumber]));
|
|
||||||
search();
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
loading.value = false;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const openLog = (row: any) => {
|
const openLog = (row: any) => {
|
||||||
composeLogRef.value.acceptParams({ compose: row.path + '/docker-compose.yml', resource: row.name });
|
composeLogRef.value.acceptParams({ compose: row.path + '/docker-compose.yml', resource: row.name });
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,110 +18,14 @@
|
||||||
<el-form-item :label="$t('commons.table.name')" prop="name">
|
<el-form-item :label="$t('commons.table.name')" prop="name">
|
||||||
<el-input :disabled="mode === 'edit'" v-model="runtime.name"></el-input>
|
<el-input :disabled="mode === 'edit'" v-model="runtime.name"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('runtime.app')" prop="appID">
|
<AppConfig v-model="runtime" :mode="mode" appKey="dotnet" />
|
||||||
<el-row :gutter="20">
|
<DirConfig v-model="runtime" :mode="mode" :scriptHelper="$t('runtime.donetHelper')" />
|
||||||
<el-col :span="12">
|
|
||||||
<el-select
|
|
||||||
v-model="runtime.appID"
|
|
||||||
:disabled="mode === 'edit'"
|
|
||||||
@change="changeApp(runtime.appID)"
|
|
||||||
class="p-w-200"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="(app, index) in apps"
|
|
||||||
:key="index"
|
|
||||||
:label="app.name"
|
|
||||||
:value="app.id"
|
|
||||||
></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-select
|
|
||||||
v-model="runtime.version"
|
|
||||||
:disabled="mode === 'edit'"
|
|
||||||
@change="changeVersion()"
|
|
||||||
class="p-w-200"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="(version, index) in appVersions"
|
|
||||||
:key="index"
|
|
||||||
:label="version"
|
|
||||||
:value="version"
|
|
||||||
></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item :label="$t('tool.supervisor.dir')" prop="codeDir">
|
|
||||||
<el-input v-model.trim="runtime.codeDir" :disabled="mode === 'edit'">
|
|
||||||
<template #prepend>
|
|
||||||
<FileList
|
|
||||||
:disabled="mode === 'edit'"
|
|
||||||
:path="runtime.codeDir"
|
|
||||||
@choose="getPath"
|
|
||||||
:dir="true"
|
|
||||||
></FileList>
|
|
||||||
</template>
|
|
||||||
</el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item :label="$t('runtime.runScript')" prop="params.EXEC_SCRIPT">
|
|
||||||
<el-input v-model="runtime.params['EXEC_SCRIPT']"></el-input>
|
|
||||||
<span class="input-help">
|
|
||||||
{{ $t('runtime.donetHelper') }}
|
|
||||||
</span>
|
|
||||||
</el-form-item>
|
|
||||||
<el-row :gutter="20">
|
|
||||||
<el-col :span="7">
|
|
||||||
<el-form-item :label="$t('runtime.appPort')" prop="params.APP_PORT">
|
|
||||||
<el-input v-model.number="runtime.params['APP_PORT']" />
|
|
||||||
<span class="input-help">{{ $t('runtime.appPortHelper') }}</span>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="7">
|
|
||||||
<el-form-item :label="$t('runtime.externalPort')" prop="port">
|
|
||||||
<el-input v-model.number="runtime.port" />
|
|
||||||
<span class="input-help">{{ $t('runtime.externalPortHelper') }}</span>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="4">
|
|
||||||
<el-form-item :label="$t('commons.button.add') + $t('commons.table.port')">
|
|
||||||
<el-button @click="addPort">
|
|
||||||
<el-icon><Plus /></el-icon>
|
|
||||||
</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="6">
|
|
||||||
<el-form-item :label="$t('app.allowPort')" prop="params.HOST_IP">
|
|
||||||
<el-switch
|
|
||||||
v-model="runtime.params['HOST_IP']"
|
|
||||||
:active-value="'0.0.0.0'"
|
|
||||||
:inactive-value="'127.0.0.1'"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-row :gutter="20" v-for="(port, index) of runtime.exposedPorts" :key="index">
|
|
||||||
<el-col :span="7">
|
|
||||||
<el-form-item :prop="'exposedPorts.' + index + '.containerPort'" :rules="rules.params.APP_PORT">
|
|
||||||
<el-input v-model.number="port.containerPort" :placeholder="$t('runtime.appPort')" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="7">
|
|
||||||
<el-form-item :prop="'exposedPorts.' + index + '.hostPort'" :rules="rules.params.APP_PORT">
|
|
||||||
<el-input v-model.number="port.hostPort" :placeholder="$t('runtime.externalPort')" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="4">
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" @click="removePort(index)" link>
|
|
||||||
{{ $t('commons.button.delete') }}
|
|
||||||
</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-form-item :label="$t('app.containerName')" prop="params.CONTAINER_NAME">
|
<el-form-item :label="$t('app.containerName')" prop="params.CONTAINER_NAME">
|
||||||
<el-input v-model.trim="runtime.params['CONTAINER_NAME']"></el-input>
|
<el-input v-model.trim="runtime.params['CONTAINER_NAME']"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<PortConfig v-model="runtime" :mode="mode" />
|
||||||
|
<Environment :environments="runtime.environments" />
|
||||||
|
<Volumes :volumes="runtime.volumes" />
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<span>
|
<span>
|
||||||
|
@ -137,13 +41,17 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { App } from '@/api/interface/app';
|
import { App } from '@/api/interface/app';
|
||||||
import { Runtime } from '@/api/interface/runtime';
|
import { Runtime } from '@/api/interface/runtime';
|
||||||
import { GetApp, GetAppDetail, SearchApp } from '@/api/modules/app';
|
|
||||||
import { CreateRuntime, GetRuntime, UpdateRuntime } from '@/api/modules/runtime';
|
import { CreateRuntime, GetRuntime, UpdateRuntime } from '@/api/modules/runtime';
|
||||||
import { Rules, checkNumberRange } from '@/global/form-rules';
|
import { Rules, checkNumberRange } from '@/global/form-rules';
|
||||||
import i18n from '@/lang';
|
import i18n from '@/lang';
|
||||||
import { MsgError, MsgSuccess } from '@/utils/message';
|
import { MsgError, MsgSuccess } from '@/utils/message';
|
||||||
import { FormInstance } from 'element-plus';
|
import { FormInstance } from 'element-plus';
|
||||||
import { reactive, ref, watch } from 'vue';
|
import { reactive, ref, watch } from 'vue';
|
||||||
|
import AppConfig from '@/views/website/runtime/app/index.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';
|
||||||
|
import DirConfig from '@/views/website/runtime/dir/index.vue';
|
||||||
|
|
||||||
interface OperateRrops {
|
interface OperateRrops {
|
||||||
id?: number;
|
id?: number;
|
||||||
|
@ -152,18 +60,10 @@ interface OperateRrops {
|
||||||
}
|
}
|
||||||
|
|
||||||
const open = ref(false);
|
const open = ref(false);
|
||||||
const apps = ref<App.App[]>([]);
|
|
||||||
const runtimeForm = ref<FormInstance>();
|
const runtimeForm = ref<FormInstance>();
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const mode = ref('create');
|
const mode = ref('create');
|
||||||
const editParams = ref<App.InstallParams[]>();
|
const editParams = ref<App.InstallParams[]>();
|
||||||
const appVersions = ref<string[]>([]);
|
|
||||||
const appReq = reactive({
|
|
||||||
type: 'donet',
|
|
||||||
page: 1,
|
|
||||||
pageSize: 20,
|
|
||||||
resource: 'remote',
|
|
||||||
});
|
|
||||||
const initData = (type: string) => ({
|
const initData = (type: string) => ({
|
||||||
name: '',
|
name: '',
|
||||||
appDetailID: undefined,
|
appDetailID: undefined,
|
||||||
|
@ -177,6 +77,8 @@ const initData = (type: string) => ({
|
||||||
codeDir: '/',
|
codeDir: '/',
|
||||||
port: 8080,
|
port: 8080,
|
||||||
exposedPorts: [],
|
exposedPorts: [],
|
||||||
|
environments: [],
|
||||||
|
volumes: [],
|
||||||
});
|
});
|
||||||
let runtime = reactive<Runtime.RuntimeCreate>(initData('donet'));
|
let runtime = reactive<Runtime.RuntimeCreate>(initData('donet'));
|
||||||
const rules = ref<any>({
|
const rules = ref<any>({
|
||||||
|
@ -195,16 +97,6 @@ const rules = ref<any>({
|
||||||
const scripts = ref<Runtime.NodeScripts[]>([]);
|
const scripts = ref<Runtime.NodeScripts[]>([]);
|
||||||
const em = defineEmits(['close']);
|
const em = defineEmits(['close']);
|
||||||
|
|
||||||
watch(
|
|
||||||
() => runtime.params['APP_PORT'],
|
|
||||||
(newVal) => {
|
|
||||||
if (newVal && mode.value == 'create') {
|
|
||||||
runtime.port = newVal;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ deep: true },
|
|
||||||
);
|
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => runtime.name,
|
() => runtime.name,
|
||||||
(newVal) => {
|
(newVal) => {
|
||||||
|
@ -221,71 +113,6 @@ const handleClose = () => {
|
||||||
runtimeForm.value?.resetFields();
|
runtimeForm.value?.resetFields();
|
||||||
};
|
};
|
||||||
|
|
||||||
const getPath = (codeDir: string) => {
|
|
||||||
runtime.codeDir = codeDir;
|
|
||||||
};
|
|
||||||
|
|
||||||
const addPort = () => {
|
|
||||||
runtime.exposedPorts.push({
|
|
||||||
hostPort: undefined,
|
|
||||||
containerPort: undefined,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const removePort = (index: number) => {
|
|
||||||
runtime.exposedPorts.splice(index, 1);
|
|
||||||
};
|
|
||||||
|
|
||||||
const searchApp = (appID: number) => {
|
|
||||||
SearchApp(appReq).then((res) => {
|
|
||||||
apps.value = res.data.items || [];
|
|
||||||
if (res.data && res.data.items && res.data.items.length > 0) {
|
|
||||||
if (appID == null) {
|
|
||||||
runtime.appID = res.data.items[0].id;
|
|
||||||
getApp(res.data.items[0].key, mode.value);
|
|
||||||
} else {
|
|
||||||
res.data.items.forEach((item) => {
|
|
||||||
if (item.id === appID) {
|
|
||||||
getApp(item.key, mode.value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const changeApp = (appID: number) => {
|
|
||||||
for (const app of apps.value) {
|
|
||||||
if (app.id === appID) {
|
|
||||||
getApp(app.key, mode.value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const changeVersion = () => {
|
|
||||||
loading.value = true;
|
|
||||||
GetAppDetail(runtime.appID, runtime.version, 'runtime')
|
|
||||||
.then((res) => {
|
|
||||||
runtime.appDetailID = res.data.id;
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
loading.value = false;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const getApp = (appkey: string, mode: string) => {
|
|
||||||
GetApp(appkey).then((res) => {
|
|
||||||
appVersions.value = res.data.versions || [];
|
|
||||||
if (res.data.versions.length > 0) {
|
|
||||||
if (mode === 'create') {
|
|
||||||
runtime.version = res.data.versions[0];
|
|
||||||
changeVersion();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const submit = async (formEl: FormInstance | undefined) => {
|
const submit = async (formEl: FormInstance | undefined) => {
|
||||||
if (!formEl) return;
|
if (!formEl) return;
|
||||||
await formEl.validate((valid) => {
|
await formEl.validate((valid) => {
|
||||||
|
@ -342,7 +169,7 @@ const getRuntime = async (id: number) => {
|
||||||
Object.assign(runtime, {
|
Object.assign(runtime, {
|
||||||
id: data.id,
|
id: data.id,
|
||||||
name: data.name,
|
name: data.name,
|
||||||
appDetailId: data.appDetailID,
|
appDetailID: data.appDetailID,
|
||||||
image: data.image,
|
image: data.image,
|
||||||
type: data.type,
|
type: data.type,
|
||||||
resource: data.resource,
|
resource: data.resource,
|
||||||
|
@ -356,7 +183,6 @@ const getRuntime = async (id: number) => {
|
||||||
});
|
});
|
||||||
runtime.exposedPorts = data.exposedPorts || [];
|
runtime.exposedPorts = data.exposedPorts || [];
|
||||||
editParams.value = data.appParams;
|
editParams.value = data.appParams;
|
||||||
searchApp(data.appID);
|
|
||||||
open.value = true;
|
open.value = true;
|
||||||
} catch (error) {}
|
} catch (error) {}
|
||||||
};
|
};
|
||||||
|
@ -366,7 +192,6 @@ const acceptParams = async (props: OperateRrops) => {
|
||||||
scripts.value = [];
|
scripts.value = [];
|
||||||
if (props.mode === 'create') {
|
if (props.mode === 'create') {
|
||||||
Object.assign(runtime, initData(props.type));
|
Object.assign(runtime, initData(props.type));
|
||||||
searchApp(null);
|
|
||||||
open.value = true;
|
open.value = true;
|
||||||
} else {
|
} else {
|
||||||
getRuntime(props.id);
|
getRuntime(props.id);
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
</el-text>
|
</el-text>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column :label="$t('website.runDir')" prop="codeDir">
|
<el-table-column :label="$t('runtime.codeDir')" prop="codeDir">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-button type="primary" link @click="toFolder(row.codeDir)">
|
<el-button type="primary" link @click="toFolder(row.codeDir)">
|
||||||
<el-icon>
|
<el-icon>
|
||||||
|
|
|
@ -18,40 +18,7 @@
|
||||||
<el-form-item :label="$t('commons.table.name')" prop="name">
|
<el-form-item :label="$t('commons.table.name')" prop="name">
|
||||||
<el-input :disabled="mode === 'edit'" v-model="runtime.name"></el-input>
|
<el-input :disabled="mode === 'edit'" v-model="runtime.name"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('runtime.app')" prop="appID">
|
<AppConfig v-model="runtime" :mode="mode" appKey="go" />
|
||||||
<el-row :gutter="20">
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-select
|
|
||||||
v-model="runtime.appID"
|
|
||||||
:disabled="mode === 'edit'"
|
|
||||||
@change="changeApp(runtime.appID)"
|
|
||||||
class="p-w-200"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="(app, index) in apps"
|
|
||||||
:key="index"
|
|
||||||
:label="app.name"
|
|
||||||
:value="app.id"
|
|
||||||
></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-select
|
|
||||||
v-model="runtime.version"
|
|
||||||
:disabled="mode === 'edit'"
|
|
||||||
@change="changeVersion()"
|
|
||||||
class="p-w-200"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="(version, index) in appVersions"
|
|
||||||
:key="index"
|
|
||||||
:label="version"
|
|
||||||
:value="version"
|
|
||||||
></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item :label="$t('tool.supervisor.dir')" prop="codeDir">
|
<el-form-item :label="$t('tool.supervisor.dir')" prop="codeDir">
|
||||||
<el-input v-model.trim="runtime.codeDir" :disabled="mode === 'edit'">
|
<el-input v-model.trim="runtime.codeDir" :disabled="mode === 'edit'">
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
|
@ -73,12 +40,12 @@
|
||||||
{{ $t('runtime.goHelper') }}
|
{{ $t('runtime.goHelper') }}
|
||||||
</span>
|
</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<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-form-item :label="$t('app.containerName')" prop="params.CONTAINER_NAME">
|
||||||
<el-input v-model.trim="runtime.params['CONTAINER_NAME']"></el-input>
|
<el-input v-model.trim="runtime.params['CONTAINER_NAME']"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<PortConfig v-model="runtime" :mode="mode" />
|
||||||
|
<Environment :environments="runtime.environments" />
|
||||||
|
<Volumes :volumes="runtime.volumes" />
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
|
@ -93,7 +60,6 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { App } from '@/api/interface/app';
|
import { App } from '@/api/interface/app';
|
||||||
import { Runtime } from '@/api/interface/runtime';
|
import { Runtime } from '@/api/interface/runtime';
|
||||||
import { GetApp, GetAppDetail, SearchApp } from '@/api/modules/app';
|
|
||||||
import { CreateRuntime, GetRuntime, UpdateRuntime } from '@/api/modules/runtime';
|
import { CreateRuntime, GetRuntime, UpdateRuntime } from '@/api/modules/runtime';
|
||||||
import { Rules, checkNumberRange } from '@/global/form-rules';
|
import { Rules, checkNumberRange } from '@/global/form-rules';
|
||||||
import i18n from '@/lang';
|
import i18n from '@/lang';
|
||||||
|
@ -103,6 +69,7 @@ import { reactive, ref, watch } from 'vue';
|
||||||
import PortConfig from '@/views/website/runtime/port/index.vue';
|
import PortConfig from '@/views/website/runtime/port/index.vue';
|
||||||
import Environment from '@/views/website/runtime/environment/index.vue';
|
import Environment from '@/views/website/runtime/environment/index.vue';
|
||||||
import Volumes from '@/views/website/runtime/volume/index.vue';
|
import Volumes from '@/views/website/runtime/volume/index.vue';
|
||||||
|
import AppConfig from '@/views/website/runtime/app/index.vue';
|
||||||
|
|
||||||
interface OperateRrops {
|
interface OperateRrops {
|
||||||
id?: number;
|
id?: number;
|
||||||
|
@ -111,18 +78,10 @@ interface OperateRrops {
|
||||||
}
|
}
|
||||||
|
|
||||||
const open = ref(false);
|
const open = ref(false);
|
||||||
const apps = ref<App.App[]>([]);
|
|
||||||
const runtimeForm = ref<FormInstance>();
|
const runtimeForm = ref<FormInstance>();
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const mode = ref('create');
|
const mode = ref('create');
|
||||||
const editParams = ref<App.InstallParams[]>();
|
const editParams = ref<App.InstallParams[]>();
|
||||||
const appVersions = ref<string[]>([]);
|
|
||||||
const appReq = reactive({
|
|
||||||
type: 'go',
|
|
||||||
page: 1,
|
|
||||||
pageSize: 20,
|
|
||||||
resource: 'remote',
|
|
||||||
});
|
|
||||||
const initData = (type: string) => ({
|
const initData = (type: string) => ({
|
||||||
name: '',
|
name: '',
|
||||||
appDetailID: undefined,
|
appDetailID: undefined,
|
||||||
|
@ -156,16 +115,6 @@ const rules = ref<any>({
|
||||||
const scripts = ref<Runtime.NodeScripts[]>([]);
|
const scripts = ref<Runtime.NodeScripts[]>([]);
|
||||||
const em = defineEmits(['close']);
|
const em = defineEmits(['close']);
|
||||||
|
|
||||||
watch(
|
|
||||||
() => runtime.params['APP_PORT'],
|
|
||||||
(newVal) => {
|
|
||||||
if (newVal && mode.value == 'create') {
|
|
||||||
runtime.port = newVal;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ deep: true },
|
|
||||||
);
|
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => runtime.name,
|
() => runtime.name,
|
||||||
(newVal) => {
|
(newVal) => {
|
||||||
|
@ -186,56 +135,6 @@ const getPath = (codeDir: string) => {
|
||||||
runtime.codeDir = codeDir;
|
runtime.codeDir = codeDir;
|
||||||
};
|
};
|
||||||
|
|
||||||
const searchApp = (appID: number) => {
|
|
||||||
SearchApp(appReq).then((res) => {
|
|
||||||
apps.value = res.data.items || [];
|
|
||||||
if (res.data && res.data.items && res.data.items.length > 0) {
|
|
||||||
if (appID == null) {
|
|
||||||
runtime.appID = res.data.items[0].id;
|
|
||||||
getApp(res.data.items[0].key, mode.value);
|
|
||||||
} else {
|
|
||||||
res.data.items.forEach((item) => {
|
|
||||||
if (item.id === appID) {
|
|
||||||
getApp(item.key, mode.value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const changeApp = (appID: number) => {
|
|
||||||
for (const app of apps.value) {
|
|
||||||
if (app.id === appID) {
|
|
||||||
getApp(app.key, mode.value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const changeVersion = () => {
|
|
||||||
loading.value = true;
|
|
||||||
GetAppDetail(runtime.appID, runtime.version, 'runtime')
|
|
||||||
.then((res) => {
|
|
||||||
runtime.appDetailID = res.data.id;
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
loading.value = false;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const getApp = (appkey: string, mode: string) => {
|
|
||||||
GetApp(appkey).then((res) => {
|
|
||||||
appVersions.value = res.data.versions || [];
|
|
||||||
if (res.data.versions.length > 0) {
|
|
||||||
if (mode === 'create') {
|
|
||||||
runtime.version = res.data.versions[0];
|
|
||||||
changeVersion();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const submit = async (formEl: FormInstance | undefined) => {
|
const submit = async (formEl: FormInstance | undefined) => {
|
||||||
if (!formEl) return;
|
if (!formEl) return;
|
||||||
await formEl.validate((valid) => {
|
await formEl.validate((valid) => {
|
||||||
|
@ -292,7 +191,7 @@ const getRuntime = async (id: number) => {
|
||||||
Object.assign(runtime, {
|
Object.assign(runtime, {
|
||||||
id: data.id,
|
id: data.id,
|
||||||
name: data.name,
|
name: data.name,
|
||||||
appDetailId: data.appDetailID,
|
appDetailID: data.appDetailID,
|
||||||
image: data.image,
|
image: data.image,
|
||||||
type: data.type,
|
type: data.type,
|
||||||
resource: data.resource,
|
resource: data.resource,
|
||||||
|
@ -308,7 +207,6 @@ const getRuntime = async (id: number) => {
|
||||||
runtime.environments = data.environments || [];
|
runtime.environments = data.environments || [];
|
||||||
runtime.volumes = data.volumes || [];
|
runtime.volumes = data.volumes || [];
|
||||||
editParams.value = data.appParams;
|
editParams.value = data.appParams;
|
||||||
searchApp(data.appID);
|
|
||||||
open.value = true;
|
open.value = true;
|
||||||
} catch (error) {}
|
} catch (error) {}
|
||||||
};
|
};
|
||||||
|
@ -318,7 +216,6 @@ const acceptParams = async (props: OperateRrops) => {
|
||||||
scripts.value = [];
|
scripts.value = [];
|
||||||
if (props.mode === 'create') {
|
if (props.mode === 'create') {
|
||||||
Object.assign(runtime, initData(props.type));
|
Object.assign(runtime, initData(props.type));
|
||||||
searchApp(null);
|
|
||||||
open.value = true;
|
open.value = true;
|
||||||
} else {
|
} else {
|
||||||
getRuntime(props.id);
|
getRuntime(props.id);
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
</el-text>
|
</el-text>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column :label="$t('website.runDir')" prop="codeDir">
|
<el-table-column :label="$t('runtime.codeDir')" prop="codeDir">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-button type="primary" link @click="toFolder(row.codeDir)">
|
<el-button type="primary" link @click="toFolder(row.codeDir)">
|
||||||
<el-icon>
|
<el-icon>
|
||||||
|
|
|
@ -17,66 +17,19 @@
|
||||||
<el-form-item :label="$t('commons.table.name')" prop="name">
|
<el-form-item :label="$t('commons.table.name')" prop="name">
|
||||||
<el-input :disabled="mode === 'edit'" v-model="runtime.name"></el-input>
|
<el-input :disabled="mode === 'edit'" v-model="runtime.name"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('runtime.app')" prop="appID">
|
<AppConfig v-model="runtime" :mode="mode" appKey="java" />
|
||||||
<el-row :gutter="20">
|
<DirConfig
|
||||||
<el-col :span="12">
|
v-model="runtime"
|
||||||
<el-select
|
:mode="mode"
|
||||||
v-model="runtime.appID"
|
:dirHelper="$t('runtime.javaDirHelper')"
|
||||||
:disabled="mode === 'edit'"
|
:scriptHelper="$t('runtime.javaScriptHelper')"
|
||||||
@change="changeApp(runtime.appID)"
|
/>
|
||||||
class="p-w-200"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="(app, index) in apps"
|
|
||||||
:key="index"
|
|
||||||
:label="app.name"
|
|
||||||
:value="app.id"
|
|
||||||
></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-select
|
|
||||||
v-model="runtime.version"
|
|
||||||
:disabled="mode === 'edit'"
|
|
||||||
@change="changeVersion()"
|
|
||||||
class="p-w-200"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="(version, index) in appVersions"
|
|
||||||
:key="index"
|
|
||||||
:label="version"
|
|
||||||
:value="version"
|
|
||||||
></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item :label="$t('tool.supervisor.dir')" prop="codeDir">
|
|
||||||
<el-input v-model.trim="runtime.codeDir" :disabled="mode === 'edit'">
|
|
||||||
<template #prepend>
|
|
||||||
<FileList
|
|
||||||
:disabled="mode === 'edit'"
|
|
||||||
:path="runtime.codeDir"
|
|
||||||
@choose="getPath"
|
|
||||||
:dir="true"
|
|
||||||
></FileList>
|
|
||||||
</template>
|
|
||||||
</el-input>
|
|
||||||
<span class="input-help">
|
|
||||||
{{ $t('runtime.javaDirHelper') }}
|
|
||||||
</span>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item :label="$t('runtime.runScript')" prop="params.EXEC_SCRIPT">
|
|
||||||
<el-input v-model="runtime.params['EXEC_SCRIPT']"></el-input>
|
|
||||||
<span class="input-help">
|
|
||||||
{{ $t('runtime.javaScriptHelper') }}
|
|
||||||
</span>
|
|
||||||
</el-form-item>
|
|
||||||
<PortConfig :params="runtime.params" :exposedPorts="runtime.exposedPorts" :rules="rules" />
|
|
||||||
<Environment :environments="runtime.environments" />
|
|
||||||
<el-form-item :label="$t('app.containerName')" prop="params.CONTAINER_NAME">
|
<el-form-item :label="$t('app.containerName')" prop="params.CONTAINER_NAME">
|
||||||
<el-input v-model.trim="runtime.params['CONTAINER_NAME']"></el-input>
|
<el-input v-model.trim="runtime.params['CONTAINER_NAME']"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<PortConfig v-model="runtime" :mode="mode" />
|
||||||
|
<Environment :environments="runtime.environments" />
|
||||||
|
<Volumes :volumes="runtime.volumes" />
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<span>
|
<span>
|
||||||
|
@ -92,7 +45,6 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { App } from '@/api/interface/app';
|
import { App } from '@/api/interface/app';
|
||||||
import { Runtime } from '@/api/interface/runtime';
|
import { Runtime } from '@/api/interface/runtime';
|
||||||
import { GetApp, GetAppDetail, SearchApp } from '@/api/modules/app';
|
|
||||||
import { CreateRuntime, GetRuntime, UpdateRuntime } from '@/api/modules/runtime';
|
import { CreateRuntime, GetRuntime, UpdateRuntime } from '@/api/modules/runtime';
|
||||||
import { Rules, checkNumberRange } from '@/global/form-rules';
|
import { Rules, checkNumberRange } from '@/global/form-rules';
|
||||||
import i18n from '@/lang';
|
import i18n from '@/lang';
|
||||||
|
@ -101,6 +53,9 @@ import { FormInstance } from 'element-plus';
|
||||||
import { reactive, ref, watch } from 'vue';
|
import { reactive, ref, watch } from 'vue';
|
||||||
import PortConfig from '@/views/website/runtime/port/index.vue';
|
import PortConfig from '@/views/website/runtime/port/index.vue';
|
||||||
import Environment from '@/views/website/runtime/environment/index.vue';
|
import Environment from '@/views/website/runtime/environment/index.vue';
|
||||||
|
import Volumes from '@/views/website/runtime/volume/index.vue';
|
||||||
|
import AppConfig from '@/views/website/runtime/app/index.vue';
|
||||||
|
import DirConfig from '@/views/website/runtime/dir/index.vue';
|
||||||
|
|
||||||
interface OperateRrops {
|
interface OperateRrops {
|
||||||
id?: number;
|
id?: number;
|
||||||
|
@ -109,18 +64,10 @@ interface OperateRrops {
|
||||||
}
|
}
|
||||||
|
|
||||||
const open = ref(false);
|
const open = ref(false);
|
||||||
const apps = ref<App.App[]>([]);
|
|
||||||
const runtimeForm = ref<FormInstance>();
|
const runtimeForm = ref<FormInstance>();
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const mode = ref('create');
|
const mode = ref('create');
|
||||||
const editParams = ref<App.InstallParams[]>();
|
const editParams = ref<App.InstallParams[]>();
|
||||||
const appVersions = ref<string[]>([]);
|
|
||||||
const appReq = reactive({
|
|
||||||
type: 'java',
|
|
||||||
page: 1,
|
|
||||||
pageSize: 20,
|
|
||||||
resource: 'remote',
|
|
||||||
});
|
|
||||||
const initData = (type: string) => ({
|
const initData = (type: string) => ({
|
||||||
name: '',
|
name: '',
|
||||||
appDetailID: undefined,
|
appDetailID: undefined,
|
||||||
|
@ -135,6 +82,7 @@ const initData = (type: string) => ({
|
||||||
port: 8080,
|
port: 8080,
|
||||||
exposedPorts: [],
|
exposedPorts: [],
|
||||||
environments: [],
|
environments: [],
|
||||||
|
volumes: [],
|
||||||
});
|
});
|
||||||
let runtime = reactive<Runtime.RuntimeCreate>(initData('java'));
|
let runtime = reactive<Runtime.RuntimeCreate>(initData('java'));
|
||||||
const rules = ref<any>({
|
const rules = ref<any>({
|
||||||
|
@ -178,60 +126,6 @@ const handleClose = () => {
|
||||||
runtimeForm.value?.resetFields();
|
runtimeForm.value?.resetFields();
|
||||||
};
|
};
|
||||||
|
|
||||||
const getPath = (codeDir: string) => {
|
|
||||||
runtime.codeDir = codeDir;
|
|
||||||
};
|
|
||||||
|
|
||||||
const searchApp = (appID: number) => {
|
|
||||||
SearchApp(appReq).then((res) => {
|
|
||||||
apps.value = res.data.items || [];
|
|
||||||
if (res.data && res.data.items && res.data.items.length > 0) {
|
|
||||||
if (appID == null) {
|
|
||||||
runtime.appID = res.data.items[0].id;
|
|
||||||
getApp(res.data.items[0].key, mode.value);
|
|
||||||
} else {
|
|
||||||
res.data.items.forEach((item) => {
|
|
||||||
if (item.id === appID) {
|
|
||||||
getApp(item.key, mode.value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const changeApp = (appID: number) => {
|
|
||||||
for (const app of apps.value) {
|
|
||||||
if (app.id === appID) {
|
|
||||||
getApp(app.key, mode.value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const changeVersion = () => {
|
|
||||||
loading.value = true;
|
|
||||||
GetAppDetail(runtime.appID, runtime.version, 'runtime')
|
|
||||||
.then((res) => {
|
|
||||||
runtime.appDetailID = res.data.id;
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
loading.value = false;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const getApp = (appkey: string, mode: string) => {
|
|
||||||
GetApp(appkey).then((res) => {
|
|
||||||
appVersions.value = res.data.versions || [];
|
|
||||||
if (res.data.versions.length > 0) {
|
|
||||||
if (mode === 'create') {
|
|
||||||
runtime.version = res.data.versions[0];
|
|
||||||
changeVersion();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const submit = async (formEl: FormInstance | undefined) => {
|
const submit = async (formEl: FormInstance | undefined) => {
|
||||||
if (!formEl) return;
|
if (!formEl) return;
|
||||||
await formEl.validate((valid) => {
|
await formEl.validate((valid) => {
|
||||||
|
@ -288,7 +182,7 @@ const getRuntime = async (id: number) => {
|
||||||
Object.assign(runtime, {
|
Object.assign(runtime, {
|
||||||
id: data.id,
|
id: data.id,
|
||||||
name: data.name,
|
name: data.name,
|
||||||
appDetailId: data.appDetailID,
|
appDetailID: data.appDetailID,
|
||||||
image: data.image,
|
image: data.image,
|
||||||
type: data.type,
|
type: data.type,
|
||||||
resource: data.resource,
|
resource: data.resource,
|
||||||
|
@ -303,7 +197,6 @@ const getRuntime = async (id: number) => {
|
||||||
runtime.exposedPorts = data.exposedPorts || [];
|
runtime.exposedPorts = data.exposedPorts || [];
|
||||||
runtime.environments = data.environments || [];
|
runtime.environments = data.environments || [];
|
||||||
editParams.value = data.appParams;
|
editParams.value = data.appParams;
|
||||||
searchApp(data.appID);
|
|
||||||
open.value = true;
|
open.value = true;
|
||||||
} catch (error) {}
|
} catch (error) {}
|
||||||
};
|
};
|
||||||
|
@ -313,7 +206,6 @@ const acceptParams = async (props: OperateRrops) => {
|
||||||
scripts.value = [];
|
scripts.value = [];
|
||||||
if (props.mode === 'create') {
|
if (props.mode === 'create') {
|
||||||
Object.assign(runtime, initData(props.type));
|
Object.assign(runtime, initData(props.type));
|
||||||
searchApp(null);
|
|
||||||
open.value = true;
|
open.value = true;
|
||||||
} else {
|
} else {
|
||||||
getRuntime(props.id);
|
getRuntime(props.id);
|
||||||
|
|
|
@ -18,93 +18,11 @@
|
||||||
<el-form-item :label="$t('commons.table.name')" prop="name">
|
<el-form-item :label="$t('commons.table.name')" prop="name">
|
||||||
<el-input :disabled="mode === 'edit'" v-model="runtime.name"></el-input>
|
<el-input :disabled="mode === 'edit'" v-model="runtime.name"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('runtime.app')" prop="appID">
|
<AppConfig v-model="runtime" :mode="mode" appKey="node" />
|
||||||
<el-row :gutter="20">
|
<DirConfig v-model="runtime" :mode="mode" appKey="node" :scriptHelper="$t('runtime.customScriptHelper')" />
|
||||||
<el-col :span="12">
|
<el-form-item :label="$t('app.containerName')" prop="params.CONTAINER_NAME">
|
||||||
<el-select
|
<el-input v-model.trim="runtime.params['CONTAINER_NAME']"></el-input>
|
||||||
v-model="runtime.appID"
|
|
||||||
:disabled="mode === 'edit'"
|
|
||||||
@change="changeApp(runtime.appID)"
|
|
||||||
class="p-w-200"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="(app, index) in apps"
|
|
||||||
:key="index"
|
|
||||||
:label="app.name"
|
|
||||||
:value="app.id"
|
|
||||||
></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-select
|
|
||||||
v-model="runtime.version"
|
|
||||||
:disabled="mode === 'edit'"
|
|
||||||
@change="changeVersion()"
|
|
||||||
class="p-w-200"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="(version, index) in appVersions"
|
|
||||||
:key="index"
|
|
||||||
:label="version"
|
|
||||||
:value="version"
|
|
||||||
></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('runtime.codeDir')" prop="codeDir">
|
|
||||||
<el-input v-model.trim="runtime.codeDir" :disabled="mode === 'edit'">
|
|
||||||
<template #prepend>
|
|
||||||
<FileList
|
|
||||||
:disabled="mode === 'edit'"
|
|
||||||
:path="runtime.codeDir"
|
|
||||||
@choose="getPath"
|
|
||||||
:dir="true"
|
|
||||||
></FileList>
|
|
||||||
</template>
|
|
||||||
</el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-row :gutter="20">
|
|
||||||
<el-col :span="18">
|
|
||||||
<el-form-item :label="$t('runtime.runScript')" prop="params.EXEC_SCRIPT">
|
|
||||||
<el-select
|
|
||||||
v-model="runtime.params['EXEC_SCRIPT']"
|
|
||||||
v-if="runtime.params['CUSTOM_SCRIPT'] == '0'"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="(script, index) in scripts"
|
|
||||||
:key="index"
|
|
||||||
:label="script.name + ' 【 ' + script.script + ' 】'"
|
|
||||||
:value="script.name"
|
|
||||||
>
|
|
||||||
<el-row :gutter="10">
|
|
||||||
<el-col :span="4">{{ script.name }}</el-col>
|
|
||||||
<el-col :span="10">{{ ' 【 ' + script.script + ' 】' }}</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-option>
|
|
||||||
</el-select>
|
|
||||||
<el-input v-else v-model="runtime.params['EXEC_SCRIPT']"></el-input>
|
|
||||||
<span class="input-help" v-if="runtime.params['CUSTOM_SCRIPT'] == '0'">
|
|
||||||
{{ $t('runtime.runScriptHelper') }}
|
|
||||||
</span>
|
|
||||||
<span class="input-help" v-else>
|
|
||||||
{{ $t('runtime.customScriptHelper') }}
|
|
||||||
</span>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="6">
|
|
||||||
<el-form-item :label="$t('runtime.customScript')" prop="params.CUSTOM_SCRIPT">
|
|
||||||
<el-switch
|
|
||||||
v-model="runtime.params['CUSTOM_SCRIPT']"
|
|
||||||
:active-value="'1'"
|
|
||||||
:inactive-value="'0'"
|
|
||||||
@change="changeScriptType"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<PortConfig :params="runtime.params" :exposedPorts="runtime.exposedPorts" :rules="rules" />
|
|
||||||
<Environment :environments="runtime.environments" />
|
|
||||||
<el-form-item :label="$t('runtime.packageManager')" prop="params.PACKAGE_MANAGER">
|
<el-form-item :label="$t('runtime.packageManager')" prop="params.PACKAGE_MANAGER">
|
||||||
<el-select v-model="runtime.params['PACKAGE_MANAGER']">
|
<el-select v-model="runtime.params['PACKAGE_MANAGER']">
|
||||||
<el-option label="npm" value="npm"></el-option>
|
<el-option label="npm" value="npm"></el-option>
|
||||||
|
@ -125,9 +43,9 @@
|
||||||
{{ $t('runtime.phpsourceHelper') }}
|
{{ $t('runtime.phpsourceHelper') }}
|
||||||
</span>
|
</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('app.containerName')" prop="params.CONTAINER_NAME">
|
<PortConfig v-model="runtime" :mode="mode" />
|
||||||
<el-input v-model.trim="runtime.params['CONTAINER_NAME']"></el-input>
|
<Environment :environments="runtime.environments" />
|
||||||
</el-form-item>
|
<Volumes :volumes="runtime.volumes" />
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
|
@ -144,8 +62,7 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { App } from '@/api/interface/app';
|
import { App } from '@/api/interface/app';
|
||||||
import { Runtime } from '@/api/interface/runtime';
|
import { Runtime } from '@/api/interface/runtime';
|
||||||
import { GetApp, GetAppDetail, SearchApp } from '@/api/modules/app';
|
import { CreateRuntime, GetRuntime, UpdateRuntime } from '@/api/modules/runtime';
|
||||||
import { CreateRuntime, GetNodeScripts, GetRuntime, UpdateRuntime } from '@/api/modules/runtime';
|
|
||||||
import { Rules, checkNumberRange } from '@/global/form-rules';
|
import { Rules, checkNumberRange } from '@/global/form-rules';
|
||||||
import i18n from '@/lang';
|
import i18n from '@/lang';
|
||||||
import { MsgError, MsgSuccess } from '@/utils/message';
|
import { MsgError, MsgSuccess } from '@/utils/message';
|
||||||
|
@ -153,6 +70,9 @@ import { FormInstance } from 'element-plus';
|
||||||
import { computed, reactive, ref, watch } from 'vue';
|
import { computed, reactive, ref, watch } from 'vue';
|
||||||
import PortConfig from '@/views/website/runtime/port/index.vue';
|
import PortConfig from '@/views/website/runtime/port/index.vue';
|
||||||
import Environment from '@/views/website/runtime/environment/index.vue';
|
import Environment from '@/views/website/runtime/environment/index.vue';
|
||||||
|
import AppConfig from '@/views/website/runtime/app/index.vue';
|
||||||
|
import Volumes from '@/views/website/runtime/volume/index.vue';
|
||||||
|
import DirConfig from '@/views/website/runtime/dir/index.vue';
|
||||||
|
|
||||||
interface OperateRrops {
|
interface OperateRrops {
|
||||||
id?: number;
|
id?: number;
|
||||||
|
@ -161,18 +81,10 @@ interface OperateRrops {
|
||||||
}
|
}
|
||||||
|
|
||||||
const open = ref(false);
|
const open = ref(false);
|
||||||
const apps = ref<App.App[]>([]);
|
|
||||||
const runtimeForm = ref<FormInstance>();
|
const runtimeForm = ref<FormInstance>();
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const mode = ref('create');
|
const mode = ref('create');
|
||||||
const editParams = ref<App.InstallParams[]>();
|
const editParams = ref<App.InstallParams[]>();
|
||||||
const appVersions = ref<string[]>([]);
|
|
||||||
const appReq = reactive({
|
|
||||||
type: 'node',
|
|
||||||
page: 1,
|
|
||||||
pageSize: 20,
|
|
||||||
resource: 'remote',
|
|
||||||
});
|
|
||||||
const initData = (type: string) => ({
|
const initData = (type: string) => ({
|
||||||
name: '',
|
name: '',
|
||||||
appDetailID: undefined,
|
appDetailID: undefined,
|
||||||
|
@ -186,10 +98,11 @@ const initData = (type: string) => ({
|
||||||
resource: 'appstore',
|
resource: 'appstore',
|
||||||
rebuild: false,
|
rebuild: false,
|
||||||
codeDir: '/',
|
codeDir: '/',
|
||||||
port: 3000,
|
port: 4004,
|
||||||
source: 'https://registry.npmjs.org/',
|
source: 'https://registry.npmjs.org/',
|
||||||
exposedPorts: [],
|
exposedPorts: [],
|
||||||
environments: [],
|
environments: [],
|
||||||
|
volumes: [],
|
||||||
});
|
});
|
||||||
let runtime = reactive<Runtime.RuntimeCreate>(initData('node'));
|
let runtime = reactive<Runtime.RuntimeCreate>(initData('node'));
|
||||||
const rules = ref<any>({
|
const rules = ref<any>({
|
||||||
|
@ -205,7 +118,6 @@ const rules = ref<any>({
|
||||||
CONTAINER_NAME: [Rules.requiredInput, Rules.containerName],
|
CONTAINER_NAME: [Rules.requiredInput, Rules.containerName],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const scripts = ref<Runtime.NodeScripts[]>([]);
|
|
||||||
const em = defineEmits(['close']);
|
const em = defineEmits(['close']);
|
||||||
|
|
||||||
const hasPnpm = computed(() => {
|
const hasPnpm = computed(() => {
|
||||||
|
@ -230,16 +142,6 @@ const imageSources = [
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
watch(
|
|
||||||
() => runtime.params['APP_PORT'],
|
|
||||||
(newVal) => {
|
|
||||||
if (newVal && mode.value == 'create') {
|
|
||||||
runtime.port = newVal;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ deep: true },
|
|
||||||
);
|
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => runtime.name,
|
() => runtime.name,
|
||||||
(newVal) => {
|
(newVal) => {
|
||||||
|
@ -256,80 +158,6 @@ const handleClose = () => {
|
||||||
runtimeForm.value?.resetFields();
|
runtimeForm.value?.resetFields();
|
||||||
};
|
};
|
||||||
|
|
||||||
const getPath = (codeDir: string) => {
|
|
||||||
runtime.codeDir = codeDir;
|
|
||||||
getScripts();
|
|
||||||
};
|
|
||||||
|
|
||||||
const changeScriptType = () => {
|
|
||||||
runtime.params['EXEC_SCRIPT'] = '';
|
|
||||||
if (runtime.params['CUSTOM_SCRIPT'] == '0') {
|
|
||||||
getScripts();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const getScripts = () => {
|
|
||||||
GetNodeScripts({ codeDir: runtime.codeDir }).then((res) => {
|
|
||||||
scripts.value = res.data;
|
|
||||||
if (mode.value == 'create' && scripts.value.length > 0) {
|
|
||||||
runtime.params['EXEC_SCRIPT'] = scripts.value[0].name;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const searchApp = (appID: number) => {
|
|
||||||
SearchApp(appReq).then((res) => {
|
|
||||||
apps.value = res.data.items || [];
|
|
||||||
if (res.data && res.data.items && res.data.items.length > 0) {
|
|
||||||
if (appID == null) {
|
|
||||||
runtime.appID = res.data.items[0].id;
|
|
||||||
getApp(res.data.items[0].key, mode.value);
|
|
||||||
} else {
|
|
||||||
res.data.items.forEach((item) => {
|
|
||||||
if (item.id === appID) {
|
|
||||||
getApp(item.key, mode.value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const changeApp = (appID: number) => {
|
|
||||||
for (const app of apps.value) {
|
|
||||||
if (app.id === appID) {
|
|
||||||
getApp(app.key, mode.value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const changeVersion = () => {
|
|
||||||
loading.value = true;
|
|
||||||
if (runtime.params['PACKAGE_MANAGER'] == 'pnpm' && !hasPnpm.value) {
|
|
||||||
runtime.params['PACKAGE_MANAGER'] = 'npm';
|
|
||||||
}
|
|
||||||
GetAppDetail(runtime.appID, runtime.version, 'runtime')
|
|
||||||
.then((res) => {
|
|
||||||
runtime.appDetailID = res.data.id;
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
loading.value = false;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const getApp = (appkey: string, mode: string) => {
|
|
||||||
GetApp(appkey).then((res) => {
|
|
||||||
appVersions.value = res.data.versions || [];
|
|
||||||
if (res.data.versions.length > 0) {
|
|
||||||
if (mode === 'create') {
|
|
||||||
runtime.version = res.data.versions[0];
|
|
||||||
changeVersion();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const submit = async (formEl: FormInstance | undefined) => {
|
const submit = async (formEl: FormInstance | undefined) => {
|
||||||
if (!formEl) return;
|
if (!formEl) return;
|
||||||
await formEl.validate((valid) => {
|
await formEl.validate((valid) => {
|
||||||
|
@ -386,7 +214,7 @@ const getRuntime = async (id: number) => {
|
||||||
Object.assign(runtime, {
|
Object.assign(runtime, {
|
||||||
id: data.id,
|
id: data.id,
|
||||||
name: data.name,
|
name: data.name,
|
||||||
appDetailId: data.appDetailID,
|
appDetailID: data.appDetailID,
|
||||||
image: data.image,
|
image: data.image,
|
||||||
type: data.type,
|
type: data.type,
|
||||||
resource: data.resource,
|
resource: data.resource,
|
||||||
|
@ -401,10 +229,8 @@ const getRuntime = async (id: number) => {
|
||||||
runtime.exposedPorts = data.exposedPorts || [];
|
runtime.exposedPorts = data.exposedPorts || [];
|
||||||
runtime.environments = data.environments || [];
|
runtime.environments = data.environments || [];
|
||||||
editParams.value = data.appParams;
|
editParams.value = data.appParams;
|
||||||
searchApp(data.appID);
|
|
||||||
if (data.params['CUSTOM_SCRIPT'] == undefined || data.params['CUSTOM_SCRIPT'] == '0') {
|
if (data.params['CUSTOM_SCRIPT'] == undefined || data.params['CUSTOM_SCRIPT'] == '0') {
|
||||||
data.params['CUSTOM_SCRIPT'] = '0';
|
data.params['CUSTOM_SCRIPT'] = '0';
|
||||||
getScripts();
|
|
||||||
}
|
}
|
||||||
open.value = true;
|
open.value = true;
|
||||||
} catch (error) {}
|
} catch (error) {}
|
||||||
|
@ -412,10 +238,8 @@ const getRuntime = async (id: number) => {
|
||||||
|
|
||||||
const acceptParams = async (props: OperateRrops) => {
|
const acceptParams = async (props: OperateRrops) => {
|
||||||
mode.value = props.mode;
|
mode.value = props.mode;
|
||||||
scripts.value = [];
|
|
||||||
if (props.mode === 'create') {
|
if (props.mode === 'create') {
|
||||||
Object.assign(runtime, initData(props.type));
|
Object.assign(runtime, initData(props.type));
|
||||||
searchApp(null);
|
|
||||||
open.value = true;
|
open.value = true;
|
||||||
} else {
|
} else {
|
||||||
getRuntime(props.id);
|
getRuntime(props.id);
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
<el-col :span="7">
|
<el-col :span="7">
|
||||||
<el-form-item :label="$t('runtime.appPort')" prop="params.APP_PORT" :rules="rules.port">
|
<el-form-item :label="$t('runtime.appPort')" prop="params.APP_PORT" :rules="rules.port">
|
||||||
<el-input v-model.number="params.APP_PORT" />
|
<el-input v-model.number="runtime.params.APP_PORT" />
|
||||||
<span class="input-help">{{ $t('runtime.appPortHelper') }}</span>
|
<span class="input-help">{{ $t('runtime.appPortHelper') }}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="7">
|
<el-col :span="7">
|
||||||
<el-form-item :label="$t('runtime.externalPort')" prop="params.port" :rules="rules.port">
|
<el-form-item :label="$t('runtime.externalPort')" prop="params.PANEL_APP_PORT_HTTP" :rules="rules.port">
|
||||||
<el-input v-model.number="params.port" />
|
<el-input v-model.number="runtime.params.PANEL_APP_PORT_HTTP" />
|
||||||
<span class="input-help">{{ $t('runtime.externalPortHelper') }}</span>
|
<span class="input-help">{{ $t('runtime.externalPortHelper') }}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
@ -21,11 +21,11 @@
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
<el-form-item :label="$t('app.allowPort')">
|
<el-form-item :label="$t('app.allowPort')">
|
||||||
<el-switch v-model="params.HOST_IP" :active-value="'0.0.0.0'" :inactive-value="'127.0.0.1'" />
|
<el-switch v-model="runtime.params.HOST_IP" :active-value="'0.0.0.0'" :inactive-value="'127.0.0.1'" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row :gutter="20" v-for="(port, index) in exposedPorts" :key="index">
|
<el-row :gutter="20" v-for="(port, index) in runtime.exposedPorts" :key="index">
|
||||||
<el-col :span="7">
|
<el-col :span="7">
|
||||||
<el-form-item :prop="`exposedPorts.${index}.containerPort`" :rules="rules.port">
|
<el-form-item :prop="`exposedPorts.${index}.containerPort`" :rules="rules.port">
|
||||||
<el-input v-model.number="port.containerPort" :placeholder="$t('runtime.appPort')" />
|
<el-input v-model.number="port.containerPort" :placeholder="$t('runtime.appPort')" />
|
||||||
|
@ -50,31 +50,43 @@
|
||||||
import { Rules, checkNumberRange } from '@/global/form-rules';
|
import { Rules, checkNumberRange } from '@/global/form-rules';
|
||||||
import { FormRules } from 'element-plus';
|
import { FormRules } from 'element-plus';
|
||||||
import { defineProps } from 'vue';
|
import { defineProps } from 'vue';
|
||||||
import { Runtime } from '@/api/interface/runtime';
|
import { useVModel } from '@vueuse/core';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
params: {
|
mode: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
modelValue: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
exposedPorts: {
|
|
||||||
type: Array<Runtime.ExposedPort>,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
const emit = defineEmits(['update:modelValue']);
|
||||||
|
const runtime = useVModel(props, 'modelValue', emit);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => runtime.value.params['APP_PORT'],
|
||||||
|
(newVal) => {
|
||||||
|
if (newVal) {
|
||||||
|
runtime.value.params['PANEL_APP_PORT_HTTP'] = newVal;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ deep: true },
|
||||||
|
);
|
||||||
|
|
||||||
const rules = reactive<FormRules>({
|
const rules = reactive<FormRules>({
|
||||||
port: [Rules.requiredInput, Rules.paramPort, checkNumberRange(1, 65535)],
|
port: [Rules.requiredInput, Rules.paramPort, checkNumberRange(1, 65535)],
|
||||||
});
|
});
|
||||||
|
|
||||||
const addPort = () => {
|
const addPort = () => {
|
||||||
props.exposedPorts.push({
|
runtime.value.exposedPorts.push({
|
||||||
hostPort: undefined,
|
hostPort: undefined,
|
||||||
containerPort: undefined,
|
containerPort: undefined,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const removePort = (index: number) => {
|
const removePort = (index: number) => {
|
||||||
props.exposedPorts.splice(index, 1);
|
runtime.value.exposedPorts.splice(index, 1);
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -18,64 +18,14 @@
|
||||||
<el-form-item :label="$t('commons.table.name')" prop="name">
|
<el-form-item :label="$t('commons.table.name')" prop="name">
|
||||||
<el-input :disabled="mode === 'edit'" v-model="runtime.name"></el-input>
|
<el-input :disabled="mode === 'edit'" v-model="runtime.name"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('runtime.app')" prop="appID">
|
<DirConfig v-model="runtime" :mode="mode" :scriptHelper="$t('runtime.pythonHelper')" />
|
||||||
<el-row :gutter="20">
|
<AppConfig v-model="runtime" :mode="mode" appKey="python" />
|
||||||
<el-col :span="12">
|
|
||||||
<el-select
|
|
||||||
v-model="runtime.appID"
|
|
||||||
:disabled="mode === 'edit'"
|
|
||||||
@change="changeApp(runtime.appID)"
|
|
||||||
class="p-w-200"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="(app, index) in apps"
|
|
||||||
:key="index"
|
|
||||||
:label="app.name"
|
|
||||||
:value="app.id"
|
|
||||||
></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-select
|
|
||||||
v-model="runtime.version"
|
|
||||||
:disabled="mode === 'edit'"
|
|
||||||
@change="changeVersion()"
|
|
||||||
class="p-w-200"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="(version, index) in appVersions"
|
|
||||||
:key="index"
|
|
||||||
:label="version"
|
|
||||||
:value="version"
|
|
||||||
></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item :label="$t('tool.supervisor.dir')" prop="codeDir">
|
|
||||||
<el-input v-model.trim="runtime.codeDir" :disabled="mode === 'edit'">
|
|
||||||
<template #prepend>
|
|
||||||
<FileList
|
|
||||||
:disabled="mode === 'edit'"
|
|
||||||
:path="runtime.codeDir"
|
|
||||||
@choose="getPath"
|
|
||||||
:dir="true"
|
|
||||||
></FileList>
|
|
||||||
</template>
|
|
||||||
</el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item :label="$t('runtime.runScript')" prop="params.EXEC_SCRIPT">
|
|
||||||
<el-input v-model="runtime.params['EXEC_SCRIPT']"></el-input>
|
|
||||||
<span class="input-help">
|
|
||||||
{{ $t('runtime.pythonHelper') }}
|
|
||||||
</span>
|
|
||||||
</el-form-item>
|
|
||||||
<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-form-item :label="$t('app.containerName')" prop="params.CONTAINER_NAME">
|
||||||
<el-input v-model.trim="runtime.params['CONTAINER_NAME']"></el-input>
|
<el-input v-model.trim="runtime.params['CONTAINER_NAME']"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<PortConfig v-model="runtime" :mode="mode" />
|
||||||
|
<Environment :environments="runtime.environments" />
|
||||||
|
<Volumes :volumes="runtime.volumes" />
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
|
@ -90,16 +40,17 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { App } from '@/api/interface/app';
|
import { App } from '@/api/interface/app';
|
||||||
import { Runtime } from '@/api/interface/runtime';
|
import { Runtime } from '@/api/interface/runtime';
|
||||||
import { GetApp, GetAppDetail, SearchApp } from '@/api/modules/app';
|
|
||||||
import { CreateRuntime, GetRuntime, UpdateRuntime } from '@/api/modules/runtime';
|
import { CreateRuntime, GetRuntime, UpdateRuntime } from '@/api/modules/runtime';
|
||||||
import { Rules, checkNumberRange } from '@/global/form-rules';
|
import { Rules, checkNumberRange } from '@/global/form-rules';
|
||||||
import i18n from '@/lang';
|
import i18n from '@/lang';
|
||||||
import { MsgError, MsgSuccess } from '@/utils/message';
|
import { MsgError, MsgSuccess } from '@/utils/message';
|
||||||
import { FormInstance } from 'element-plus';
|
import { FormInstance } from 'element-plus';
|
||||||
import { reactive, ref, watch } from 'vue';
|
import { reactive, ref } from 'vue';
|
||||||
import PortConfig from '@/views/website/runtime/port/index.vue';
|
import PortConfig from '@/views/website/runtime/port/index.vue';
|
||||||
import Environment from '@/views/website/runtime/environment/index.vue';
|
import Environment from '@/views/website/runtime/environment/index.vue';
|
||||||
import Volumes from '@/views/website/runtime/volume/index.vue';
|
import Volumes from '@/views/website/runtime/volume/index.vue';
|
||||||
|
import AppConfig from '@/views/website/runtime/app/index.vue';
|
||||||
|
import DirConfig from '@/views/website/runtime/dir/index.vue';
|
||||||
|
|
||||||
interface OperateRrops {
|
interface OperateRrops {
|
||||||
id?: number;
|
id?: number;
|
||||||
|
@ -108,18 +59,10 @@ interface OperateRrops {
|
||||||
}
|
}
|
||||||
|
|
||||||
const open = ref(false);
|
const open = ref(false);
|
||||||
const apps = ref<App.App[]>([]);
|
|
||||||
const runtimeForm = ref<FormInstance>();
|
const runtimeForm = ref<FormInstance>();
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const mode = ref('create');
|
const mode = ref('create');
|
||||||
const editParams = ref<App.InstallParams[]>();
|
const editParams = ref<App.InstallParams[]>();
|
||||||
const appVersions = ref<string[]>([]);
|
|
||||||
const appReq = reactive({
|
|
||||||
type: 'python',
|
|
||||||
page: 1,
|
|
||||||
pageSize: 20,
|
|
||||||
resource: 'remote',
|
|
||||||
});
|
|
||||||
const initData = (type: string) => ({
|
const initData = (type: string) => ({
|
||||||
name: '',
|
name: '',
|
||||||
appDetailID: undefined,
|
appDetailID: undefined,
|
||||||
|
@ -153,86 +96,12 @@ const rules = ref<any>({
|
||||||
const scripts = ref<Runtime.NodeScripts[]>([]);
|
const scripts = ref<Runtime.NodeScripts[]>([]);
|
||||||
const em = defineEmits(['close']);
|
const em = defineEmits(['close']);
|
||||||
|
|
||||||
watch(
|
|
||||||
() => runtime.params['APP_PORT'],
|
|
||||||
(newVal) => {
|
|
||||||
if (newVal && mode.value == 'create') {
|
|
||||||
runtime.port = newVal;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ deep: true },
|
|
||||||
);
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => runtime.name,
|
|
||||||
(newVal) => {
|
|
||||||
if (newVal && mode.value == 'create') {
|
|
||||||
runtime.params['CONTAINER_NAME'] = newVal;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ deep: true },
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
open.value = false;
|
open.value = false;
|
||||||
em('close', false);
|
em('close', false);
|
||||||
runtimeForm.value?.resetFields();
|
runtimeForm.value?.resetFields();
|
||||||
};
|
};
|
||||||
|
|
||||||
const getPath = (codeDir: string) => {
|
|
||||||
runtime.codeDir = codeDir;
|
|
||||||
};
|
|
||||||
|
|
||||||
const searchApp = (appID: number) => {
|
|
||||||
SearchApp(appReq).then((res) => {
|
|
||||||
apps.value = res.data.items || [];
|
|
||||||
if (res.data && res.data.items && res.data.items.length > 0) {
|
|
||||||
if (appID == null) {
|
|
||||||
runtime.appID = res.data.items[0].id;
|
|
||||||
getApp(res.data.items[0].key, mode.value);
|
|
||||||
} else {
|
|
||||||
res.data.items.forEach((item) => {
|
|
||||||
if (item.id === appID) {
|
|
||||||
getApp(item.key, mode.value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const changeApp = (appID: number) => {
|
|
||||||
for (const app of apps.value) {
|
|
||||||
if (app.id === appID) {
|
|
||||||
getApp(app.key, mode.value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const changeVersion = () => {
|
|
||||||
loading.value = true;
|
|
||||||
GetAppDetail(runtime.appID, runtime.version, 'runtime')
|
|
||||||
.then((res) => {
|
|
||||||
runtime.appDetailID = res.data.id;
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
loading.value = false;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const getApp = (appkey: string, mode: string) => {
|
|
||||||
GetApp(appkey).then((res) => {
|
|
||||||
appVersions.value = res.data.versions || [];
|
|
||||||
if (res.data.versions.length > 0) {
|
|
||||||
if (mode === 'create') {
|
|
||||||
runtime.version = res.data.versions[0];
|
|
||||||
changeVersion();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const submit = async (formEl: FormInstance | undefined) => {
|
const submit = async (formEl: FormInstance | undefined) => {
|
||||||
if (!formEl) return;
|
if (!formEl) return;
|
||||||
await formEl.validate((valid) => {
|
await formEl.validate((valid) => {
|
||||||
|
@ -289,7 +158,7 @@ const getRuntime = async (id: number) => {
|
||||||
Object.assign(runtime, {
|
Object.assign(runtime, {
|
||||||
id: data.id,
|
id: data.id,
|
||||||
name: data.name,
|
name: data.name,
|
||||||
appDetailId: data.appDetailID,
|
appDetailID: data.appDetailID,
|
||||||
image: data.image,
|
image: data.image,
|
||||||
type: data.type,
|
type: data.type,
|
||||||
resource: data.resource,
|
resource: data.resource,
|
||||||
|
@ -305,7 +174,6 @@ const getRuntime = async (id: number) => {
|
||||||
runtime.environments = data.environments || [];
|
runtime.environments = data.environments || [];
|
||||||
runtime.volumes = data.volumes || [];
|
runtime.volumes = data.volumes || [];
|
||||||
editParams.value = data.appParams;
|
editParams.value = data.appParams;
|
||||||
searchApp(data.appID);
|
|
||||||
open.value = true;
|
open.value = true;
|
||||||
} catch (error) {}
|
} catch (error) {}
|
||||||
};
|
};
|
||||||
|
@ -315,7 +183,6 @@ const acceptParams = async (props: OperateRrops) => {
|
||||||
scripts.value = [];
|
scripts.value = [];
|
||||||
if (props.mode === 'create') {
|
if (props.mode === 'create') {
|
||||||
Object.assign(runtime, initData(props.type));
|
Object.assign(runtime, initData(props.type));
|
||||||
searchApp(null);
|
|
||||||
open.value = true;
|
open.value = true;
|
||||||
} else {
|
} else {
|
||||||
getRuntime(props.id);
|
getRuntime(props.id);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="mt-1.5">
|
<div class="mt-2">
|
||||||
<el-text>{{ $t('container.mount') }}</el-text>
|
<el-text>{{ $t('container.mount') }}</el-text>
|
||||||
<div class="mt-1.5">
|
<div class="mt-2">
|
||||||
<el-row :gutter="20" v-for="(volume, index) in volumes" :key="index">
|
<el-row :gutter="20" v-for="(volume, index) in volumes" :key="index">
|
||||||
<el-col :span="7">
|
<el-col :span="7">
|
||||||
<el-form-item :prop="`volumes.${index}.source`" :rules="rules.value">
|
<el-form-item :prop="`volumes.${index}.source`" :rules="rules.value">
|
||||||
|
|
Loading…
Add table
Reference in a new issue