mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-18 22:22:59 +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
|
||||
// @Summary Search app detail by id
|
||||
// @Description 通过 id 获取应用详情
|
||||
// @Summary Search app detail by appid
|
||||
// @Description 通过 appid 获取应用详情
|
||||
// @Accept json
|
||||
// @Param appId path integer true "app id"
|
||||
// @Param version path string true "app 版本"
|
||||
@ -97,13 +97,13 @@ func (b *BaseApi) GetAppDetail(c *gin.Context) {
|
||||
}
|
||||
|
||||
// @Tags App
|
||||
// @Summary Search app detail by id
|
||||
// @Summary Get app detail by id
|
||||
// @Description 通过 id 获取应用详情
|
||||
// @Accept json
|
||||
// @Param appId path integer true "id"
|
||||
// @Success 200 {object} response.AppDetailDTO
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /apps/detail/:id[get]
|
||||
// @Router /apps/details/:id [get]
|
||||
func (b *BaseApi) GetAppDetailByID(c *gin.Context) {
|
||||
appDetailID, err := helper.GetIntParamByKey(c, "id")
|
||||
if err != nil {
|
||||
|
@ -498,3 +498,47 @@ func (b *BaseApi) ChangeDefaultServer(c *gin.Context) {
|
||||
}
|
||||
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 {
|
||||
dto.PageInfo
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
type RuntimeCreate struct {
|
||||
|
@ -134,3 +134,8 @@ type WebsiteLogReq struct {
|
||||
type WebsiteDefaultUpdate struct {
|
||||
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"`
|
||||
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)
|
||||
GetFirst(opts ...DBOption) (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
|
||||
Delete(ctx context.Context, install 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
|
||||
}
|
||||
|
||||
func (a *AppInstallRepo) Save(install *model.AppInstall) error {
|
||||
return getDb().Save(&install).Error
|
||||
func (a *AppInstallRepo) Save(ctx context.Context, install *model.AppInstall) error {
|
||||
return getTx(ctx).Save(&install).Error
|
||||
}
|
||||
|
||||
func (a *AppInstallRepo) DeleteBy(opts ...DBOption) error {
|
||||
|
@ -13,6 +13,7 @@ type IRuntimeRepo interface {
|
||||
WithName(name string) DBOption
|
||||
WithImage(image string) DBOption
|
||||
WithNotId(id uint) DBOption
|
||||
WithStatus(status string) DBOption
|
||||
Page(page, size int, opts ...DBOption) (int64, []model.Runtime, error)
|
||||
Create(ctx context.Context, 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 {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("image = ?", image)
|
||||
|
@ -17,6 +17,7 @@ type IWebsiteRepo interface {
|
||||
WithGroupID(groupId uint) DBOption
|
||||
WithDefaultServer() DBOption
|
||||
WithDomainLike(domain string) DBOption
|
||||
WithRuntimeID(runtimeID uint) DBOption
|
||||
Page(page, size int, opts ...DBOption) (int64, []model.Website, error)
|
||||
List(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 {
|
||||
return func(db *gorm.DB) *gorm.DB {
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
go upApp(appInstall.GetComposePath(), appInstall)
|
||||
go upApp(ctx, appInstall.GetComposePath(), appInstall)
|
||||
go updateToolApp(appInstall)
|
||||
return &appInstall, nil
|
||||
}
|
||||
|
@ -260,7 +260,7 @@ func (a *AppInstallService) Update(req request.AppInstalledUpdate) error {
|
||||
if err := env.Write(oldEnvMaps, envPath); err != nil {
|
||||
return err
|
||||
}
|
||||
_ = appInstallRepo.Save(&installed)
|
||||
_ = appInstallRepo.Save(context.Background(), &installed)
|
||||
|
||||
if err := rebuildApp(installed); err != nil {
|
||||
return err
|
||||
@ -300,7 +300,7 @@ func (a *AppInstallService) SyncAll(systemInit bool) error {
|
||||
if systemInit {
|
||||
i.Status = constant.Error
|
||||
i.Message = "System restart causes application exception"
|
||||
_ = appInstallRepo.Save(&i)
|
||||
_ = appInstallRepo.Save(context.Background(), &i)
|
||||
}
|
||||
continue
|
||||
}
|
||||
@ -569,15 +569,15 @@ func syncById(installId uint) error {
|
||||
if containerCount == 0 {
|
||||
appInstall.Status = constant.Error
|
||||
appInstall.Message = "container is not found"
|
||||
return appInstallRepo.Save(&appInstall)
|
||||
return appInstallRepo.Save(context.Background(), &appInstall)
|
||||
}
|
||||
if errCount == 0 && existedCount == 0 {
|
||||
appInstall.Status = constant.Running
|
||||
return appInstallRepo.Save(&appInstall)
|
||||
return appInstallRepo.Save(context.Background(), &appInstall)
|
||||
}
|
||||
if existedCount == normalCount {
|
||||
appInstall.Status = constant.Stopped
|
||||
return appInstallRepo.Save(&appInstall)
|
||||
return appInstallRepo.Save(context.Background(), &appInstall)
|
||||
}
|
||||
if errCount == normalCount {
|
||||
appInstall.Status = constant.Error
|
||||
@ -602,7 +602,7 @@ func syncById(installId uint) error {
|
||||
errMsg.Write([]byte("\n"))
|
||||
}
|
||||
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 {
|
||||
|
@ -239,7 +239,7 @@ func updateInstall(installId uint, detailId uint) error {
|
||||
}
|
||||
return err
|
||||
}
|
||||
return appInstallRepo.Save(&install)
|
||||
return appInstallRepo.Save(context.Background(), &install)
|
||||
}
|
||||
|
||||
func getContainerNames(install model.AppInstall) ([]string, error) {
|
||||
@ -381,7 +381,7 @@ func upAppPre(app model.App, appInstall model.AppInstall) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func upApp(composeFilePath string, appInstall model.AppInstall) {
|
||||
func upApp(ctx context.Context, composeFilePath string, appInstall model.AppInstall) {
|
||||
out, err := compose.Up(composeFilePath)
|
||||
if err != nil {
|
||||
if out != "" {
|
||||
@ -390,10 +390,10 @@ func upApp(composeFilePath string, appInstall model.AppInstall) {
|
||||
appInstall.Message = err.Error()
|
||||
}
|
||||
appInstall.Status = constant.Error
|
||||
_ = appInstallRepo.Save(&appInstall)
|
||||
_ = appInstallRepo.Save(ctx, &appInstall)
|
||||
} else {
|
||||
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)
|
||||
install.Status = constant.Error
|
||||
}
|
||||
_ = appInstallRepo.Save(&install)
|
||||
_ = appInstallRepo.Save(context.Background(), &install)
|
||||
return reErr
|
||||
}
|
||||
|
||||
@ -579,7 +579,7 @@ func updateToolApp(installed model.AppInstall) {
|
||||
return
|
||||
}
|
||||
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())
|
||||
return
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
@ -192,7 +193,7 @@ func handleAppRecover(install *model.AppInstall, recoverFile string, isRollback
|
||||
}
|
||||
|
||||
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)
|
||||
return err
|
||||
}
|
||||
|
@ -121,6 +121,9 @@ func (r *RuntimeService) Page(req request.RuntimeSearch) (int64, []response.Runt
|
||||
if 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...)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
@ -138,7 +141,10 @@ func (r *RuntimeService) Delete(id uint) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//TODO 校验网站关联
|
||||
website, _ := websiteRepo.GetFirst(websiteRepo.WithRuntimeID(id))
|
||||
if website.ID > 0 {
|
||||
return buserr.New(constant.ErrDelWithWebsite)
|
||||
}
|
||||
//TODO 删除镜像
|
||||
if runtime.Resource == constant.ResourceAppstore {
|
||||
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
|
||||
if form.Type == "select" {
|
||||
if form.Multiple {
|
||||
appParam.Value = strings.Split(v, ",")
|
||||
if v == "" {
|
||||
appParam.Value = []string{}
|
||||
} else {
|
||||
appParam.Value = strings.Split(v, ",")
|
||||
}
|
||||
} else {
|
||||
for _, fv := range form.Values {
|
||||
if fv.Value == v {
|
||||
|
@ -1,10 +1,12 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/common"
|
||||
"os"
|
||||
"path"
|
||||
"reflect"
|
||||
@ -52,6 +54,8 @@ type IWebsiteService interface {
|
||||
UpdateNginxConfigFile(req request.WebsiteNginxUpdate) error
|
||||
OpWebsiteLog(req request.WebsiteLogReq) (*response.WebsiteLog, error)
|
||||
ChangeDefaultServer(id uint) error
|
||||
GetPHPConfig(id uint) (*response.PHPConfig, error)
|
||||
UpdatePHPConfig(req request.WebsitePHPConfigUpdate) error
|
||||
}
|
||||
|
||||
func NewIWebsiteService() IWebsiteService {
|
||||
@ -180,6 +184,9 @@ func (w WebsiteService) CreateWebsite(ctx context.Context, create request.Websit
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if common.ScanPort(create.Port) {
|
||||
return buserr.WithDetail(constant.ErrPortInUsed, create.Port, nil)
|
||||
}
|
||||
if runtime.Resource == constant.ResourceAppstore {
|
||||
var req request.AppInstallCreate
|
||||
reg, _ := regexp.Compile("[^a-z0-9_\\-]+")
|
||||
@ -826,3 +833,86 @@ func (w WebsiteService) ChangeDefaultServer(id uint) error {
|
||||
}
|
||||
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
|
||||
var (
|
||||
ErrDirNotFound = "ErrDirNotFound"
|
||||
ErrFileNotExist = "ErrFileNotExist"
|
||||
ErrImageBuildErr = "ErrImageBuildErr"
|
||||
ErrImageExist = "ErrImageExist"
|
||||
ErrDirNotFound = "ErrDirNotFound"
|
||||
ErrFileNotExist = "ErrFileNotExist"
|
||||
ErrImageBuildErr = "ErrImageBuildErr"
|
||||
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!"
|
||||
ErrFileNotExist: "{{ .detail }} file does not exist! Please check source file integrity!"
|
||||
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 文件夹不存在!请检查文件完整性!"
|
||||
ErrFileNotExist: "{{ .detail }} 文件不存在!请检查源文件完整性!"
|
||||
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/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 {
|
||||
name?: string;
|
||||
status?: string;
|
||||
}
|
||||
|
||||
export interface RuntimeDTO extends Runtime {
|
||||
|
@ -261,4 +261,13 @@ export namespace Website {
|
||||
export interface DefaultServerUpdate {
|
||||
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) => {
|
||||
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 网络',
|
||||
phpFPM: 'FPM 配置文件',
|
||||
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: {
|
||||
serverNamesHashBucketSizeHelper: '服务器名字的hash表大小',
|
||||
|
@ -30,12 +30,16 @@
|
||||
<el-button type="primary" :plain="index !== 'resource'" @click="changeTab('resource')">
|
||||
{{ $t('website.source') }}
|
||||
</el-button>
|
||||
<el-button type="primary" v-if="configPHP" :plain="index !== 'php'" @click="changeTab('php')">
|
||||
PHP
|
||||
</el-button>
|
||||
</template>
|
||||
<template #main>
|
||||
<Basic :id="id" v-if="index === 'basic'"></Basic>
|
||||
<Safety :id="id" v-if="index === 'safety'"></Safety>
|
||||
<Log :id="id" v-if="index === 'log'"></Log>
|
||||
<Resource :id="id" v-if="index === 'resource'"></Resource>
|
||||
<PHP :id="id" v-if="index === 'php'"></PHP>
|
||||
</template>
|
||||
</LayoutContent>
|
||||
</div>
|
||||
@ -48,9 +52,11 @@ import Basic from './basic/index.vue';
|
||||
import Safety from './safety/index.vue';
|
||||
import Resource from './resource/index.vue';
|
||||
import Log from './log/index.vue';
|
||||
import PHP from './php/index.vue';
|
||||
import router from '@/routers';
|
||||
import WebsiteStatus from '@/views/website/website/status/index.vue';
|
||||
import { GetWebsite } from '@/api/modules/website';
|
||||
import { GetRuntime } from '@/api/modules/runtime';
|
||||
|
||||
const props = defineProps({
|
||||
id: {
|
||||
@ -67,6 +73,7 @@ let id = ref(0);
|
||||
let index = ref('basic');
|
||||
let website = ref<any>({});
|
||||
let loading = ref(false);
|
||||
const configPHP = ref(false);
|
||||
|
||||
watch(index, (curr, old) => {
|
||||
if (curr != old) {
|
||||
@ -83,8 +90,14 @@ onMounted(() => {
|
||||
id.value = Number(props.id);
|
||||
loading.value = true;
|
||||
GetWebsite(id.value)
|
||||
.then((res) => {
|
||||
.then(async (res) => {
|
||||
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(() => {
|
||||
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 v-if="website.type === 'runtime'">
|
||||
<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
|
||||
v-for="(run, index) in runtimes"
|
||||
:key="index"
|
||||
v-for="run in runtimes"
|
||||
:key="run.name"
|
||||
:label="run.name + '(' + $t('runtime.' + run.resource) + ')'"
|
||||
:value="run.id"
|
||||
></el-option>
|
||||
@ -303,7 +307,8 @@ let staticPath = ref('');
|
||||
let runtimeResource = ref('appstore');
|
||||
const runtimeReq = ref<Runtime.RuntimeReq>({
|
||||
page: 1,
|
||||
pageSize: 20,
|
||||
pageSize: 100,
|
||||
status: 'normal',
|
||||
});
|
||||
const runtimes = ref<Runtime.RuntimeDTO[]>([]);
|
||||
|
||||
@ -400,7 +405,9 @@ const getRuntimes = async () => {
|
||||
const first = runtimes.value[0];
|
||||
website.value.runtimeID = first.id;
|
||||
runtimeResource.value = first.resource;
|
||||
getAppDetailByID(first.appDetailId);
|
||||
if (first.type === 'appstore') {
|
||||
getAppDetailByID(first.appDetailId);
|
||||
}
|
||||
}
|
||||
} catch (error) {}
|
||||
};
|
||||
|
4
go.mod
4
go.mod
@ -8,6 +8,7 @@ require (
|
||||
github.com/compose-spec/compose-go v1.13.2
|
||||
github.com/creack/pty v1.1.18
|
||||
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/docker v23.0.1+incompatible
|
||||
github.com/docker/go-connections v0.4.0
|
||||
@ -41,6 +42,7 @@ require (
|
||||
github.com/spf13/afero v1.9.2
|
||||
github.com/spf13/cobra v1.6.1
|
||||
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/gin-swagger v1.5.3
|
||||
github.com/swaggo/swag v1.8.4
|
||||
@ -91,7 +93,6 @@ require (
|
||||
github.com/dgraph-io/ristretto v0.1.1 // indirect
|
||||
github.com/distribution/distribution/v3 v3.0.0-20230223072852-e5d5810851d1 // 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/docker-credential-helpers v0.7.0 // 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/pflag v1.0.5 // 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/theupdateframework/notary v0.7.0 // 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.1.0-rc2 h1:2zx/Stx4Wc5pIPDvIxHXvXtQFW/7XWJGmnM7r3wg034=
|
||||
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.4/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg=
|
||||
github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/GDEs=
|
||||
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/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
|
||||
|
Loading…
Reference in New Issue
Block a user