feat: 创建应用增加 compose 文件配置功能 (#1105)

Refs https://github.com/1Panel-dev/1Panel/issues/301
This commit is contained in:
zhengkunwang223 2023-05-22 19:19:40 +08:00 committed by GitHub
parent 53600900f2
commit 74cfc11a37
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 53 additions and 5 deletions

View File

@ -28,6 +28,8 @@ type AppContainerConfig struct {
MemoryUnit string `json:"memoryUnit"`
ContainerName string `json:"containerName"`
AllowPort bool `json:"allowPort"`
EditCompose bool `json:"editCompose"`
DockerCompose string `json:"dockerCompose"`
}
type AppInstalledSearch struct {

View File

@ -5,7 +5,7 @@ type AppDetail struct {
AppId uint `json:"appId" gorm:"type:integer;not null"`
Version string `json:"version" gorm:"type:varchar(64);not null"`
Params string `json:"-" gorm:"type:longtext;"`
DockerCompose string `json:"-" gorm:"type:longtext;"`
DockerCompose string `json:"dockerCompose" gorm:"type:longtext;"`
Status string `json:"status" gorm:"type:varchar(64);not null"`
LastVersion string `json:"lastVersion" gorm:"type:varchar(64);"`
LastModified int `json:"lastModified" gorm:"type:integer;"`

View File

@ -268,8 +268,14 @@ func (a AppService) Install(ctx context.Context, req request.AppInstallCreate) (
App: app,
}
composeMap := make(map[string]interface{})
if err = yaml.Unmarshal([]byte(appDetail.DockerCompose), &composeMap); err != nil {
return
if req.EditCompose {
if err = yaml.Unmarshal([]byte(req.DockerCompose), &composeMap); err != nil {
return
}
} else {
if err = yaml.Unmarshal([]byte(appDetail.DockerCompose), &composeMap); err != nil {
return
}
}
value, ok := composeMap["services"]

View File

@ -1120,6 +1120,9 @@ const message = {
'The application does not release the external access port by default, you can choose to release it in the advanced settings',
upgradeStart: 'Start upgrading! Please refresh the page later',
toFolder: 'Open the installation directory',
editCompose: 'Edit compose file',
editComposeHelper: 'Editing the compose file may cause the software installation to fail',
composeNullErr: 'compose cannot be empty',
},
website: {
website: 'Website',

View File

@ -1113,6 +1113,9 @@ const message = {
appInstallWarn: '应用默认不放开外部访问端口可以在高级设置中选择放开',
upgradeStart: '开始升级请稍后刷新页面',
toFolder: '打开安装目录',
editCompose: '编辑 compose 文件',
editComposeHelper: '编辑 compose 文件可能导致软件安装失败',
composeNullErr: 'compose 不能为空',
},
website: {
website: '网站',

View File

@ -150,6 +150,7 @@ const openInstall = () => {
params: appDetail.value.params,
appDetailId: appDetail.value.id,
app: app.value,
compose: appDetail.value.dockerCompose,
};
if (app.value.type === 'php') {
router.push({ path: '/websites/runtime/php' });

View File

@ -7,9 +7,8 @@
:before-close="handleClose"
>
<template #header>
<Header :header="$t('app.install')" :back="handleClose" />
<Header :header="$t('app.install')" :back="handleClose"></Header>
</template>
<el-row v-loading="loading">
<el-col :span="22" :offset="1">
<el-alert type="info" :closable="false">
@ -66,6 +65,25 @@
<el-checkbox v-model="req.allowPort" :label="$t('app.allowPort')" size="large" />
<span class="input-help">{{ $t('app.allowPortHelper') }}</span>
</el-form-item>
<el-form-item prop="editCompose">
<el-checkbox v-model="req.editCompose" :label="$t('app.editCompose')" size="large" />
<span class="input-help">{{ $t('app.editComposeHelper') }}</span>
</el-form-item>
<div v-if="req.editCompose">
<codemirror
:autofocus="true"
placeholder=""
:indent-with-tab="true"
:tabSize="4"
style="height: 400px"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="req.dockerCompose"
/>
</div>
</div>
</el-form>
</el-col>
@ -92,18 +110,26 @@ import { reactive, ref } from 'vue';
import { useRouter } from 'vue-router';
import Params from '../params/index.vue';
import Header from '@/components/drawer-header/index.vue';
import { Codemirror } from 'vue-codemirror';
import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark';
import i18n from '@/lang';
import { MsgError } from '@/utils/message';
const extensions = [javascript(), oneDark];
const router = useRouter();
interface InstallRrops {
appDetailId: number;
params?: App.AppParams;
app: any;
compose: string;
}
const installData = ref<InstallRrops>({
appDetailId: 0,
app: {},
compose: '',
});
const open = ref(false);
const rules = ref<FormRules>({
@ -126,6 +152,8 @@ const initData = () => ({
memoryUnit: 'MB',
containerName: '',
allowPort: false,
editCompose: false,
dockerCompose: '',
});
const req = reactive(initData());
@ -140,6 +168,7 @@ const resetForm = () => {
paramForm.value.resetFields();
}
Object.assign(req, initData());
req.dockerCompose = installData.value.compose;
};
const acceptParams = (props: InstallRrops): void => {
@ -154,6 +183,10 @@ const submit = async (formEl: FormInstance | undefined) => {
if (!valid) {
return;
}
if (req.editCompose && req.dockerCompose == '') {
MsgError(i18n.global.t('app.composeNullErr'));
return;
}
req.appDetailId = installData.value.appDetailId;
loading.value = true;
InstallApp(req)