mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-10-07 22:16:16 +08:00
feat: OpenResty 增加默认扩展 (#6556)
Some checks failed
sync2gitee / repo-sync (push) Failing after -9m27s
Some checks failed
sync2gitee / repo-sync (push) Failing after -9m27s
This commit is contained in:
parent
3c0dca6992
commit
4720bda29b
12 changed files with 235 additions and 57 deletions
|
@ -84,3 +84,11 @@ type NginxUpstreamServer struct {
|
|||
var LBAlgorithms = map[string]struct{}{"ip_hash": {}, "least_conn": {}}
|
||||
|
||||
var RealIPKeys = map[string]struct{}{"X-Forwarded-For": {}, "X-Real-IP": {}, "CF-Connecting-IP": {}}
|
||||
|
||||
type NginxModule struct {
|
||||
Name string `json:"name"`
|
||||
Script string `json:"script"`
|
||||
Packages []string `json:"packages"`
|
||||
Params string `json:"params"`
|
||||
Enable bool `json:"enable"`
|
||||
}
|
||||
|
|
|
@ -109,6 +109,7 @@ type NginxRedirectUpdate struct {
|
|||
|
||||
type NginxBuildReq struct {
|
||||
TaskID string `json:"taskID" validate:"required"`
|
||||
Mirror string `json:"mirror" validate:"required"`
|
||||
}
|
||||
|
||||
type NginxModuleUpdate struct {
|
||||
|
|
|
@ -69,9 +69,14 @@ type NginxProxyCache struct {
|
|||
}
|
||||
|
||||
type NginxModule struct {
|
||||
Name string `json:"name"`
|
||||
Script string `json:"script"`
|
||||
Packages []string `json:"packages"`
|
||||
Params string `json:"params"`
|
||||
Enable bool `json:"enable"`
|
||||
Name string `json:"name"`
|
||||
Script string `json:"script"`
|
||||
Packages string `json:"packages"`
|
||||
Params string `json:"params"`
|
||||
Enable bool `json:"enable"`
|
||||
}
|
||||
|
||||
type NginxBuildConfig struct {
|
||||
Mirror string `json:"mirror"`
|
||||
Modules []NginxModule `json:"modules"`
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ type INginxService interface {
|
|||
ClearProxyCache() error
|
||||
|
||||
Build(req request.NginxBuildReq) error
|
||||
GetModules() ([]response.NginxModule, error)
|
||||
GetModules() (*response.NginxBuildConfig, error)
|
||||
UpdateModule(req request.NginxModuleUpdate) error
|
||||
}
|
||||
|
||||
|
@ -179,7 +179,7 @@ func (n NginxService) Build(req request.NginxBuildReq) error {
|
|||
return err
|
||||
}
|
||||
var (
|
||||
modules []response.NginxModule
|
||||
modules []dto.NginxModule
|
||||
addModuleParams []string
|
||||
addPackages []string
|
||||
)
|
||||
|
@ -211,6 +211,7 @@ func (n NginxService) Build(req request.NginxBuildReq) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
envs["CONTAINER_PACKAGE_URL"] = req.Mirror
|
||||
envs["RESTY_CONFIG_OPTIONS_MORE"] = ""
|
||||
envs["RESTY_ADD_PACKAGE_BUILDDEPS"] = ""
|
||||
if len(addModuleParams) > 0 {
|
||||
|
@ -239,16 +240,16 @@ func (n NginxService) Build(req request.NginxBuildReq) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (n NginxService) GetModules() ([]response.NginxModule, error) {
|
||||
func (n NginxService) GetModules() (*response.NginxBuildConfig, error) {
|
||||
nginxInstall, err := getAppInstallByKey(constant.AppOpenresty)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fileOp := files.NewFileOp()
|
||||
var modules []response.NginxModule
|
||||
var modules []dto.NginxModule
|
||||
moduleConfigPath := path.Join(nginxInstall.GetPath(), "build", "module.json")
|
||||
if !fileOp.Stat(moduleConfigPath) {
|
||||
return modules, nil
|
||||
return nil, nil
|
||||
}
|
||||
moduleContent, err := fileOp.GetContent(moduleConfigPath)
|
||||
if err != nil {
|
||||
|
@ -257,7 +258,25 @@ func (n NginxService) GetModules() ([]response.NginxModule, error) {
|
|||
if len(moduleContent) > 0 {
|
||||
_ = json.Unmarshal(moduleContent, &modules)
|
||||
}
|
||||
return modules, nil
|
||||
var resList []response.NginxModule
|
||||
for _, module := range modules {
|
||||
resList = append(resList, response.NginxModule{
|
||||
Name: module.Name,
|
||||
Script: module.Script,
|
||||
Packages: strings.Join(module.Packages, ","),
|
||||
Params: module.Params,
|
||||
Enable: module.Enable,
|
||||
})
|
||||
}
|
||||
envs, err := gotenv.Read(nginxInstall.GetEnvPath())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &response.NginxBuildConfig{
|
||||
Mirror: envs["CONTAINER_PACKAGE_URL"],
|
||||
Modules: resList,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (n NginxService) UpdateModule(req request.NginxModuleUpdate) error {
|
||||
|
@ -266,7 +285,9 @@ func (n NginxService) UpdateModule(req request.NginxModuleUpdate) error {
|
|||
return err
|
||||
}
|
||||
fileOp := files.NewFileOp()
|
||||
var modules []response.NginxModule
|
||||
var (
|
||||
modules []dto.NginxModule
|
||||
)
|
||||
moduleConfigPath := path.Join(nginxInstall.GetPath(), "build", "module.json")
|
||||
if !fileOp.Stat(moduleConfigPath) {
|
||||
_ = fileOp.CreateFile(moduleConfigPath)
|
||||
|
@ -278,6 +299,7 @@ func (n NginxService) UpdateModule(req request.NginxModuleUpdate) error {
|
|||
if len(moduleContent) > 0 {
|
||||
_ = json.Unmarshal(moduleContent, &modules)
|
||||
}
|
||||
|
||||
switch req.Operate {
|
||||
case "create":
|
||||
for _, module := range modules {
|
||||
|
@ -285,10 +307,10 @@ func (n NginxService) UpdateModule(req request.NginxModuleUpdate) error {
|
|||
return buserr.New("ErrNameIsExist")
|
||||
}
|
||||
}
|
||||
modules = append(modules, response.NginxModule{
|
||||
modules = append(modules, dto.NginxModule{
|
||||
Name: req.Name,
|
||||
Script: req.Script,
|
||||
Packages: strings.Split(req.Packages, " "),
|
||||
Packages: strings.Split(req.Packages, ","),
|
||||
Params: req.Params,
|
||||
Enable: true,
|
||||
})
|
||||
|
@ -296,7 +318,7 @@ func (n NginxService) UpdateModule(req request.NginxModuleUpdate) error {
|
|||
for i, module := range modules {
|
||||
if module.Name == req.Name {
|
||||
modules[i].Script = req.Script
|
||||
modules[i].Packages = strings.Split(req.Packages, " ")
|
||||
modules[i].Packages = strings.Split(req.Packages, ",")
|
||||
modules[i].Params = req.Params
|
||||
modules[i].Enable = req.Enable
|
||||
break
|
||||
|
|
|
@ -31,22 +31,23 @@ export namespace Nginx {
|
|||
|
||||
export interface NginxBuildReq {
|
||||
taskID: string;
|
||||
mirror: string;
|
||||
}
|
||||
|
||||
export interface NginxModule {
|
||||
name: string;
|
||||
script?: string;
|
||||
packages?: string[];
|
||||
enable: boolean;
|
||||
params: string;
|
||||
}
|
||||
|
||||
export interface NginxModuleUpdate {
|
||||
operate: string;
|
||||
name: string;
|
||||
script?: string;
|
||||
packages?: string;
|
||||
enable: boolean;
|
||||
params: string;
|
||||
}
|
||||
|
||||
export interface NginxBuildConfig {
|
||||
mirror: string;
|
||||
modules: NginxModule[];
|
||||
}
|
||||
|
||||
export interface NginxModuleUpdate extends NginxModule {
|
||||
operate: string;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ export const BuildNginx = (req: Nginx.NginxBuildReq) => {
|
|||
};
|
||||
|
||||
export const GetNginxModules = () => {
|
||||
return http.get<Nginx.NginxModule[]>(`/openresty/modules`);
|
||||
return http.get<Nginx.NginxBuildConfig>(`/openresty/modules`);
|
||||
};
|
||||
|
||||
export const UpdateNginxModule = (req: Nginx.NginxModuleUpdate) => {
|
||||
|
|
|
@ -2260,6 +2260,13 @@ const message = {
|
|||
build: 'Build',
|
||||
buildWarn:
|
||||
'Building OpenResty requires reserving a certain amount of CPU and memory, which may take a long time, please be patient',
|
||||
mirrorUrl: 'Software Source',
|
||||
paramsHelper: 'For example: --add-module=/tmp/ngx_brotli',
|
||||
packagesHelper: 'For example: git, curl (separated by commas)',
|
||||
scriptHelper:
|
||||
'Scripts to execute before compilation, usually for downloading module source code, installing dependencies, etc.',
|
||||
buildHelper:
|
||||
'Click build after adding/modifying a module. OpenResty will automatically restart upon successful build.',
|
||||
},
|
||||
ssl: {
|
||||
create: 'Apply',
|
||||
|
|
|
@ -2104,6 +2104,11 @@ const message = {
|
|||
module: '模組',
|
||||
build: '建構',
|
||||
buildWarn: '建構 OpenResty 需要預留一定的 CPU 和內存,時間較長,請耐心等待',
|
||||
mirrorUrl: '軟體源',
|
||||
paramsHelper: '例如:--add-module=/tmp/ngx_brotli',
|
||||
packagesHelper: '例如:git,curl 以逗號分割',
|
||||
scriptHelper: '編譯之前執行的腳本,通常用於下載模組原始碼,安裝依賴等',
|
||||
buildHelper: '添加/修改模組後點擊構建,構建成功後會自動重啟 OpenResty',
|
||||
},
|
||||
ssl: {
|
||||
create: '申請證書',
|
||||
|
|
|
@ -2105,6 +2105,11 @@ const message = {
|
|||
module: '模块',
|
||||
build: '构建',
|
||||
buildWarn: '构建 OpenResty 需要预留一定的 CPU 和内存,时间较长,请耐心等待',
|
||||
mirrorUrl: '软件源',
|
||||
paramsHelper: '例如:--add-module=/tmp/ngx_brotli',
|
||||
packagesHelper: '例如:git,curl 按,分割',
|
||||
scriptHelper: '编译之前执行的脚本,一般为下载模块源码,安装依赖等',
|
||||
buildHelper: '添加/修改模块之后点击构建,构建成功后会自动重启 OpenResty',
|
||||
},
|
||||
ssl: {
|
||||
create: '申请证书',
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
<template>
|
||||
<DrawerPro v-model="open" :header="$t('nginx.build')" size="normal" :back="handleClose">
|
||||
<el-form ref="buildForm" label-position="top" :model="build" :rules="rules">
|
||||
<el-form-item :label="$t('nginx.mirrorUrl')" prop="mirror">
|
||||
<el-select v-model="build.mirror">
|
||||
<el-option
|
||||
value="http://archive.ubuntu.com/ubuntu/"
|
||||
label="http://archive.ubuntu.com/ubuntu/"
|
||||
></el-option>
|
||||
<el-option
|
||||
value="http://mirrors.aliyun.com/ubuntu/"
|
||||
label="http://mirrors.aliyun.com/ubuntu/"
|
||||
></el-option>
|
||||
<el-option
|
||||
value="https://mirrors.tuna.tsinghua.edu.cn/ubuntu/"
|
||||
label="https://mirrors.tuna.tsinghua.edu.cn/ubuntu/"
|
||||
></el-option>
|
||||
<el-option
|
||||
value="https://mirrors.ustc.edu.cn/ubuntu/"
|
||||
label="https://mirrors.ustc.edu.cn/ubuntu/"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="handleClose" :disabled="loading">{{ $t('commons.button.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="submit(buildForm)" :disabled="loading">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</DrawerPro>
|
||||
<TaskLog ref="taskLogRef" />
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { FormInstance } from 'element-plus';
|
||||
import { GetNginxModules, BuildNginx } from '@/api/modules/nginx';
|
||||
import i18n from '@/lang';
|
||||
import { newUUID } from '@/utils/util';
|
||||
import TaskLog from '@/components/task-log/index.vue';
|
||||
import { Rules } from '@/global/form-rules';
|
||||
|
||||
const open = ref(false);
|
||||
const loading = ref(false);
|
||||
const buildForm = ref<FormInstance>();
|
||||
const build = ref({
|
||||
mirror: 'http://archive.ubuntu.com/ubuntu',
|
||||
});
|
||||
const rules = {
|
||||
mirror: [Rules.requiredSelect],
|
||||
};
|
||||
const taskLogRef = ref();
|
||||
|
||||
const acceptParams = async () => {
|
||||
getModules();
|
||||
open.value = true;
|
||||
};
|
||||
|
||||
const getModules = async () => {
|
||||
try {
|
||||
const res = await GetNginxModules();
|
||||
build.value.mirror = res.data.mirror;
|
||||
} catch (error) {}
|
||||
};
|
||||
|
||||
const submit = async (form: FormInstance) => {
|
||||
await form.validate();
|
||||
if (form.validate()) {
|
||||
ElMessageBox.confirm(i18n.global.t('nginx.buildWarn'), i18n.global.t('nginx.build'), {
|
||||
confirmButtonText: i18n.global.t('commons.button.confirm'),
|
||||
cancelButtonText: i18n.global.t('commons.button.cancel'),
|
||||
}).then(async () => {
|
||||
const taskID = newUUID();
|
||||
try {
|
||||
await BuildNginx({
|
||||
taskID: taskID,
|
||||
mirror: build.value.mirror,
|
||||
});
|
||||
openTaskLog(taskID);
|
||||
} catch (error) {}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const openTaskLog = (taskID: string) => {
|
||||
taskLogRef.value.openWithTaskID(taskID);
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
open.value = false;
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
acceptParams,
|
||||
});
|
||||
</script>
|
|
@ -4,40 +4,46 @@
|
|||
<template #toolbar>
|
||||
<el-button type="primary" @click="openOperate">{{ $t('commons.button.create') }}</el-button>
|
||||
<el-button type="primary" plain @click="buildNginx">{{ $t('nginx.build') }}</el-button>
|
||||
<el-text type="warning" class="!ml-2">{{ $t('nginx.buildHelper') }}</el-text>
|
||||
</template>
|
||||
<el-table-column prop="name" :label="$t('commons.table.name')" />
|
||||
<el-table-column prop="params" :label="$t('nginx.params')" />
|
||||
<el-table-column :label="$t('commons.table.status')" fix>
|
||||
<template #default="{ row }">
|
||||
<el-switch v-model="row.enable" />
|
||||
<el-switch v-model="row.enable" @click="updateModule(row)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<fu-table-operations
|
||||
:ellipsis="2"
|
||||
width="100px"
|
||||
width="200px"
|
||||
:buttons="buttons"
|
||||
:label="$t('commons.table.operate')"
|
||||
fixed="right"
|
||||
fix
|
||||
/>
|
||||
</ComplexTable>
|
||||
<TaskLog ref="taskLogRef" />
|
||||
<Operate ref="operateRef" @close="search" />
|
||||
<OpDialog ref="deleteRef" @search="search" @cancel="search" />
|
||||
<Build ref="buildRef" />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { BuildNginx, GetNginxModules, UpdateNginxModule } from '@/api/modules/nginx';
|
||||
import { newUUID } from '@/utils/util';
|
||||
import TaskLog from '@/components/task-log/index.vue';
|
||||
import Operate from './operate/index.vue';
|
||||
import { GetNginxModules, UpdateNginxModule } from '@/api/modules/nginx';
|
||||
import i18n from '@/lang';
|
||||
import { Nginx } from '@/api/interface/nginx';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import Operate from './operate/index.vue';
|
||||
import Build from './build/index.vue';
|
||||
|
||||
const taskLogRef = ref();
|
||||
const data = ref([]);
|
||||
const loading = ref(false);
|
||||
const buttons = [
|
||||
{
|
||||
label: i18n.global.t('commons.button.edit'),
|
||||
click: function (row: Nginx.NginxModule) {
|
||||
openEdit(row);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: i18n.global.t('commons.button.delete'),
|
||||
click: function (row: Nginx.NginxModule) {
|
||||
|
@ -47,39 +53,44 @@ const buttons = [
|
|||
];
|
||||
const operateRef = ref();
|
||||
const deleteRef = ref();
|
||||
const buildRef = ref();
|
||||
|
||||
const buildNginx = async () => {
|
||||
ElMessageBox.confirm(i18n.global.t('nginx.buildWarn'), i18n.global.t('nginx.build'), {
|
||||
confirmButtonText: i18n.global.t('commons.button.confirm'),
|
||||
cancelButtonText: i18n.global.t('commons.button.cancel'),
|
||||
}).then(async () => {
|
||||
const taskID = newUUID();
|
||||
try {
|
||||
await BuildNginx({
|
||||
taskID: taskID,
|
||||
});
|
||||
openTaskLog(taskID);
|
||||
} catch (error) {}
|
||||
});
|
||||
buildRef.value.acceptParams();
|
||||
};
|
||||
|
||||
const search = () => {
|
||||
loading.value = true;
|
||||
GetNginxModules()
|
||||
.then((res) => {
|
||||
data.value = res.data;
|
||||
data.value = res.data.modules;
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
const openTaskLog = (taskID: string) => {
|
||||
taskLogRef.value.openWithTaskID(taskID);
|
||||
const openOperate = () => {
|
||||
operateRef.value.acceptParams('create');
|
||||
};
|
||||
|
||||
const openOperate = () => {
|
||||
operateRef.value.acceptParams();
|
||||
const openEdit = (row: Nginx.NginxModule) => {
|
||||
operateRef.value.acceptParams('update', row);
|
||||
};
|
||||
|
||||
const updateModule = (row: Nginx.NginxModule) => {
|
||||
loading.value = true;
|
||||
const data = {
|
||||
...row,
|
||||
operate: 'update',
|
||||
};
|
||||
UpdateNginxModule(data)
|
||||
.then(() => {
|
||||
MsgSuccess(i18n.global.t('commons.msg.updateSuccess'));
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
const deleteModule = async (row: Nginx.NginxModule) => {
|
||||
|
|
|
@ -3,21 +3,26 @@
|
|||
v-model="open"
|
||||
:header="$t('nginx.' + mode)"
|
||||
size="large"
|
||||
:resource="mode === 'edit' ? module.name : ''"
|
||||
:resource="mode === 'update' ? module.name : ''"
|
||||
:back="handleClose"
|
||||
>
|
||||
<el-form ref="moduleForm" label-position="top" :model="module" :rules="rules">
|
||||
<el-form-item :label="$t('commons.table.name')" prop="name">
|
||||
<el-input v-model.trim="module.name" :disabled="mode === 'edit'"></el-input>
|
||||
<el-input v-model.trim="module.name" :disabled="mode === 'update'"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('nginx.params')" prop="params">
|
||||
<el-input v-model.trim="module.params"></el-input>
|
||||
<el-input v-model.trim="module.params" :placeholder="$t('nginx.paramsHelper')"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('nginx.packages')" prop="packages">
|
||||
<el-input v-model.trim="module.packages"></el-input>
|
||||
<el-input v-model.trim="module.packages" :placeholder="$t('nginx.packagesHelper')"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('nginx.script')" prop="script">
|
||||
<el-input v-model="module.script" type="textarea" :rows="10"></el-input>
|
||||
<el-input
|
||||
v-model="module.script"
|
||||
type="textarea"
|
||||
:rows="10"
|
||||
:placeholder="$t('nginx.scriptHelper')"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
|
@ -30,6 +35,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { Nginx } from '@/api/interface/nginx';
|
||||
import { UpdateNginxModule } from '@/api/modules/nginx';
|
||||
import { Rules } from '@/global/form-rules';
|
||||
import i18n from '@/lang';
|
||||
|
@ -59,7 +65,18 @@ const handleClose = () => {
|
|||
em('close', false);
|
||||
};
|
||||
|
||||
const acceptParams = async () => {
|
||||
const acceptParams = async (operate: string, editModule: Nginx.NginxModule) => {
|
||||
mode.value = operate;
|
||||
if (operate === 'update') {
|
||||
module.value = {
|
||||
name: editModule.name,
|
||||
script: editModule.script,
|
||||
enable: editModule.enable,
|
||||
params: editModule.params,
|
||||
packages: editModule.packages,
|
||||
operate: 'update',
|
||||
};
|
||||
}
|
||||
open.value = true;
|
||||
};
|
||||
|
||||
|
@ -73,7 +90,7 @@ const submit = async (form: FormInstance) => {
|
|||
};
|
||||
UpdateNginxModule(data)
|
||||
.then(() => {
|
||||
if (mode.value === 'edit') {
|
||||
if (mode.value === 'update') {
|
||||
MsgSuccess(i18n.global.t('commons.msg.updateSuccess'));
|
||||
} else if (mode.value === 'create') {
|
||||
MsgSuccess(i18n.global.t('commons.msg.createSuccess'));
|
||||
|
|
Loading…
Add table
Reference in a new issue