mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-31 14:08:06 +08:00
feat: 增加 PHP 相关配置修改功能
This commit is contained in:
parent
947293f34e
commit
5706de5ca7
@ -71,8 +71,8 @@ func (b *BaseApi) GetApp(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// @Tags App
|
// @Tags App
|
||||||
// @Summary Search app detail by id
|
// @Summary Search app detail by appid
|
||||||
// @Description 通过 id 获取应用详情
|
// @Description 通过 appid 获取应用详情
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param appId path integer true "app id"
|
// @Param appId path integer true "app id"
|
||||||
// @Param version path string true "app 版本"
|
// @Param version path string true "app 版本"
|
||||||
@ -97,13 +97,13 @@ func (b *BaseApi) GetAppDetail(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// @Tags App
|
// @Tags App
|
||||||
// @Summary Search app detail by id
|
// @Summary Get app detail by id
|
||||||
// @Description 通过 id 获取应用详情
|
// @Description 通过 id 获取应用详情
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param appId path integer true "id"
|
// @Param appId path integer true "id"
|
||||||
// @Success 200 {object} response.AppDetailDTO
|
// @Success 200 {object} response.AppDetailDTO
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Router /apps/detail/:id[get]
|
// @Router /apps/details/:id [get]
|
||||||
func (b *BaseApi) GetAppDetailByID(c *gin.Context) {
|
func (b *BaseApi) GetAppDetailByID(c *gin.Context) {
|
||||||
appDetailID, err := helper.GetIntParamByKey(c, "id")
|
appDetailID, err := helper.GetIntParamByKey(c, "id")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -498,3 +498,47 @@ func (b *BaseApi) ChangeDefaultServer(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
helper.SuccessWithData(c, nil)
|
helper.SuccessWithData(c, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Website
|
||||||
|
// @Summary Load websit php conf
|
||||||
|
// @Description 获取网站 php 配置
|
||||||
|
// @Accept json
|
||||||
|
// @Param id path integer true "request"
|
||||||
|
// @Success 200 {object} response.PHPConfig
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Router /websites/php/config/:id [get]
|
||||||
|
func (b *BaseApi) GetWebsitePHPConfig(c *gin.Context) {
|
||||||
|
id, err := helper.GetParamID(c)
|
||||||
|
if err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInternalServer, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
data, err := websiteService.GetPHPConfig(id)
|
||||||
|
if err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Website PHP
|
||||||
|
// @Summary Update website php conf
|
||||||
|
// @Description 更新 网站 PHP 配置
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.WebsitePHPConfigUpdate true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Router /websites/php/update [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"websites","output_colume":"primary_domain","output_value":"domain"}],"formatZH":"[domain] PHP 配置修改","formatEN":"[domain] PHP conf update"}
|
||||||
|
func (b *BaseApi) UpdateWebsitePHPConfig(c *gin.Context) {
|
||||||
|
var req request.WebsitePHPConfigUpdate
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := websiteService.UpdatePHPConfig(req); err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, nil)
|
||||||
|
}
|
||||||
|
@ -4,8 +4,9 @@ import "github.com/1Panel-dev/1Panel/backend/app/dto"
|
|||||||
|
|
||||||
type RuntimeSearch struct {
|
type RuntimeSearch struct {
|
||||||
dto.PageInfo
|
dto.PageInfo
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
Status string `json:"status"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type RuntimeCreate struct {
|
type RuntimeCreate struct {
|
||||||
|
@ -134,3 +134,8 @@ type WebsiteLogReq struct {
|
|||||||
type WebsiteDefaultUpdate struct {
|
type WebsiteDefaultUpdate struct {
|
||||||
ID uint `json:"id" validate:"required"`
|
ID uint `json:"id" validate:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type WebsitePHPConfigUpdate struct {
|
||||||
|
ID uint `json:"id" validate:"required"`
|
||||||
|
Params map[string]string `json:"params" validate:"required"`
|
||||||
|
}
|
||||||
|
@ -42,3 +42,7 @@ type WebsiteLog struct {
|
|||||||
Enable bool `json:"enable"`
|
Enable bool `json:"enable"`
|
||||||
Content string `json:"content"`
|
Content string `json:"content"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PHPConfig struct {
|
||||||
|
Params map[string]string `json:"params"`
|
||||||
|
}
|
||||||
|
@ -23,7 +23,7 @@ type IAppInstallRepo interface {
|
|||||||
ListBy(opts ...DBOption) ([]model.AppInstall, error)
|
ListBy(opts ...DBOption) ([]model.AppInstall, error)
|
||||||
GetFirst(opts ...DBOption) (model.AppInstall, error)
|
GetFirst(opts ...DBOption) (model.AppInstall, error)
|
||||||
Create(ctx context.Context, install *model.AppInstall) error
|
Create(ctx context.Context, install *model.AppInstall) error
|
||||||
Save(install *model.AppInstall) error
|
Save(ctx context.Context, install *model.AppInstall) error
|
||||||
DeleteBy(opts ...DBOption) error
|
DeleteBy(opts ...DBOption) error
|
||||||
Delete(ctx context.Context, install model.AppInstall) error
|
Delete(ctx context.Context, install model.AppInstall) error
|
||||||
Page(page, size int, opts ...DBOption) (int64, []model.AppInstall, error)
|
Page(page, size int, opts ...DBOption) (int64, []model.AppInstall, error)
|
||||||
@ -110,8 +110,8 @@ func (a *AppInstallRepo) Create(ctx context.Context, install *model.AppInstall)
|
|||||||
return db.Create(&install).Error
|
return db.Create(&install).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AppInstallRepo) Save(install *model.AppInstall) error {
|
func (a *AppInstallRepo) Save(ctx context.Context, install *model.AppInstall) error {
|
||||||
return getDb().Save(&install).Error
|
return getTx(ctx).Save(&install).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AppInstallRepo) DeleteBy(opts ...DBOption) error {
|
func (a *AppInstallRepo) DeleteBy(opts ...DBOption) error {
|
||||||
|
@ -13,6 +13,7 @@ type IRuntimeRepo interface {
|
|||||||
WithName(name string) DBOption
|
WithName(name string) DBOption
|
||||||
WithImage(image string) DBOption
|
WithImage(image string) DBOption
|
||||||
WithNotId(id uint) DBOption
|
WithNotId(id uint) DBOption
|
||||||
|
WithStatus(status string) DBOption
|
||||||
Page(page, size int, opts ...DBOption) (int64, []model.Runtime, error)
|
Page(page, size int, opts ...DBOption) (int64, []model.Runtime, error)
|
||||||
Create(ctx context.Context, runtime *model.Runtime) error
|
Create(ctx context.Context, runtime *model.Runtime) error
|
||||||
Save(runtime *model.Runtime) error
|
Save(runtime *model.Runtime) error
|
||||||
@ -30,6 +31,12 @@ func (r *RuntimeRepo) WithName(name string) DBOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *RuntimeRepo) WithStatus(status string) DBOption {
|
||||||
|
return func(g *gorm.DB) *gorm.DB {
|
||||||
|
return g.Where("status = ?", status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (r *RuntimeRepo) WithImage(image string) DBOption {
|
func (r *RuntimeRepo) WithImage(image string) DBOption {
|
||||||
return func(g *gorm.DB) *gorm.DB {
|
return func(g *gorm.DB) *gorm.DB {
|
||||||
return g.Where("image = ?", image)
|
return g.Where("image = ?", image)
|
||||||
|
@ -17,6 +17,7 @@ type IWebsiteRepo interface {
|
|||||||
WithGroupID(groupId uint) DBOption
|
WithGroupID(groupId uint) DBOption
|
||||||
WithDefaultServer() DBOption
|
WithDefaultServer() DBOption
|
||||||
WithDomainLike(domain string) DBOption
|
WithDomainLike(domain string) DBOption
|
||||||
|
WithRuntimeID(runtimeID uint) DBOption
|
||||||
Page(page, size int, opts ...DBOption) (int64, []model.Website, error)
|
Page(page, size int, opts ...DBOption) (int64, []model.Website, error)
|
||||||
List(opts ...DBOption) ([]model.Website, error)
|
List(opts ...DBOption) ([]model.Website, error)
|
||||||
GetFirst(opts ...DBOption) (model.Website, error)
|
GetFirst(opts ...DBOption) (model.Website, error)
|
||||||
@ -40,6 +41,12 @@ func (w *WebsiteRepo) WithAppInstallId(appInstallId uint) DBOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *WebsiteRepo) WithRuntimeID(runtimeID uint) DBOption {
|
||||||
|
return func(db *gorm.DB) *gorm.DB {
|
||||||
|
return db.Where("runtime_id = ?", runtimeID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (w *WebsiteRepo) WithDomain(domain string) DBOption {
|
func (w *WebsiteRepo) WithDomain(domain string) DBOption {
|
||||||
return func(db *gorm.DB) *gorm.DB {
|
return func(db *gorm.DB) *gorm.DB {
|
||||||
return db.Where("primary_domain = ?", domain)
|
return db.Where("primary_domain = ?", domain)
|
||||||
|
@ -316,7 +316,7 @@ func (a AppService) Install(ctx context.Context, req request.AppInstallCreate) (
|
|||||||
if err := upAppPre(app, appInstall); err != nil {
|
if err := upAppPre(app, appInstall); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
go upApp(appInstall.GetComposePath(), appInstall)
|
go upApp(ctx, appInstall.GetComposePath(), appInstall)
|
||||||
go updateToolApp(appInstall)
|
go updateToolApp(appInstall)
|
||||||
return &appInstall, nil
|
return &appInstall, nil
|
||||||
}
|
}
|
||||||
|
@ -260,7 +260,7 @@ func (a *AppInstallService) Update(req request.AppInstalledUpdate) error {
|
|||||||
if err := env.Write(oldEnvMaps, envPath); err != nil {
|
if err := env.Write(oldEnvMaps, envPath); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_ = appInstallRepo.Save(&installed)
|
_ = appInstallRepo.Save(context.Background(), &installed)
|
||||||
|
|
||||||
if err := rebuildApp(installed); err != nil {
|
if err := rebuildApp(installed); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -300,7 +300,7 @@ func (a *AppInstallService) SyncAll(systemInit bool) error {
|
|||||||
if systemInit {
|
if systemInit {
|
||||||
i.Status = constant.Error
|
i.Status = constant.Error
|
||||||
i.Message = "System restart causes application exception"
|
i.Message = "System restart causes application exception"
|
||||||
_ = appInstallRepo.Save(&i)
|
_ = appInstallRepo.Save(context.Background(), &i)
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -569,15 +569,15 @@ func syncById(installId uint) error {
|
|||||||
if containerCount == 0 {
|
if containerCount == 0 {
|
||||||
appInstall.Status = constant.Error
|
appInstall.Status = constant.Error
|
||||||
appInstall.Message = "container is not found"
|
appInstall.Message = "container is not found"
|
||||||
return appInstallRepo.Save(&appInstall)
|
return appInstallRepo.Save(context.Background(), &appInstall)
|
||||||
}
|
}
|
||||||
if errCount == 0 && existedCount == 0 {
|
if errCount == 0 && existedCount == 0 {
|
||||||
appInstall.Status = constant.Running
|
appInstall.Status = constant.Running
|
||||||
return appInstallRepo.Save(&appInstall)
|
return appInstallRepo.Save(context.Background(), &appInstall)
|
||||||
}
|
}
|
||||||
if existedCount == normalCount {
|
if existedCount == normalCount {
|
||||||
appInstall.Status = constant.Stopped
|
appInstall.Status = constant.Stopped
|
||||||
return appInstallRepo.Save(&appInstall)
|
return appInstallRepo.Save(context.Background(), &appInstall)
|
||||||
}
|
}
|
||||||
if errCount == normalCount {
|
if errCount == normalCount {
|
||||||
appInstall.Status = constant.Error
|
appInstall.Status = constant.Error
|
||||||
@ -602,7 +602,7 @@ func syncById(installId uint) error {
|
|||||||
errMsg.Write([]byte("\n"))
|
errMsg.Write([]byte("\n"))
|
||||||
}
|
}
|
||||||
appInstall.Message = errMsg.String()
|
appInstall.Message = errMsg.String()
|
||||||
return appInstallRepo.Save(&appInstall)
|
return appInstallRepo.Save(context.Background(), &appInstall)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateInstallInfoInDB(appKey, appName, param string, isRestart bool, value interface{}) error {
|
func updateInstallInfoInDB(appKey, appName, param string, isRestart bool, value interface{}) error {
|
||||||
|
@ -239,7 +239,7 @@ func updateInstall(installId uint, detailId uint) error {
|
|||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return appInstallRepo.Save(&install)
|
return appInstallRepo.Save(context.Background(), &install)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getContainerNames(install model.AppInstall) ([]string, error) {
|
func getContainerNames(install model.AppInstall) ([]string, error) {
|
||||||
@ -381,7 +381,7 @@ func upAppPre(app model.App, appInstall model.AppInstall) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func upApp(composeFilePath string, appInstall model.AppInstall) {
|
func upApp(ctx context.Context, composeFilePath string, appInstall model.AppInstall) {
|
||||||
out, err := compose.Up(composeFilePath)
|
out, err := compose.Up(composeFilePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if out != "" {
|
if out != "" {
|
||||||
@ -390,10 +390,10 @@ func upApp(composeFilePath string, appInstall model.AppInstall) {
|
|||||||
appInstall.Message = err.Error()
|
appInstall.Message = err.Error()
|
||||||
}
|
}
|
||||||
appInstall.Status = constant.Error
|
appInstall.Status = constant.Error
|
||||||
_ = appInstallRepo.Save(&appInstall)
|
_ = appInstallRepo.Save(ctx, &appInstall)
|
||||||
} else {
|
} else {
|
||||||
appInstall.Status = constant.Running
|
appInstall.Status = constant.Running
|
||||||
_ = appInstallRepo.Save(&appInstall)
|
_ = appInstallRepo.Save(ctx, &appInstall)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -468,7 +468,7 @@ func handleErr(install model.AppInstall, err error, out string) error {
|
|||||||
reErr = errors.New(out)
|
reErr = errors.New(out)
|
||||||
install.Status = constant.Error
|
install.Status = constant.Error
|
||||||
}
|
}
|
||||||
_ = appInstallRepo.Save(&install)
|
_ = appInstallRepo.Save(context.Background(), &install)
|
||||||
return reErr
|
return reErr
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -579,7 +579,7 @@ func updateToolApp(installed model.AppInstall) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
toolInstall.Env = string(contentByte)
|
toolInstall.Env = string(contentByte)
|
||||||
if err := appInstallRepo.Save(&toolInstall); err != nil {
|
if err := appInstallRepo.Save(context.Background(), &toolInstall); err != nil {
|
||||||
global.LOG.Errorf("update tool app [%s] error : %s", toolInstall.Name, err.Error())
|
global.LOG.Errorf("update tool app [%s] error : %s", toolInstall.Name, err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
@ -192,7 +193,7 @@ func handleAppRecover(install *model.AppInstall, recoverFile string, isRollback
|
|||||||
}
|
}
|
||||||
|
|
||||||
oldInstall.Status = constant.Running
|
oldInstall.Status = constant.Running
|
||||||
if err := appInstallRepo.Save(install); err != nil {
|
if err := appInstallRepo.Save(context.Background(), install); err != nil {
|
||||||
global.LOG.Errorf("save db app install failed, err: %v", err)
|
global.LOG.Errorf("save db app install failed, err: %v", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -121,6 +121,9 @@ func (r *RuntimeService) Page(req request.RuntimeSearch) (int64, []response.Runt
|
|||||||
if req.Name != "" {
|
if req.Name != "" {
|
||||||
opts = append(opts, commonRepo.WithLikeName(req.Name))
|
opts = append(opts, commonRepo.WithLikeName(req.Name))
|
||||||
}
|
}
|
||||||
|
if req.Status != "" {
|
||||||
|
opts = append(opts, runtimeRepo.WithStatus(req.Status))
|
||||||
|
}
|
||||||
total, runtimes, err := runtimeRepo.Page(req.Page, req.PageSize, opts...)
|
total, runtimes, err := runtimeRepo.Page(req.Page, req.PageSize, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, nil, err
|
return 0, nil, err
|
||||||
@ -138,7 +141,10 @@ func (r *RuntimeService) Delete(id uint) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
//TODO 校验网站关联
|
website, _ := websiteRepo.GetFirst(websiteRepo.WithRuntimeID(id))
|
||||||
|
if website.ID > 0 {
|
||||||
|
return buserr.New(constant.ErrDelWithWebsite)
|
||||||
|
}
|
||||||
//TODO 删除镜像
|
//TODO 删除镜像
|
||||||
if runtime.Resource == constant.ResourceAppstore {
|
if runtime.Resource == constant.ResourceAppstore {
|
||||||
runtimeDir := path.Join(constant.RuntimeDir, runtime.Type, runtime.Name)
|
runtimeDir := path.Join(constant.RuntimeDir, runtime.Type, runtime.Name)
|
||||||
@ -193,7 +199,11 @@ func (r *RuntimeService) Get(id uint) (*response.RuntimeRes, error) {
|
|||||||
appParam.Value = v
|
appParam.Value = v
|
||||||
if form.Type == "select" {
|
if form.Type == "select" {
|
||||||
if form.Multiple {
|
if form.Multiple {
|
||||||
appParam.Value = strings.Split(v, ",")
|
if v == "" {
|
||||||
|
appParam.Value = []string{}
|
||||||
|
} else {
|
||||||
|
appParam.Value = strings.Split(v, ",")
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
for _, fv := range form.Values {
|
for _, fv := range form.Values {
|
||||||
if fv.Value == v {
|
if fv.Value == v {
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"context"
|
"context"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/utils/common"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"reflect"
|
"reflect"
|
||||||
@ -52,6 +54,8 @@ type IWebsiteService interface {
|
|||||||
UpdateNginxConfigFile(req request.WebsiteNginxUpdate) error
|
UpdateNginxConfigFile(req request.WebsiteNginxUpdate) error
|
||||||
OpWebsiteLog(req request.WebsiteLogReq) (*response.WebsiteLog, error)
|
OpWebsiteLog(req request.WebsiteLogReq) (*response.WebsiteLog, error)
|
||||||
ChangeDefaultServer(id uint) error
|
ChangeDefaultServer(id uint) error
|
||||||
|
GetPHPConfig(id uint) (*response.PHPConfig, error)
|
||||||
|
UpdatePHPConfig(req request.WebsitePHPConfigUpdate) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewIWebsiteService() IWebsiteService {
|
func NewIWebsiteService() IWebsiteService {
|
||||||
@ -180,6 +184,9 @@ func (w WebsiteService) CreateWebsite(ctx context.Context, create request.Websit
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if common.ScanPort(create.Port) {
|
||||||
|
return buserr.WithDetail(constant.ErrPortInUsed, create.Port, nil)
|
||||||
|
}
|
||||||
if runtime.Resource == constant.ResourceAppstore {
|
if runtime.Resource == constant.ResourceAppstore {
|
||||||
var req request.AppInstallCreate
|
var req request.AppInstallCreate
|
||||||
reg, _ := regexp.Compile("[^a-z0-9_\\-]+")
|
reg, _ := regexp.Compile("[^a-z0-9_\\-]+")
|
||||||
@ -826,3 +833,86 @@ func (w WebsiteService) ChangeDefaultServer(id uint) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w WebsiteService) GetPHPConfig(id uint) (*response.PHPConfig, error) {
|
||||||
|
website, err := websiteRepo.GetFirst(commonRepo.WithByID(id))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
appInstall, err := appInstallRepo.GetFirst(commonRepo.WithByID(website.AppInstallID))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
phpConfigPath := path.Join(appInstall.GetPath(), "conf", "php.ini")
|
||||||
|
fileOp := files.NewFileOp()
|
||||||
|
if !fileOp.Stat(phpConfigPath) {
|
||||||
|
return nil, buserr.WithDetail(constant.ErrFileCanNotRead, "php.ini", nil)
|
||||||
|
}
|
||||||
|
params := make(map[string]string)
|
||||||
|
configFile, err := fileOp.OpenFile(phpConfigPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer configFile.Close()
|
||||||
|
scanner := bufio.NewScanner(configFile)
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := strings.TrimSpace(scanner.Text())
|
||||||
|
if strings.HasPrefix(line, ";") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
matches := regexp.MustCompile(`^\s*([a-z_]+)\s*=\s*(.*)$`).FindStringSubmatch(line)
|
||||||
|
if len(matches) == 3 {
|
||||||
|
params[matches[1]] = matches[2]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &response.PHPConfig{Params: params}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w WebsiteService) UpdatePHPConfig(req request.WebsitePHPConfigUpdate) (err error) {
|
||||||
|
website, err := websiteRepo.GetFirst(commonRepo.WithByID(req.ID))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
appInstall, err := appInstallRepo.GetFirst(commonRepo.WithByID(website.AppInstallID))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
phpConfigPath := path.Join(appInstall.GetPath(), "conf", "php.ini")
|
||||||
|
fileOp := files.NewFileOp()
|
||||||
|
if !fileOp.Stat(phpConfigPath) {
|
||||||
|
return buserr.WithDetail(constant.ErrFileCanNotRead, "php.ini", nil)
|
||||||
|
}
|
||||||
|
configFile, err := fileOp.OpenFile(phpConfigPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer configFile.Close()
|
||||||
|
|
||||||
|
contentBytes, err := fileOp.GetContent(phpConfigPath)
|
||||||
|
content := string(contentBytes)
|
||||||
|
lines := strings.Split(content, "\n")
|
||||||
|
for i, line := range lines {
|
||||||
|
if strings.HasPrefix(line, ";") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for key, value := range req.Params {
|
||||||
|
pattern := "^" + regexp.QuoteMeta(key) + "\\s*=\\s*.*$"
|
||||||
|
if matched, _ := regexp.MatchString(pattern, line); matched {
|
||||||
|
lines[i] = key + " = " + value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updatedContent := strings.Join(lines, "\n")
|
||||||
|
if err := fileOp.WriteFile(phpConfigPath, strings.NewReader(updatedContent), 0755); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
appInstallReq := request.AppInstalledOperate{
|
||||||
|
InstallId: appInstall.ID,
|
||||||
|
Operate: constant.Restart,
|
||||||
|
}
|
||||||
|
if err = NewIAppInstalledService().Operate(context.Background(), appInstallReq); err != nil {
|
||||||
|
_ = fileOp.WriteFile(phpConfigPath, strings.NewReader(string(contentBytes)), 0755)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -106,8 +106,9 @@ var (
|
|||||||
|
|
||||||
// runtime
|
// runtime
|
||||||
var (
|
var (
|
||||||
ErrDirNotFound = "ErrDirNotFound"
|
ErrDirNotFound = "ErrDirNotFound"
|
||||||
ErrFileNotExist = "ErrFileNotExist"
|
ErrFileNotExist = "ErrFileNotExist"
|
||||||
ErrImageBuildErr = "ErrImageBuildErr"
|
ErrImageBuildErr = "ErrImageBuildErr"
|
||||||
ErrImageExist = "ErrImageExist"
|
ErrImageExist = "ErrImageExist"
|
||||||
|
ErrDelWithWebsite = "ErrDelWithWebsite"
|
||||||
)
|
)
|
||||||
|
@ -64,4 +64,5 @@ ErrObjectInUsed: "This object is in use and cannot be deleted"
|
|||||||
ErrDirNotFound: "The build folder does not exist! Please check file integrity!"
|
ErrDirNotFound: "The build folder does not exist! Please check file integrity!"
|
||||||
ErrFileNotExist: "{{ .detail }} file does not exist! Please check source file integrity!"
|
ErrFileNotExist: "{{ .detail }} file does not exist! Please check source file integrity!"
|
||||||
ErrImageBuildErr: "Image build failed"
|
ErrImageBuildErr: "Image build failed"
|
||||||
ErrImageExist: "Image is already exist!"
|
ErrImageExist: "Image is already exist!"
|
||||||
|
ErrDelWithWebsite: "The operating environment has been associated with a website and cannot be deleted"
|
@ -64,4 +64,5 @@ ErrObjectInUsed: "该对象正被使用,无法删除"
|
|||||||
ErrDirNotFound: "build 文件夹不存在!请检查文件完整性!"
|
ErrDirNotFound: "build 文件夹不存在!请检查文件完整性!"
|
||||||
ErrFileNotExist: "{{ .detail }} 文件不存在!请检查源文件完整性!"
|
ErrFileNotExist: "{{ .detail }} 文件不存在!请检查源文件完整性!"
|
||||||
ErrImageBuildErr: "镜像 build 失败"
|
ErrImageBuildErr: "镜像 build 失败"
|
||||||
ErrImageExist: "镜像已存在!"
|
ErrImageExist: "镜像已存在!"
|
||||||
|
ErrDelWithWebsite: "运行环境已经关联网站,无法删除"
|
@ -41,5 +41,8 @@ func (a *WebsiteRouter) InitWebsiteRouter(Router *gin.RouterGroup) {
|
|||||||
|
|
||||||
groupRouter.POST("/waf/config", baseApi.GetWebsiteWafConfig)
|
groupRouter.POST("/waf/config", baseApi.GetWebsiteWafConfig)
|
||||||
groupRouter.POST("/waf/update", baseApi.UpdateWebsiteWafConfig)
|
groupRouter.POST("/waf/update", baseApi.UpdateWebsiteWafConfig)
|
||||||
|
|
||||||
|
groupRouter.GET("/php/config/:id", baseApi.GetWebsitePHPConfig)
|
||||||
|
groupRouter.POST("/php/config", baseApi.UpdateWebsitePHPConfig)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
-----BEGIN privateKey-----
|
|
||||||
MIIEoAIBAAKCAQEAvZRFbJcXQSIyhfbl9ZiulTgwFUNsqO3YOZgpRa0T0dgbg6BO
|
|
||||||
0nnPvlcZvR8TcdDc1B/kplps3O9QkV2d8AzutYWOG/TkZ8ywVuwni1yWqfyy7msV
|
|
||||||
GyhAqNI2lE6AMY5QJ7/GXX7vuN2jwUWBKSjYTXhyyWOMXmeijI0j3FPCtCN6G9x6
|
|
||||||
+oV0chtNTtDpz1lOw7g+b7cVqDD0MKMaFMl5EhbjSkw5E0GDPLIYRmctXRdFBTow
|
|
||||||
UcPxpMM0yuKksLROUccLRUIazHi+19HTlVx7sPYCTrFhh0N4xuPrv0pyfBUWInE0
|
|
||||||
Yza2ESpym6AlQLzSpOQji9IKdh8uIAZyShpFgwIDAQABAoIBAAzkjYgiCmHSmo8D
|
|
||||||
yIXYWV8qkBKSIEyoyEC6eWwUpjlqMgzUlSe5QwiV0dlLyL2/z5TZimpJ0geAewE3
|
|
||||||
1aripkVQDOcX04S/pepzawkORezPk7elLq1HIoaYrT+OyycTn53ka/Al1tXCtQVK
|
|
||||||
3crXzUYPf/b0PzKYZ7SZUKwGQkKP3QoHfFB+zVr0ZczHhWhdyk3rqNbblVR0OPJE
|
|
||||||
QCDQRqe7pS2wxs2Br3lNUnCqHqThtRu2sQK3UTBRP37AxrRd+gplB+QS+vPpgIFs
|
|
||||||
kVEoOdtuox7U5OOHj3WwhDosMLvXgK359g30olVL7ZTuLregFwhaidZcF4fI8A69
|
|
||||||
MX0YyLkCgYEAy4MQNELXWFJpTwova/RFEnczdP34rtcg/Z5Zvwq6Th4SbbMrVudM
|
|
||||||
BGEUVUHQbV4unD6T722FtQhfLrQXxgrLlHu7KkcnkciQd6iZCStAAH+XpnVvlj6k
|
|
||||||
THvnJxN1H1b4kimsxTuc+/96BqkpkHnbb0KBbHPdz3rGKtWKfIYBRhcCgYEA7nlK
|
|
||||||
vAGnOdVFKa5MPkdWeuwym3bjjZXBQB7/aRucqt3URi9XTl4/EwxHGmGpzTTSmpCN
|
|
||||||
+SDg5+lGVtivyk6QiRuKvhB9uohj3C6krHKjZtJz+ydtzrSi6DcAGrsWdu1EsSXR
|
|
||||||
s1aLhetrrPmKpayzK6TsUzcW3yVdgIYXFhY3y3UCfzR3lbXjhaE/nebCuXcbgrNA
|
|
||||||
CAQhdfudeuPn7ztRiLabCiU+C+5bsz1tydAxJ4sKvPmLKJiRo+cIQYHI7FgicFnX
|
|
||||||
jGlZ7tmm25f933Z9sAJw4qgHnr0daT5Os0lfutJZmbwVAnXW6KIPO2Z8NjsJL4l/
|
|
||||||
m95aANV80Zo5c3qnEa0CgYBvw8Ll6DRyo2Sdy0WKbq62P5rcR9UQF16R6bU0kq9T
|
|
||||||
WVHSbv+RCBSxnbB5ScpmFVqa/CK93s3pgufnbfi9bSLKT3Ev8NSsJp3+pJGjDLtO
|
|
||||||
RlX7IJiTJw+um5Bd9s7pf/wQtjPYxDfx1MsLL4zuZsk2LD5iJdB/VqjCwpVxUYpm
|
|
||||||
vQKBgFtmL0pSbd6433YwY+vR5sZ8uMSXqaS9imisW42fAj7v3W1Td0yi1WwNTNqr
|
|
||||||
zXQVMspNVBXf5fyzh8gAW4gzD7JLBsxA5sr4gPFpxwJTfbvrIR0K8jr+1yxviGAb
|
|
||||||
eJcEigsnUfhZrVEa1am+mRaumjkZBdS+xCClS7auY2raxQ5x
|
|
||||||
-----END privateKey-----
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -16,6 +16,7 @@ export namespace Runtime {
|
|||||||
|
|
||||||
export interface RuntimeReq extends ReqPage {
|
export interface RuntimeReq extends ReqPage {
|
||||||
name?: string;
|
name?: string;
|
||||||
|
status?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RuntimeDTO extends Runtime {
|
export interface RuntimeDTO extends Runtime {
|
||||||
|
@ -261,4 +261,13 @@ export namespace Website {
|
|||||||
export interface DefaultServerUpdate {
|
export interface DefaultServerUpdate {
|
||||||
id: number;
|
id: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface PHPConfig {
|
||||||
|
params: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PHPConfigUpdate {
|
||||||
|
id: number;
|
||||||
|
params: any;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -158,3 +158,11 @@ export const UpdateNginxFile = (req: Website.NginxUpdate) => {
|
|||||||
export const ChangeDefaultServer = (req: Website.DefaultServerUpdate) => {
|
export const ChangeDefaultServer = (req: Website.DefaultServerUpdate) => {
|
||||||
return http.post<any>(`/websites/default/server`, req);
|
return http.post<any>(`/websites/default/server`, req);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const GetPHPConfig = (id: number) => {
|
||||||
|
return http.get<Website.PHPConfig>(`/websites/php/config/${id}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const UpdatePHPConfig = (req: Website.PHPConfigUpdate) => {
|
||||||
|
return http.post<any>(`/websites/php/config/`, req);
|
||||||
|
};
|
||||||
|
@ -1141,6 +1141,25 @@ const message = {
|
|||||||
tcp: 'TCP/IP 网络',
|
tcp: 'TCP/IP 网络',
|
||||||
phpFPM: 'FPM 配置文件',
|
phpFPM: 'FPM 配置文件',
|
||||||
phpConfig: 'PHP 配置文件',
|
phpConfig: 'PHP 配置文件',
|
||||||
|
updateConfig: '配置修改',
|
||||||
|
isOn: '开启',
|
||||||
|
isOff: '关闭',
|
||||||
|
},
|
||||||
|
php: {
|
||||||
|
short_open_tag: '短标签支持',
|
||||||
|
max_execution_time: '最大脚本运行时间',
|
||||||
|
max_input_time: '最大输入时间',
|
||||||
|
memory_limit: ' 脚本内存限制',
|
||||||
|
post_max_size: 'POST数据最大尺寸',
|
||||||
|
file_uploads: '是否允许上传文件',
|
||||||
|
upload_max_filesize: '允许上传文件的最大尺寸',
|
||||||
|
max_file_uploads: '允许同时上传文件的最大数量',
|
||||||
|
default_socket_timeout: 'Socket超时时间',
|
||||||
|
error_reporting: '错误级别',
|
||||||
|
display_errors: '是否输出详细错误信息',
|
||||||
|
cgi_fix_pathinfo: '是否开启pathinfo',
|
||||||
|
date_timezone: '时区',
|
||||||
|
second: '秒',
|
||||||
},
|
},
|
||||||
nginx: {
|
nginx: {
|
||||||
serverNamesHashBucketSizeHelper: '服务器名字的hash表大小',
|
serverNamesHashBucketSizeHelper: '服务器名字的hash表大小',
|
||||||
|
@ -30,12 +30,16 @@
|
|||||||
<el-button type="primary" :plain="index !== 'resource'" @click="changeTab('resource')">
|
<el-button type="primary" :plain="index !== 'resource'" @click="changeTab('resource')">
|
||||||
{{ $t('website.source') }}
|
{{ $t('website.source') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
<el-button type="primary" v-if="configPHP" :plain="index !== 'php'" @click="changeTab('php')">
|
||||||
|
PHP
|
||||||
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
<template #main>
|
<template #main>
|
||||||
<Basic :id="id" v-if="index === 'basic'"></Basic>
|
<Basic :id="id" v-if="index === 'basic'"></Basic>
|
||||||
<Safety :id="id" v-if="index === 'safety'"></Safety>
|
<Safety :id="id" v-if="index === 'safety'"></Safety>
|
||||||
<Log :id="id" v-if="index === 'log'"></Log>
|
<Log :id="id" v-if="index === 'log'"></Log>
|
||||||
<Resource :id="id" v-if="index === 'resource'"></Resource>
|
<Resource :id="id" v-if="index === 'resource'"></Resource>
|
||||||
|
<PHP :id="id" v-if="index === 'php'"></PHP>
|
||||||
</template>
|
</template>
|
||||||
</LayoutContent>
|
</LayoutContent>
|
||||||
</div>
|
</div>
|
||||||
@ -48,9 +52,11 @@ import Basic from './basic/index.vue';
|
|||||||
import Safety from './safety/index.vue';
|
import Safety from './safety/index.vue';
|
||||||
import Resource from './resource/index.vue';
|
import Resource from './resource/index.vue';
|
||||||
import Log from './log/index.vue';
|
import Log from './log/index.vue';
|
||||||
|
import PHP from './php/index.vue';
|
||||||
import router from '@/routers';
|
import router from '@/routers';
|
||||||
import WebsiteStatus from '@/views/website/website/status/index.vue';
|
import WebsiteStatus from '@/views/website/website/status/index.vue';
|
||||||
import { GetWebsite } from '@/api/modules/website';
|
import { GetWebsite } from '@/api/modules/website';
|
||||||
|
import { GetRuntime } from '@/api/modules/runtime';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
id: {
|
id: {
|
||||||
@ -67,6 +73,7 @@ let id = ref(0);
|
|||||||
let index = ref('basic');
|
let index = ref('basic');
|
||||||
let website = ref<any>({});
|
let website = ref<any>({});
|
||||||
let loading = ref(false);
|
let loading = ref(false);
|
||||||
|
const configPHP = ref(false);
|
||||||
|
|
||||||
watch(index, (curr, old) => {
|
watch(index, (curr, old) => {
|
||||||
if (curr != old) {
|
if (curr != old) {
|
||||||
@ -83,8 +90,14 @@ onMounted(() => {
|
|||||||
id.value = Number(props.id);
|
id.value = Number(props.id);
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
GetWebsite(id.value)
|
GetWebsite(id.value)
|
||||||
.then((res) => {
|
.then(async (res) => {
|
||||||
website.value = res.data;
|
website.value = res.data;
|
||||||
|
if (res.data.type === 'runtime') {
|
||||||
|
const runRes = await GetRuntime(res.data.runtimeID);
|
||||||
|
if (runRes.data.resource === 'appstore') {
|
||||||
|
configPHP.value = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
|
199
frontend/src/views/website/website/config/php/config/index.vue
Normal file
199
frontend/src/views/website/website/config/php/config/index.vue
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
<template>
|
||||||
|
<div v-loading="loading">
|
||||||
|
<el-form :model="form" :rules="variablesRules" ref="phpFormRef" label-position="top">
|
||||||
|
<el-row v-loading="loading">
|
||||||
|
<el-col :span="1"><br /></el-col>
|
||||||
|
<el-col :span="9">
|
||||||
|
<el-form-item label="short_open_tag" prop="short_open_tag">
|
||||||
|
<el-select v-model="form.short_open_tag">
|
||||||
|
<el-option :label="$t('website.isOff')" :value="'Off'"></el-option>
|
||||||
|
<el-option :label="$t('website.isOn')" :value="'On'"></el-option>
|
||||||
|
</el-select>
|
||||||
|
<span class="input-help">{{ $t('php.short_open_tag') }}</span>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="max_execution_time" prop="max_execution_time">
|
||||||
|
<el-input clearable v-model.number="form.max_execution_time" maxlength="15">
|
||||||
|
<template #append>{{ $t('php.second') }}</template>
|
||||||
|
</el-input>
|
||||||
|
<span class="input-help">{{ $t('php.max_execution_time') }}</span>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="post_max_size" prop="post_max_size">
|
||||||
|
<el-input clearable v-model.number="form.post_max_size" maxlength="15">
|
||||||
|
<template #append>M</template>
|
||||||
|
</el-input>
|
||||||
|
<span class="input-help">{{ $t('php.post_max_size') }}</span>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="file_uploads" prop="file_uploads">
|
||||||
|
<el-select v-model="form.file_uploads">
|
||||||
|
<el-option :label="$t('website.isOff')" :value="'Off'"></el-option>
|
||||||
|
<el-option :label="$t('website.isOn')" :value="'On'"></el-option>
|
||||||
|
</el-select>
|
||||||
|
<span class="input-help">{{ $t('php.file_uploads') }}</span>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="upload_max_filesize" prop="upload_max_filesize">
|
||||||
|
<el-input clearable v-model.number="form.upload_max_filesize" maxlength="15">
|
||||||
|
<template #append>M</template>
|
||||||
|
</el-input>
|
||||||
|
<span class="input-help">{{ $t('php.upload_max_filesize') }}</span>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="max_file_uploads" prop="max_file_uploads">
|
||||||
|
<el-input clearable v-model.number="form.max_file_uploads" maxlength="15"></el-input>
|
||||||
|
<span class="input-help">{{ $t('php.max_file_uploads') }}</span>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="onSaveStart(phpFormRef)">
|
||||||
|
{{ $t('commons.button.save') }}
|
||||||
|
</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1"><br /></el-col>
|
||||||
|
<el-col :span="9">
|
||||||
|
<el-form-item label="default_socket_timeout" prop="default_socket_timeout">
|
||||||
|
<el-input clearable v-model.number="form.default_socket_timeout" maxlength="15">
|
||||||
|
<template #append>{{ $t('php.second') }}</template>
|
||||||
|
</el-input>
|
||||||
|
<span class="input-help">{{ $t('php.default_socket_timeout') }}</span>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="error_reporting" prop="error_reporting">
|
||||||
|
<el-input clearable v-model.trim="form.error_reporting"></el-input>
|
||||||
|
<span class="input-help">{{ $t('php.error_reporting') }}</span>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="display_errors" prop="display_errors">
|
||||||
|
<el-select v-model="form.display_errors">
|
||||||
|
<el-option :label="$t('website.isOff')" :value="'Off'"></el-option>
|
||||||
|
<el-option :label="$t('website.isOn')" :value="'On'"></el-option>
|
||||||
|
</el-select>
|
||||||
|
<span class="input-help">{{ $t('php.display_errors') }}</span>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="max_input_time" prop="max_input_time">
|
||||||
|
<el-input clearable v-model.number="form.max_input_time" maxlength="15">
|
||||||
|
<template #append>{{ $t('php.second') }}</template>
|
||||||
|
</el-input>
|
||||||
|
<span class="input-help">{{ $t('php.max_input_time') }}</span>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="memory_limit" prop="memory_limit">
|
||||||
|
<el-input clearable v-model.number="form.memory_limit" maxlength="15">
|
||||||
|
<template #append>M</template>
|
||||||
|
</el-input>
|
||||||
|
<span class="input-help">{{ $t('php.memory_limit') }}</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
<ConfirmDialog ref="confirmDialogRef" @confirm="submit"></ConfirmDialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { GetPHPConfig, UpdatePHPConfig } from '@/api/modules/website';
|
||||||
|
import { checkNumberRange, Rules } from '@/global/form-rules';
|
||||||
|
import i18n from '@/lang';
|
||||||
|
import { MsgSuccess } from '@/utils/message';
|
||||||
|
import { FormInstance } from 'element-plus';
|
||||||
|
import { computed, onMounted, reactive, ref } from 'vue';
|
||||||
|
import ConfirmDialog from '@/components/confirm-dialog/index.vue';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
id: {
|
||||||
|
type: Number,
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const id = computed(() => {
|
||||||
|
return props.id;
|
||||||
|
});
|
||||||
|
const loading = ref(false);
|
||||||
|
const phpFormRef = ref();
|
||||||
|
const confirmDialogRef = ref();
|
||||||
|
let form = reactive({
|
||||||
|
short_open_tag: 'Off',
|
||||||
|
max_execution_time: 50,
|
||||||
|
max_input_time: 50,
|
||||||
|
memory_limit: 50,
|
||||||
|
post_max_size: 50,
|
||||||
|
file_uploads: 'On',
|
||||||
|
upload_max_filesize: 50,
|
||||||
|
max_file_uploads: 20,
|
||||||
|
default_socket_timeout: 50,
|
||||||
|
error_reporting: '',
|
||||||
|
display_errors: 'On',
|
||||||
|
});
|
||||||
|
const variablesRules = reactive({
|
||||||
|
max_execution_time: [checkNumberRange(0, 999999999)],
|
||||||
|
max_input_time: [checkNumberRange(0, 999999999)],
|
||||||
|
memory_limit: [checkNumberRange(0, 999999999)],
|
||||||
|
post_max_size: [checkNumberRange(0, 999999999)],
|
||||||
|
upload_max_filesize: [checkNumberRange(0, 999999999)],
|
||||||
|
max_file_uploads: [checkNumberRange(0, 999999999)],
|
||||||
|
default_socket_timeout: [checkNumberRange(0, 999999999)],
|
||||||
|
error_reporting: [Rules.requiredInput],
|
||||||
|
short_open_tag: [Rules.requiredSelect],
|
||||||
|
file_uploads: [Rules.requiredSelect],
|
||||||
|
display_errors: [Rules.requiredSelect],
|
||||||
|
});
|
||||||
|
|
||||||
|
const get = () => {
|
||||||
|
loading.value = true;
|
||||||
|
GetPHPConfig(id.value)
|
||||||
|
.then((res) => {
|
||||||
|
const param = res.data.params;
|
||||||
|
form.short_open_tag = param.short_open_tag;
|
||||||
|
form.max_execution_time = Number(param.max_execution_time);
|
||||||
|
form.max_input_time = Number(param.max_input_time);
|
||||||
|
form.memory_limit = parseFloat(param.memory_limit.replace(/[^\d.]/g, ''));
|
||||||
|
form.post_max_size = parseFloat(param.post_max_size.replace(/[^\d.]/g, ''));
|
||||||
|
form.file_uploads = param.file_uploads;
|
||||||
|
form.upload_max_filesize = parseFloat(param.upload_max_filesize.replace(/[^\d.]/g, ''));
|
||||||
|
form.max_file_uploads = Number(param.max_file_uploads);
|
||||||
|
form.default_socket_timeout = Number(param.default_socket_timeout);
|
||||||
|
form.error_reporting = param.error_reporting;
|
||||||
|
form.display_errors = param.display_errors;
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onSaveStart = async (formEl: FormInstance | undefined) => {
|
||||||
|
if (!formEl) return;
|
||||||
|
formEl.validate(async (valid) => {
|
||||||
|
if (!valid) return;
|
||||||
|
let params = {
|
||||||
|
header: i18n.global.t('database.confChange'),
|
||||||
|
operationInfo: i18n.global.t('database.restartNowHelper'),
|
||||||
|
submitInputInfo: i18n.global.t('database.restartNow'),
|
||||||
|
};
|
||||||
|
confirmDialogRef.value!.acceptParams(params);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const submit = async () => {
|
||||||
|
const params = {
|
||||||
|
short_open_tag: form.short_open_tag,
|
||||||
|
max_execution_time: String(form.max_execution_time),
|
||||||
|
max_input_time: String(form.max_input_time),
|
||||||
|
memory_limit: form.memory_limit + 'M',
|
||||||
|
post_max_size: form.post_max_size + 'M',
|
||||||
|
file_uploads: form.file_uploads,
|
||||||
|
upload_max_filesize: form.upload_max_filesize + 'M',
|
||||||
|
max_file_uploads: String(form.max_file_uploads),
|
||||||
|
default_socket_timeout: String(form.default_socket_timeout),
|
||||||
|
error_reporting: form.error_reporting,
|
||||||
|
display_errors: form.display_errors,
|
||||||
|
};
|
||||||
|
loading.value = true;
|
||||||
|
UpdatePHPConfig({ id: id.value, params: params })
|
||||||
|
.then(() => {
|
||||||
|
MsgSuccess(i18n.global.t('commons.msg.updateSuccess'));
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
get();
|
||||||
|
});
|
||||||
|
</script>
|
44
frontend/src/views/website/website/config/php/index.vue
Normal file
44
frontend/src/views/website/website/config/php/index.vue
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<template>
|
||||||
|
<el-tabs tab-position="left" v-model="index">
|
||||||
|
<el-tab-pane :label="$t('website.updateConfig')" name="0">
|
||||||
|
<Config :id="id"></Config>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { GetRuntime } from '@/api/modules/runtime';
|
||||||
|
import { GetWebsite } from '@/api/modules/website';
|
||||||
|
import { computed, onMounted, ref } from 'vue';
|
||||||
|
import Config from './config/index.vue';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
id: {
|
||||||
|
type: Number,
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const id = computed(() => {
|
||||||
|
return props.id;
|
||||||
|
});
|
||||||
|
|
||||||
|
let index = ref('0');
|
||||||
|
let configPHP = ref(false);
|
||||||
|
let installId = ref(0);
|
||||||
|
|
||||||
|
const getWebsiteDetail = async () => {
|
||||||
|
const res = await GetWebsite(props.id);
|
||||||
|
if (res.data.type === 'runtime') {
|
||||||
|
installId.value = res.data.appInstallId;
|
||||||
|
const runRes = await GetRuntime(res.data.runtimeID);
|
||||||
|
if (runRes.data.resource === 'appstore') {
|
||||||
|
configPHP.value = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getWebsiteDetail();
|
||||||
|
});
|
||||||
|
</script>
|
@ -152,10 +152,14 @@
|
|||||||
</div>
|
</div>
|
||||||
<div v-if="website.type === 'runtime'">
|
<div v-if="website.type === 'runtime'">
|
||||||
<el-form-item :label="$t('runtime.runtime')" prop="runtimeID">
|
<el-form-item :label="$t('runtime.runtime')" prop="runtimeID">
|
||||||
<el-select v-model="website.runtimeID" @change="changeRuntime(website.runtimeID)">
|
<el-select
|
||||||
|
v-model="website.runtimeID"
|
||||||
|
@change="changeRuntime(website.runtimeID)"
|
||||||
|
filterable
|
||||||
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="(run, index) in runtimes"
|
v-for="run in runtimes"
|
||||||
:key="index"
|
:key="run.name"
|
||||||
:label="run.name + '(' + $t('runtime.' + run.resource) + ')'"
|
:label="run.name + '(' + $t('runtime.' + run.resource) + ')'"
|
||||||
:value="run.id"
|
:value="run.id"
|
||||||
></el-option>
|
></el-option>
|
||||||
@ -303,7 +307,8 @@ let staticPath = ref('');
|
|||||||
let runtimeResource = ref('appstore');
|
let runtimeResource = ref('appstore');
|
||||||
const runtimeReq = ref<Runtime.RuntimeReq>({
|
const runtimeReq = ref<Runtime.RuntimeReq>({
|
||||||
page: 1,
|
page: 1,
|
||||||
pageSize: 20,
|
pageSize: 100,
|
||||||
|
status: 'normal',
|
||||||
});
|
});
|
||||||
const runtimes = ref<Runtime.RuntimeDTO[]>([]);
|
const runtimes = ref<Runtime.RuntimeDTO[]>([]);
|
||||||
|
|
||||||
@ -400,7 +405,9 @@ const getRuntimes = async () => {
|
|||||||
const first = runtimes.value[0];
|
const first = runtimes.value[0];
|
||||||
website.value.runtimeID = first.id;
|
website.value.runtimeID = first.id;
|
||||||
runtimeResource.value = first.resource;
|
runtimeResource.value = first.resource;
|
||||||
getAppDetailByID(first.appDetailId);
|
if (first.type === 'appstore') {
|
||||||
|
getAppDetailByID(first.appDetailId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {}
|
} catch (error) {}
|
||||||
};
|
};
|
||||||
|
4
go.mod
4
go.mod
@ -8,6 +8,7 @@ require (
|
|||||||
github.com/compose-spec/compose-go v1.13.2
|
github.com/compose-spec/compose-go v1.13.2
|
||||||
github.com/creack/pty v1.1.18
|
github.com/creack/pty v1.1.18
|
||||||
github.com/dgraph-io/badger/v3 v3.2103.5
|
github.com/dgraph-io/badger/v3 v3.2103.5
|
||||||
|
github.com/docker/cli v23.0.1+incompatible
|
||||||
github.com/docker/compose/v2 v2.17.2
|
github.com/docker/compose/v2 v2.17.2
|
||||||
github.com/docker/docker v23.0.1+incompatible
|
github.com/docker/docker v23.0.1+incompatible
|
||||||
github.com/docker/go-connections v0.4.0
|
github.com/docker/go-connections v0.4.0
|
||||||
@ -41,6 +42,7 @@ require (
|
|||||||
github.com/spf13/afero v1.9.2
|
github.com/spf13/afero v1.9.2
|
||||||
github.com/spf13/cobra v1.6.1
|
github.com/spf13/cobra v1.6.1
|
||||||
github.com/spf13/viper v1.14.0
|
github.com/spf13/viper v1.14.0
|
||||||
|
github.com/subosito/gotenv v1.4.1
|
||||||
github.com/swaggo/files v0.0.0-20220728132757-551d4a08d97a
|
github.com/swaggo/files v0.0.0-20220728132757-551d4a08d97a
|
||||||
github.com/swaggo/gin-swagger v1.5.3
|
github.com/swaggo/gin-swagger v1.5.3
|
||||||
github.com/swaggo/swag v1.8.4
|
github.com/swaggo/swag v1.8.4
|
||||||
@ -91,7 +93,6 @@ require (
|
|||||||
github.com/dgraph-io/ristretto v0.1.1 // indirect
|
github.com/dgraph-io/ristretto v0.1.1 // indirect
|
||||||
github.com/distribution/distribution/v3 v3.0.0-20230223072852-e5d5810851d1 // indirect
|
github.com/distribution/distribution/v3 v3.0.0-20230223072852-e5d5810851d1 // indirect
|
||||||
github.com/docker/buildx v0.10.4 // indirect
|
github.com/docker/buildx v0.10.4 // indirect
|
||||||
github.com/docker/cli v23.0.1+incompatible // indirect
|
|
||||||
github.com/docker/distribution v2.8.1+incompatible // indirect
|
github.com/docker/distribution v2.8.1+incompatible // indirect
|
||||||
github.com/docker/docker-credential-helpers v0.7.0 // indirect
|
github.com/docker/docker-credential-helpers v0.7.0 // indirect
|
||||||
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c // indirect
|
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c // indirect
|
||||||
@ -200,7 +201,6 @@ require (
|
|||||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||||
github.com/spf13/pflag v1.0.5 // indirect
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
github.com/stretchr/testify v1.8.2 // indirect
|
github.com/stretchr/testify v1.8.2 // indirect
|
||||||
github.com/subosito/gotenv v1.4.1 // indirect
|
|
||||||
github.com/therootcompany/xz v1.0.1 // indirect
|
github.com/therootcompany/xz v1.0.1 // indirect
|
||||||
github.com/theupdateframework/notary v0.7.0 // indirect
|
github.com/theupdateframework/notary v0.7.0 // indirect
|
||||||
github.com/tilt-dev/fsnotify v1.4.8-0.20220602155310-fff9c274a375 // indirect
|
github.com/tilt-dev/fsnotify v1.4.8-0.20220602155310-fff9c274a375 // indirect
|
||||||
|
4
go.sum
4
go.sum
@ -678,8 +678,8 @@ github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3I
|
|||||||
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||||
github.com/opencontainers/image-spec v1.1.0-rc2 h1:2zx/Stx4Wc5pIPDvIxHXvXtQFW/7XWJGmnM7r3wg034=
|
github.com/opencontainers/image-spec v1.1.0-rc2 h1:2zx/Stx4Wc5pIPDvIxHXvXtQFW/7XWJGmnM7r3wg034=
|
||||||
github.com/opencontainers/image-spec v1.1.0-rc2/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ=
|
github.com/opencontainers/image-spec v1.1.0-rc2/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ=
|
||||||
github.com/opencontainers/runc v1.1.4 h1:nRCz/8sKg6K6jgYAFLDlXzPeITBZJyX28DBVhWD+5dg=
|
github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/GDEs=
|
||||||
github.com/opencontainers/runc v1.1.4/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg=
|
github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg=
|
||||||
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 h1:3snG66yBm59tKhhSPQrQ/0bCrv1LQbKt40LnUPiUxdc=
|
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 h1:3snG66yBm59tKhhSPQrQ/0bCrv1LQbKt40LnUPiUxdc=
|
||||||
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||||
github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
|
github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
|
||||||
|
Loading…
x
Reference in New Issue
Block a user