mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2024-11-24 02:59:16 +08:00
feat: docker 配置界面样式统一 (#1173)
This commit is contained in:
parent
2d6925ac4f
commit
ec843f2396
@ -58,13 +58,13 @@ func (b *BaseApi) LoadDaemonJson(c *gin.Context) {
|
||||
// @Summary Update docker daemon.json
|
||||
// @Description 修改 docker 配置信息
|
||||
// @Accept json
|
||||
// @Param request body dto.DaemonJsonConf true "request"
|
||||
// @Param request body dto.SettingUpdate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/daemonjson/update [post]
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFuntions":[],"formatZH":"更新 docker daemon.json 配置","formatEN":"Updated the docker daemon.json configuration"}
|
||||
// @x-panel-log {"bodyKeys":["key", "value"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"更新 docker daemon.json 配置 [key]=>[value]","formatEN":"Updated the docker daemon.json configuration [key]=>[value]"}
|
||||
func (b *BaseApi) UpdateDaemonJson(c *gin.Context) {
|
||||
var req dto.DaemonJsonConf
|
||||
var req dto.SettingUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
@ -78,6 +78,30 @@ func (b *BaseApi) UpdateDaemonJson(c *gin.Context) {
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Container Docker
|
||||
// @Summary Update docker daemon.json log option
|
||||
// @Description 修改 docker 日志配置
|
||||
// @Accept json
|
||||
// @Param request body dto.LogOption true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/daemonjson/update [post]
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFuntions":[],"formatZH":"更新 docker daemon.json 日志配置","formatEN":"Updated the docker daemon.json log option"}
|
||||
func (b *BaseApi) UpdateLogOption(c *gin.Context) {
|
||||
var req dto.LogOption
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := dockerService.UpdateLogOption(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Container Docker
|
||||
// @Summary Update docker daemon.json by upload file
|
||||
// @Description 上传替换 docker 配置文件
|
||||
|
@ -18,6 +18,11 @@ type DaemonJsonConf struct {
|
||||
LogMaxFile string `json:"logMaxFile"`
|
||||
}
|
||||
|
||||
type LogOption struct {
|
||||
LogMaxSize string `json:"logMaxSize"`
|
||||
LogMaxFile string `json:"logMaxFile"`
|
||||
}
|
||||
|
||||
type DockerOperation struct {
|
||||
Operation string `json:"operation" validate:"required,oneof=start restart stop"`
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"bufio"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
@ -18,7 +19,8 @@ import (
|
||||
type DockerService struct{}
|
||||
|
||||
type IDockerService interface {
|
||||
UpdateConf(req dto.DaemonJsonConf) error
|
||||
UpdateConf(req dto.SettingUpdate) error
|
||||
UpdateLogOption(req dto.LogOption) error
|
||||
UpdateConfByFile(info dto.DaemonJsonUpdateByFile) error
|
||||
LoadDockerStatus() string
|
||||
LoadDockerConf() *dto.DaemonJsonConf
|
||||
@ -95,6 +97,7 @@ func (u *DockerService) LoadDockerConf() *dto.DaemonJsonConf {
|
||||
return &data
|
||||
}
|
||||
if err := json.Unmarshal(arr, &conf); err != nil {
|
||||
fmt.Println(err)
|
||||
return &data
|
||||
}
|
||||
if _, ok := deamonMap["iptables"]; !ok {
|
||||
@ -116,7 +119,7 @@ func (u *DockerService) LoadDockerConf() *dto.DaemonJsonConf {
|
||||
return &data
|
||||
}
|
||||
|
||||
func (u *DockerService) UpdateConf(req dto.DaemonJsonConf) error {
|
||||
func (u *DockerService) UpdateConf(req dto.SettingUpdate) error {
|
||||
if _, err := os.Stat(constant.DaemonJsonPath); err != nil && os.IsNotExist(err) {
|
||||
if err = os.MkdirAll(path.Dir(constant.DaemonJsonPath), os.ModePerm); err != nil {
|
||||
return err
|
||||
@ -131,43 +134,51 @@ func (u *DockerService) UpdateConf(req dto.DaemonJsonConf) error {
|
||||
deamonMap := make(map[string]interface{})
|
||||
_ = json.Unmarshal(file, &deamonMap)
|
||||
|
||||
if len(req.Registries) == 0 {
|
||||
delete(deamonMap, "insecure-registries")
|
||||
} else {
|
||||
deamonMap["insecure-registries"] = req.Registries
|
||||
}
|
||||
if len(req.Mirrors) == 0 {
|
||||
delete(deamonMap, "registry-mirrors")
|
||||
} else {
|
||||
deamonMap["registry-mirrors"] = req.Mirrors
|
||||
}
|
||||
|
||||
changeLogOption(deamonMap, req.LogMaxFile, req.LogMaxSize)
|
||||
|
||||
if !req.LiveRestore {
|
||||
delete(deamonMap, "live-restore")
|
||||
} else {
|
||||
deamonMap["live-restore"] = req.LiveRestore
|
||||
}
|
||||
if req.IPTables {
|
||||
delete(deamonMap, "iptables")
|
||||
} else {
|
||||
deamonMap["iptables"] = false
|
||||
}
|
||||
if opts, ok := deamonMap["exec-opts"]; ok {
|
||||
if optsValue, isArray := opts.([]interface{}); isArray {
|
||||
for i := 0; i < len(optsValue); i++ {
|
||||
if opt, isStr := optsValue[i].(string); isStr {
|
||||
if strings.HasPrefix(opt, "native.cgroupdriver=") {
|
||||
optsValue[i] = "native.cgroupdriver=" + req.CgroupDriver
|
||||
break
|
||||
switch req.Key {
|
||||
case "Registries":
|
||||
if len(req.Value) == 0 {
|
||||
delete(deamonMap, "insecure-registries")
|
||||
} else {
|
||||
deamonMap["insecure-registries"] = strings.Split(req.Value, ",")
|
||||
}
|
||||
case "Mirrors":
|
||||
if len(req.Value) == 0 {
|
||||
delete(deamonMap, "registry-mirrors")
|
||||
} else {
|
||||
deamonMap["registry-mirrors"] = strings.Split(req.Value, ",")
|
||||
}
|
||||
case "LogOption":
|
||||
if req.Value == "disable" {
|
||||
delete(deamonMap, "log-opts")
|
||||
}
|
||||
case "LiveRestore":
|
||||
if req.Value == "disable" {
|
||||
delete(deamonMap, "live-restore")
|
||||
} else {
|
||||
deamonMap["live-restore"] = true
|
||||
}
|
||||
case "IPtables":
|
||||
if req.Value == "enable" {
|
||||
delete(deamonMap, "iptables")
|
||||
} else {
|
||||
deamonMap["iptables"] = false
|
||||
}
|
||||
case "Dirver":
|
||||
if opts, ok := deamonMap["exec-opts"]; ok {
|
||||
if optsValue, isArray := opts.([]interface{}); isArray {
|
||||
for i := 0; i < len(optsValue); i++ {
|
||||
if opt, isStr := optsValue[i].(string); isStr {
|
||||
if strings.HasPrefix(opt, "native.cgroupdriver=") {
|
||||
optsValue[i] = "native.cgroupdriver=" + req.Value
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if req.CgroupDriver == "systemd" {
|
||||
deamonMap["exec-opts"] = []string{"native.cgroupdriver=systemd"}
|
||||
} else {
|
||||
if req.Value == "systemd" {
|
||||
deamonMap["exec-opts"] = []string{"native.cgroupdriver=systemd"}
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(deamonMap) == 0 {
|
||||
@ -189,6 +200,41 @@ func (u *DockerService) UpdateConf(req dto.DaemonJsonConf) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *DockerService) UpdateLogOption(req dto.LogOption) error {
|
||||
if _, err := os.Stat(constant.DaemonJsonPath); err != nil && os.IsNotExist(err) {
|
||||
if err = os.MkdirAll(path.Dir(constant.DaemonJsonPath), os.ModePerm); err != nil {
|
||||
return err
|
||||
}
|
||||
_, _ = os.Create(constant.DaemonJsonPath)
|
||||
}
|
||||
|
||||
file, err := os.ReadFile(constant.DaemonJsonPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
deamonMap := make(map[string]interface{})
|
||||
_ = json.Unmarshal(file, &deamonMap)
|
||||
|
||||
changeLogOption(deamonMap, req.LogMaxFile, req.LogMaxSize)
|
||||
if len(deamonMap) == 0 {
|
||||
_ = os.Remove(constant.DaemonJsonPath)
|
||||
return nil
|
||||
}
|
||||
newJson, err := json.MarshalIndent(deamonMap, "", "\t")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.WriteFile(constant.DaemonJsonPath, newJson, 0640); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
stdout, err := cmd.Exec("systemctl restart docker")
|
||||
if err != nil {
|
||||
return errors.New(string(stdout))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *DockerService) UpdateConfByFile(req dto.DaemonJsonUpdateByFile) error {
|
||||
if len(req.File) == 0 {
|
||||
_ = os.Remove(constant.DaemonJsonPath)
|
||||
|
@ -379,7 +379,7 @@ func (u *FirewallService) pingStatus() string {
|
||||
return constant.StatusDisable
|
||||
}
|
||||
|
||||
func (u *FirewallService) updatePingStatus(enabel string) error {
|
||||
func (u *FirewallService) updatePingStatus(enable string) error {
|
||||
lineBytes, err := os.ReadFile(confPath)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -389,14 +389,14 @@ func (u *FirewallService) updatePingStatus(enabel string) error {
|
||||
hasLine := false
|
||||
for _, line := range files {
|
||||
if strings.Contains(line, "net/ipv4/icmp_echo_ignore_all") || strings.HasPrefix(line, "net/ipv4/icmp_echo_ignore_all") {
|
||||
newFiles = append(newFiles, "net/ipv4/icmp_echo_ignore_all="+enabel)
|
||||
newFiles = append(newFiles, "net/ipv4/icmp_echo_ignore_all="+enable)
|
||||
hasLine = true
|
||||
} else {
|
||||
newFiles = append(newFiles, line)
|
||||
}
|
||||
}
|
||||
if !hasLine {
|
||||
newFiles = append(newFiles, "net/ipv4/icmp_echo_ignore_all="+enabel)
|
||||
newFiles = append(newFiles, "net/ipv4/icmp_echo_ignore_all="+enable)
|
||||
}
|
||||
file, err := os.OpenFile(confPath, os.O_WRONLY|os.O_TRUNC, 0666)
|
||||
if err != nil {
|
||||
|
@ -68,6 +68,7 @@ func (s *ContainerRouter) InitContainerRouter(Router *gin.RouterGroup) {
|
||||
baRouter.GET("/docker/status", baseApi.LoadDockerStatus)
|
||||
baRouter.POST("/docker/operate", baseApi.OperateDocker)
|
||||
baRouter.POST("/daemonjson/update", baseApi.UpdateDaemonJson)
|
||||
baRouter.POST("/logoption/update", baseApi.UpdateLogOption)
|
||||
baRouter.POST("/daemonjson/update/byfile", baseApi.UpdateDaemonJsonByFile)
|
||||
}
|
||||
}
|
||||
|
@ -1241,14 +1241,14 @@ var doc = `{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "修改 docker 配置信息",
|
||||
"description": "修改 docker 日志配置",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Container Docker"
|
||||
],
|
||||
"summary": "Update docker daemon.json",
|
||||
"summary": "Update docker daemon.json log option",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "request",
|
||||
@ -1256,7 +1256,7 @@ var doc = `{
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.DaemonJsonConf"
|
||||
"$ref": "#/definitions/dto.LogOption"
|
||||
}
|
||||
}
|
||||
],
|
||||
@ -1268,8 +1268,8 @@ var doc = `{
|
||||
"x-panel-log": {
|
||||
"BeforeFuntions": [],
|
||||
"bodyKeys": [],
|
||||
"formatEN": "Updated the docker daemon.json configuration",
|
||||
"formatZH": "更新 docker daemon.json 配置",
|
||||
"formatEN": "Updated the docker daemon.json log option",
|
||||
"formatZH": "更新 docker daemon.json 日志配置",
|
||||
"paramKeys": []
|
||||
}
|
||||
}
|
||||
@ -9040,6 +9040,72 @@ var doc = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/websites/leech": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "获取防盗链配置",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Website"
|
||||
],
|
||||
"summary": "Get AntiLeech conf",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "request",
|
||||
"name": "request",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/request.NginxCommonReq"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/websites/leech/update": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "更新防盗链配置",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Website"
|
||||
],
|
||||
"summary": "Update AntiLeech",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "request",
|
||||
"name": "request",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/request.NginxAntiLeechUpdate"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/websites/list": {
|
||||
"get": {
|
||||
"security": [
|
||||
@ -10691,6 +10757,9 @@ var doc = `{
|
||||
"script": {
|
||||
"type": "string"
|
||||
},
|
||||
"second": {
|
||||
"type": "integer"
|
||||
},
|
||||
"sourceDir": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -10770,6 +10839,9 @@ var doc = `{
|
||||
"script": {
|
||||
"type": "string"
|
||||
},
|
||||
"second": {
|
||||
"type": "integer"
|
||||
},
|
||||
"sourceDir": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -11531,6 +11603,17 @@ var doc = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.LogOption": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"logMaxFile": {
|
||||
"type": "string"
|
||||
},
|
||||
"logMaxSize": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.Login": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@ -12501,6 +12584,9 @@ var doc = `{
|
||||
"mfaStatus": {
|
||||
"type": "string"
|
||||
},
|
||||
"monitorInterval": {
|
||||
"type": "string"
|
||||
},
|
||||
"monitorStatus": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -13634,6 +13720,53 @@ var doc = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"request.NginxAntiLeechUpdate": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"enable",
|
||||
"extends",
|
||||
"return",
|
||||
"websiteID"
|
||||
],
|
||||
"properties": {
|
||||
"blocked": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"cache": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"cacheTime": {
|
||||
"type": "integer"
|
||||
},
|
||||
"cacheUint": {
|
||||
"type": "string"
|
||||
},
|
||||
"enable": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"extends": {
|
||||
"type": "string"
|
||||
},
|
||||
"logEnable": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"noneRef": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"return": {
|
||||
"type": "string"
|
||||
},
|
||||
"serverNames": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"websiteID": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"request.NginxAuthReq": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
@ -13671,6 +13804,17 @@ var doc = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"request.NginxCommonReq": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"websiteID"
|
||||
],
|
||||
"properties": {
|
||||
"websiteID": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"request.NginxConfigFileUpdate": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
@ -14198,9 +14342,15 @@ var doc = `{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"id",
|
||||
"params"
|
||||
"scope"
|
||||
],
|
||||
"properties": {
|
||||
"disableFunctions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
@ -14209,6 +14359,12 @@ var doc = `{
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"scope": {
|
||||
"type": "string"
|
||||
},
|
||||
"uploadMaxSize": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -14806,11 +14962,20 @@ var doc = `{
|
||||
"response.PHPConfig": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"disableFunctions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"uploadMaxSize": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -1227,14 +1227,14 @@
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "修改 docker 配置信息",
|
||||
"description": "修改 docker 日志配置",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Container Docker"
|
||||
],
|
||||
"summary": "Update docker daemon.json",
|
||||
"summary": "Update docker daemon.json log option",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "request",
|
||||
@ -1242,7 +1242,7 @@
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.DaemonJsonConf"
|
||||
"$ref": "#/definitions/dto.LogOption"
|
||||
}
|
||||
}
|
||||
],
|
||||
@ -1254,8 +1254,8 @@
|
||||
"x-panel-log": {
|
||||
"BeforeFuntions": [],
|
||||
"bodyKeys": [],
|
||||
"formatEN": "Updated the docker daemon.json configuration",
|
||||
"formatZH": "更新 docker daemon.json 配置",
|
||||
"formatEN": "Updated the docker daemon.json log option",
|
||||
"formatZH": "更新 docker daemon.json 日志配置",
|
||||
"paramKeys": []
|
||||
}
|
||||
}
|
||||
@ -9026,6 +9026,72 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/websites/leech": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "获取防盗链配置",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Website"
|
||||
],
|
||||
"summary": "Get AntiLeech conf",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "request",
|
||||
"name": "request",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/request.NginxCommonReq"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/websites/leech/update": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "更新防盗链配置",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Website"
|
||||
],
|
||||
"summary": "Update AntiLeech",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "request",
|
||||
"name": "request",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/request.NginxAntiLeechUpdate"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/websites/list": {
|
||||
"get": {
|
||||
"security": [
|
||||
@ -10677,6 +10743,9 @@
|
||||
"script": {
|
||||
"type": "string"
|
||||
},
|
||||
"second": {
|
||||
"type": "integer"
|
||||
},
|
||||
"sourceDir": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -10756,6 +10825,9 @@
|
||||
"script": {
|
||||
"type": "string"
|
||||
},
|
||||
"second": {
|
||||
"type": "integer"
|
||||
},
|
||||
"sourceDir": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -11517,6 +11589,17 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.LogOption": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"logMaxFile": {
|
||||
"type": "string"
|
||||
},
|
||||
"logMaxSize": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.Login": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@ -12487,6 +12570,9 @@
|
||||
"mfaStatus": {
|
||||
"type": "string"
|
||||
},
|
||||
"monitorInterval": {
|
||||
"type": "string"
|
||||
},
|
||||
"monitorStatus": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -13620,6 +13706,53 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"request.NginxAntiLeechUpdate": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"enable",
|
||||
"extends",
|
||||
"return",
|
||||
"websiteID"
|
||||
],
|
||||
"properties": {
|
||||
"blocked": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"cache": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"cacheTime": {
|
||||
"type": "integer"
|
||||
},
|
||||
"cacheUint": {
|
||||
"type": "string"
|
||||
},
|
||||
"enable": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"extends": {
|
||||
"type": "string"
|
||||
},
|
||||
"logEnable": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"noneRef": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"return": {
|
||||
"type": "string"
|
||||
},
|
||||
"serverNames": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"websiteID": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"request.NginxAuthReq": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
@ -13657,6 +13790,17 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"request.NginxCommonReq": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"websiteID"
|
||||
],
|
||||
"properties": {
|
||||
"websiteID": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"request.NginxConfigFileUpdate": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
@ -14184,9 +14328,15 @@
|
||||
"type": "object",
|
||||
"required": [
|
||||
"id",
|
||||
"params"
|
||||
"scope"
|
||||
],
|
||||
"properties": {
|
||||
"disableFunctions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
@ -14195,6 +14345,12 @@
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"scope": {
|
||||
"type": "string"
|
||||
},
|
||||
"uploadMaxSize": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -14792,11 +14948,20 @@
|
||||
"response.PHPConfig": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"disableFunctions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"uploadMaxSize": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -400,6 +400,8 @@ definitions:
|
||||
type: integer
|
||||
script:
|
||||
type: string
|
||||
second:
|
||||
type: integer
|
||||
sourceDir:
|
||||
type: string
|
||||
specType:
|
||||
@ -454,6 +456,8 @@ definitions:
|
||||
type: integer
|
||||
script:
|
||||
type: string
|
||||
second:
|
||||
type: integer
|
||||
sourceDir:
|
||||
type: string
|
||||
specType:
|
||||
@ -969,6 +973,13 @@ definitions:
|
||||
type:
|
||||
type: string
|
||||
type: object
|
||||
dto.LogOption:
|
||||
properties:
|
||||
logMaxFile:
|
||||
type: string
|
||||
logMaxSize:
|
||||
type: string
|
||||
type: object
|
||||
dto.Login:
|
||||
properties:
|
||||
authMethod:
|
||||
@ -1614,6 +1625,8 @@ definitions:
|
||||
type: string
|
||||
mfaStatus:
|
||||
type: string
|
||||
monitorInterval:
|
||||
type: string
|
||||
monitorStatus:
|
||||
type: string
|
||||
monitorStoreDays:
|
||||
@ -2367,6 +2380,38 @@ definitions:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
type: object
|
||||
request.NginxAntiLeechUpdate:
|
||||
properties:
|
||||
blocked:
|
||||
type: boolean
|
||||
cache:
|
||||
type: boolean
|
||||
cacheTime:
|
||||
type: integer
|
||||
cacheUint:
|
||||
type: string
|
||||
enable:
|
||||
type: boolean
|
||||
extends:
|
||||
type: string
|
||||
logEnable:
|
||||
type: boolean
|
||||
noneRef:
|
||||
type: boolean
|
||||
return:
|
||||
type: string
|
||||
serverNames:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
websiteID:
|
||||
type: integer
|
||||
required:
|
||||
- enable
|
||||
- extends
|
||||
- return
|
||||
- websiteID
|
||||
type: object
|
||||
request.NginxAuthReq:
|
||||
properties:
|
||||
websiteID:
|
||||
@ -2392,6 +2437,13 @@ definitions:
|
||||
- username
|
||||
- websiteID
|
||||
type: object
|
||||
request.NginxCommonReq:
|
||||
properties:
|
||||
websiteID:
|
||||
type: integer
|
||||
required:
|
||||
- websiteID
|
||||
type: object
|
||||
request.NginxConfigFileUpdate:
|
||||
properties:
|
||||
backup:
|
||||
@ -2745,15 +2797,23 @@ definitions:
|
||||
type: object
|
||||
request.WebsitePHPConfigUpdate:
|
||||
properties:
|
||||
disableFunctions:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
id:
|
||||
type: integer
|
||||
params:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
scope:
|
||||
type: string
|
||||
uploadMaxSize:
|
||||
type: string
|
||||
required:
|
||||
- id
|
||||
- params
|
||||
- scope
|
||||
type: object
|
||||
request.WebsitePHPFileUpdate:
|
||||
properties:
|
||||
@ -3154,10 +3214,16 @@ definitions:
|
||||
type: object
|
||||
response.PHPConfig:
|
||||
properties:
|
||||
disableFunctions:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
params:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
uploadMaxSize:
|
||||
type: string
|
||||
type: object
|
||||
response.WebsiteAcmeAccountDTO:
|
||||
properties:
|
||||
@ -4058,27 +4124,27 @@ paths:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 修改 docker 配置信息
|
||||
description: 修改 docker 日志配置
|
||||
parameters:
|
||||
- description: request
|
||||
in: body
|
||||
name: request
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/dto.DaemonJsonConf'
|
||||
$ref: '#/definitions/dto.LogOption'
|
||||
responses:
|
||||
"200":
|
||||
description: ""
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: Update docker daemon.json
|
||||
summary: Update docker daemon.json log option
|
||||
tags:
|
||||
- Container Docker
|
||||
x-panel-log:
|
||||
BeforeFuntions: []
|
||||
bodyKeys: []
|
||||
formatEN: Updated the docker daemon.json configuration
|
||||
formatZH: 更新 docker daemon.json 配置
|
||||
formatEN: Updated the docker daemon.json log option
|
||||
formatZH: 更新 docker daemon.json 日志配置
|
||||
paramKeys: []
|
||||
/containers/daemonjson/update/byfile:
|
||||
post:
|
||||
@ -9016,6 +9082,46 @@ paths:
|
||||
formatEN: Delete domain [domain]
|
||||
formatZH: 删除域名 [domain]
|
||||
paramKeys: []
|
||||
/websites/leech:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 获取防盗链配置
|
||||
parameters:
|
||||
- description: request
|
||||
in: body
|
||||
name: request
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/request.NginxCommonReq'
|
||||
responses:
|
||||
"200":
|
||||
description: ""
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: Get AntiLeech conf
|
||||
tags:
|
||||
- Website
|
||||
/websites/leech/update:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 更新防盗链配置
|
||||
parameters:
|
||||
- description: request
|
||||
in: body
|
||||
name: request
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/request.NginxAntiLeechUpdate'
|
||||
responses:
|
||||
"200":
|
||||
description: ""
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: Update AntiLeech
|
||||
tags:
|
||||
- Website
|
||||
/websites/list:
|
||||
get:
|
||||
description: 获取网站列表
|
||||
|
@ -148,8 +148,11 @@ export const loadDaemonJsonFile = () => {
|
||||
export const loadDockerStatus = () => {
|
||||
return http.get<string>(`/containers/docker/status`);
|
||||
};
|
||||
export const updateDaemonJson = (params: Container.DaemonJsonConf) => {
|
||||
return http.post(`/containers/daemonjson/update`, params);
|
||||
export const updateDaemonJson = (key: string, value: string) => {
|
||||
return http.post(`/containers/daemonjson/update`, { key: key, value: value }, 60000);
|
||||
};
|
||||
export const updateLogOption = (maxSize: string, maxFile: string) => {
|
||||
return http.post(`/containers/logoption/update`, { maxSize: maxSize, maxFile: maxFile }, 60000);
|
||||
};
|
||||
export const updateDaemonJsonByfile = (params: Container.DaemonJsonUpdateByFile) => {
|
||||
return http.post(`/containers/daemonjson/update/byfile`, params);
|
||||
|
@ -605,9 +605,9 @@ const message = {
|
||||
'Allows the running container state to be preserved in case of unexpected shutdown or crash of the Docker daemon',
|
||||
liveWithSwarmHelper: 'live-restore daemon configuration is incompatible with swarm mode.',
|
||||
iptablesDisable: 'Close iptables',
|
||||
iptablesHelper1: 'This setting will disable Docker automatic configuration of iptables rules.',
|
||||
iptablesHelper1: 'Automatic configuration of iptables rules for Docker.',
|
||||
iptablesHelper2:
|
||||
'This may cause the container to be unable to communicate with external networks. Do you want to continue?',
|
||||
'Disabling iptables will result in the containers being unable to communicate with external networks.',
|
||||
daemonJsonPath: 'Conf Path',
|
||||
serviceUnavailable: 'Docker service is not started at present, please click',
|
||||
startIn: ' to start',
|
||||
|
@ -616,8 +616,8 @@ const message = {
|
||||
liveHelper: '允许在 Docker 守护进程发生意外停机或崩溃时保留正在运行的容器状态',
|
||||
liveWithSwarmHelper: 'live-restore 守护进程配置与 Swarm 模式不兼容',
|
||||
iptablesDisable: '关闭 iptables',
|
||||
iptablesHelper1: '该设置将关闭 Docker 对 iptables 规则的自动配置',
|
||||
iptablesHelper2: '这可能会导致容器无法与外部网络通信,是否继续?',
|
||||
iptablesHelper1: 'Docker 对 iptables 规则的自动配置',
|
||||
iptablesHelper2: '关闭 iptables 会导致容器无法与外部网络通信。',
|
||||
daemonJsonPath: '配置路径',
|
||||
serviceUnavailable: '当前未启动 Docker 服务,请在',
|
||||
startIn: '中开启',
|
||||
|
@ -10,7 +10,7 @@
|
||||
<el-input clearable v-model.trim="form.name" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('container.image')" prop="image">
|
||||
<el-select style="width: 100%" allow-create filterable v-model="form.image">
|
||||
<el-select class="widthClass" allow-create filterable v-model="form.image">
|
||||
<el-option
|
||||
v-for="(item, index) of images"
|
||||
:key="index"
|
||||
@ -26,7 +26,7 @@
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="!form.publishAllPorts">
|
||||
<el-card style="width: 100%">
|
||||
<el-card class="widthClass">
|
||||
<table style="width: 100%" class="tab-table">
|
||||
<tr v-if="form.exposedPorts.length !== 0">
|
||||
<th scope="col" width="45%" align="left">
|
||||
@ -107,21 +107,21 @@
|
||||
<el-card style="width: 100%">
|
||||
<table style="width: 100%" class="tab-table">
|
||||
<tr v-if="form.volumes.length !== 0">
|
||||
<th scope="col" width="42%" align="left">
|
||||
<th scope="col" width="39%" align="left">
|
||||
<label>{{ $t('container.serverPath') }}</label>
|
||||
</th>
|
||||
<th scope="col" width="12%" align="left">
|
||||
<th scope="col" width="18%" align="left">
|
||||
<label>{{ $t('container.mode') }}</label>
|
||||
</th>
|
||||
<th scope="col" width="42%" align="left">
|
||||
<th scope="col" width="39%" align="left">
|
||||
<label>{{ $t('container.containerDir') }}</label>
|
||||
</th>
|
||||
<th align="left"></th>
|
||||
</tr>
|
||||
<tr v-for="(row, index) in form.volumes" :key="index">
|
||||
<td width="42%">
|
||||
<td width="39%">
|
||||
<el-select
|
||||
style="width: 100%"
|
||||
class="widthClass"
|
||||
allow-create
|
||||
clearable
|
||||
:placeholder="$t('commons.msg.inputOrSelect')"
|
||||
@ -136,13 +136,13 @@
|
||||
/>
|
||||
</el-select>
|
||||
</td>
|
||||
<td width="12%">
|
||||
<el-select style="width: 100%" filterable v-model="row.mode">
|
||||
<td width="18%">
|
||||
<el-select class="widthClass" filterable v-model="row.mode">
|
||||
<el-option value="rw" :label="$t('container.modeRW')" />
|
||||
<el-option value="ro" :label="$t('container.modeR')" />
|
||||
</el-select>
|
||||
</td>
|
||||
<td width="42%">
|
||||
<td width="39%">
|
||||
<el-input v-model="row.containerDir" />
|
||||
</td>
|
||||
<td>
|
||||
@ -416,3 +416,9 @@ defineExpose({
|
||||
acceptParams,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.widthClass {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
@ -46,12 +46,31 @@
|
||||
<el-col :span="10">
|
||||
<el-form :model="form" label-position="left" :rules="rules" ref="formRef" label-width="150px">
|
||||
<el-form-item :label="$t('container.mirrors')" prop="mirrors">
|
||||
<el-input
|
||||
type="textarea"
|
||||
:placeholder="$t('container.mirrorHelper')"
|
||||
:autosize="{ minRows: 3, maxRows: 10 }"
|
||||
v-model="form.mirrors"
|
||||
/>
|
||||
<div style="width: 100%">
|
||||
<el-input
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 3, maxRows: 5 }"
|
||||
disabled
|
||||
v-if="form.mirrors"
|
||||
v-model="form.mirrors"
|
||||
style="width: calc(100% - 80px)"
|
||||
/>
|
||||
<el-button
|
||||
v-if="form.mirrors"
|
||||
style="width: 80px"
|
||||
@click="onChangeMirrors"
|
||||
icon="Setting"
|
||||
>
|
||||
{{ $t('commons.button.set') }}
|
||||
</el-button>
|
||||
</div>
|
||||
<el-input disabled v-if="!form.mirrors" v-model="unset">
|
||||
<template #append>
|
||||
<el-button @click="onChangeMirrors" icon="Setting">
|
||||
{{ $t('commons.button.set') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
<span class="input-help">{{ $t('container.mirrorsHelper') }}</span>
|
||||
<span class="input-help">
|
||||
{{ $t('container.mirrorsHelper2') }}
|
||||
@ -66,60 +85,58 @@
|
||||
</span>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('container.registries')" prop="registries">
|
||||
<el-input
|
||||
type="textarea"
|
||||
:placeholder="$t('container.registrieHelper')"
|
||||
:autosize="{ minRows: 3, maxRows: 10 }"
|
||||
v-model="form.registries"
|
||||
/>
|
||||
<div style="width: 100%">
|
||||
<el-input
|
||||
v-if="form.registries"
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 3, maxRows: 5 }"
|
||||
disabled
|
||||
v-model="form.registries"
|
||||
style="width: calc(100% - 80px)"
|
||||
/>
|
||||
<el-button
|
||||
v-if="form.mirrors"
|
||||
style="width: 80px"
|
||||
@click="onChangeRegistries"
|
||||
icon="Setting"
|
||||
>
|
||||
{{ $t('commons.button.set') }}
|
||||
</el-button>
|
||||
</div>
|
||||
<el-input disabled v-if="!form.registries" v-model="unset">
|
||||
<template #append>
|
||||
<el-button @click="onChangeRegistries" icon="Setting">
|
||||
{{ $t('commons.button.set') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('container.cutLog')" prop="hasLogOption">
|
||||
<el-switch v-model="form.logOptionShow"></el-switch>
|
||||
<el-switch v-model="form.logOptionShow" @change="handleLogOption"></el-switch>
|
||||
</el-form-item>
|
||||
<div v-if="form.logOptionShow">
|
||||
<el-form-item prop="logMaxSize">
|
||||
<el-input v-model.number="form.logMaxSize">
|
||||
<template #prepend>{{ $t('container.maxSize') }}</template>
|
||||
<template #append>
|
||||
<el-select v-model="form.sizeUnit" style="width: 70px">
|
||||
<el-option label="b" value="b"></el-option>
|
||||
<el-option label="k" value="k"></el-option>
|
||||
<el-option label="m" value="m"></el-option>
|
||||
<el-option label="g" value="g"></el-option>
|
||||
<el-option label="t" value="t"></el-option>
|
||||
</el-select>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="logMaxFile">
|
||||
<el-input v-model.number="form.logMaxFile">
|
||||
<template #prepend>{{ $t('container.maxFile') }}</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</div>
|
||||
|
||||
<el-form-item label="iptables" prop="iptables">
|
||||
<el-switch v-model="form.iptables" @change="onChangeIptables"></el-switch>
|
||||
<el-switch v-model="form.iptables" @change="handleIptables"></el-switch>
|
||||
<span class="input-help">{{ $t('container.iptablesHelper1') }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="live-restore" prop="liveRestore">
|
||||
<el-switch :disabled="form.isSwarm" v-model="form.liveRestore"></el-switch>
|
||||
<el-switch
|
||||
:disabled="form.isSwarm"
|
||||
v-model="form.liveRestore"
|
||||
@change="handleLive"
|
||||
></el-switch>
|
||||
<span class="input-help">{{ $t('container.liveHelper') }}</span>
|
||||
<span v-if="form.isSwarm" class="input-help">
|
||||
{{ $t('container.liveWithSwarmHelper') }}
|
||||
</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="cgroup-driver" prop="cgroupDriver">
|
||||
<el-radio-group v-model="form.cgroupDriver">
|
||||
<el-radio-group v-model="form.cgroupDriver" @change="handleCgroup">
|
||||
<el-radio label="cgroupfs">cgroupfs</el-radio>
|
||||
<el-radio label="systemd">systemd</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button :disabled="loading" type="primary" @click="onSave(formRef)">
|
||||
{{ $t('commons.button.save') }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@ -154,21 +171,47 @@
|
||||
:close-on-press-escape="false"
|
||||
:show-close="false"
|
||||
>
|
||||
<span>{{ $t('container.iptablesHelper1') }}</span>
|
||||
<div style="margin-top: 10px">
|
||||
<span style="color: red; font-weight: 500">{{ $t('container.iptablesHelper2') }}</span>
|
||||
<span style="color: red">{{ $t('container.iptablesHelper2') }}</span>
|
||||
<div style="margin-top: 10px">
|
||||
<span style="font-size: 12px">{{ $t('database.restartNowHelper') }}</span>
|
||||
</div>
|
||||
<div style="margin-top: 10px">
|
||||
<span style="font-size: 12px">{{ $t('commons.msg.operateConfirm') }}</span>
|
||||
<span style="font-size: 12px; color: red; font-weight: 500">'{{ $t('database.restartNow') }}'</span>
|
||||
</div>
|
||||
<el-input style="margin-top: 10px" v-model="submitInput"></el-input>
|
||||
</div>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="onSaveIptables(true)">{{ $t('commons.button.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="onSaveIptables(false)">
|
||||
<el-button
|
||||
@click="
|
||||
iptablesVisiable = false;
|
||||
search();
|
||||
"
|
||||
>
|
||||
{{ $t('commons.button.cancel') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
:disabled="submitInput !== $t('database.restartNow')"
|
||||
type="primary"
|
||||
@click="onSubmitCloseIPtable"
|
||||
>
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<ConfirmDialog ref="confirmDialogRef" @confirm="onSubmitSave"></ConfirmDialog>
|
||||
<Mirror ref="mirrorRef" @search="search" />
|
||||
<Registry ref="registriesRef" @search="search" />
|
||||
<LogOption ref="logOptionRef" @search="search" />
|
||||
<ConfirmDialog ref="confirmDialogRefIptable" @confirm="onSubmitOpenIPtable" @cancle="search" />
|
||||
<ConfirmDialog ref="confirmDialogRefLog" @confirm="onSubmitSaveLog" @cancle="search" />
|
||||
<ConfirmDialog ref="confirmDialogRefLive" @confirm="onSubmitSaveLive" @cancle="search" />
|
||||
<ConfirmDialog ref="confirmDialogRefCgroup" @confirm="onSubmitSaveCgroup" @cancle="search" />
|
||||
|
||||
<ConfirmDialog ref="confirmDialogRefFile" @confirm="onSubmitSaveFile" @cancle="search" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -178,6 +221,9 @@ import { onMounted, reactive, ref } from 'vue';
|
||||
import { Codemirror } from 'vue-codemirror';
|
||||
import { javascript } from '@codemirror/lang-javascript';
|
||||
import { oneDark } from '@codemirror/theme-one-dark';
|
||||
import Mirror from '@/views/container/setting/mirror/index.vue';
|
||||
import Registry from '@/views/container/setting/registry/index.vue';
|
||||
import LogOption from '@/views/container/setting/log/index.vue';
|
||||
import ConfirmDialog from '@/components/confirm-dialog/index.vue';
|
||||
import i18n from '@/lang';
|
||||
import {
|
||||
@ -190,11 +236,22 @@ import {
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { checkNumberRange } from '@/global/form-rules';
|
||||
|
||||
const unset = ref(i18n.global.t('setting.unSetting'));
|
||||
const submitInput = ref();
|
||||
|
||||
const loading = ref(false);
|
||||
const showDaemonJsonAlert = ref(false);
|
||||
const extensions = [javascript(), oneDark];
|
||||
const confShowType = ref('base');
|
||||
|
||||
const logOptionRef = ref();
|
||||
const confirmDialogRefLog = ref();
|
||||
const mirrorRef = ref();
|
||||
const registriesRef = ref();
|
||||
const confirmDialogRefLive = ref();
|
||||
const confirmDialogRefCgroup = ref();
|
||||
const confirmDialogRefIptable = ref();
|
||||
|
||||
const form = reactive({
|
||||
isSwarm: false,
|
||||
status: '',
|
||||
@ -205,8 +262,7 @@ const form = reactive({
|
||||
iptables: true,
|
||||
cgroupDriver: '',
|
||||
logOptionShow: false,
|
||||
logMaxSize: 10,
|
||||
sizeUnit: 'm',
|
||||
logMaxSize: '',
|
||||
logMaxFile: 3,
|
||||
});
|
||||
const rules = reactive({
|
||||
@ -220,19 +276,6 @@ const confirmDialogRef = ref();
|
||||
|
||||
const iptablesVisiable = ref();
|
||||
|
||||
const onSave = async (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return;
|
||||
formEl.validate(async (valid) => {
|
||||
if (!valid) return;
|
||||
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 onSaveFile = async () => {
|
||||
let params = {
|
||||
header: i18n.global.t('database.confChange'),
|
||||
@ -242,19 +285,87 @@ const onSaveFile = async () => {
|
||||
confirmDialogRef.value!.acceptParams(params);
|
||||
};
|
||||
|
||||
const toDoc = () => {
|
||||
window.open('https://1panel.cn/docs/user_manual/containers/setting/', '_blank');
|
||||
const onChangeMirrors = () => {
|
||||
mirrorRef.value.acceptParams({ mirrors: form.mirrors });
|
||||
};
|
||||
const onChangeRegistries = () => {
|
||||
registriesRef.value.acceptParams({ registries: form.registries });
|
||||
};
|
||||
const handleLogOption = async () => {
|
||||
if (form.logOptionShow) {
|
||||
logOptionRef.value.acceptParams({ logMaxSize: form.logMaxSize, logMaxFile: form.logMaxFile });
|
||||
return;
|
||||
}
|
||||
let params = {
|
||||
header: i18n.global.t('database.confChange'),
|
||||
operationInfo: i18n.global.t('database.restartNowHelper'),
|
||||
submitInputInfo: i18n.global.t('database.restartNow'),
|
||||
};
|
||||
confirmDialogRefLog.value!.acceptParams(params);
|
||||
};
|
||||
const onSubmitSaveLog = async () => {
|
||||
save('LogOption', 'disable');
|
||||
};
|
||||
|
||||
const onChangeIptables = () => {
|
||||
if (!form.iptables) {
|
||||
const handleIptables = () => {
|
||||
if (form.iptables) {
|
||||
let params = {
|
||||
header: i18n.global.t('database.confChange'),
|
||||
operationInfo: i18n.global.t('database.restartNowHelper'),
|
||||
submitInputInfo: i18n.global.t('database.restartNow'),
|
||||
};
|
||||
confirmDialogRefIptable.value!.acceptParams(params);
|
||||
return;
|
||||
} else {
|
||||
iptablesVisiable.value = true;
|
||||
}
|
||||
};
|
||||
const onSubmitCloseIPtable = () => {
|
||||
save('IPtables', 'disable');
|
||||
};
|
||||
const onSubmitOpenIPtable = () => {
|
||||
save('IPtables', 'enable');
|
||||
};
|
||||
|
||||
const onSaveIptables = (status: boolean) => {
|
||||
form.iptables = status;
|
||||
iptablesVisiable.value = false;
|
||||
const handleLive = async () => {
|
||||
let params = {
|
||||
header: i18n.global.t('database.confChange'),
|
||||
operationInfo: i18n.global.t('database.restartNowHelper'),
|
||||
submitInputInfo: i18n.global.t('database.restartNow'),
|
||||
};
|
||||
confirmDialogRefLive.value!.acceptParams(params);
|
||||
};
|
||||
const onSubmitSaveLive = () => {
|
||||
save('LiveRestore', form.liveRestore ? 'enable' : 'disable');
|
||||
};
|
||||
const handleCgroup = async () => {
|
||||
let params = {
|
||||
header: i18n.global.t('database.confChange'),
|
||||
operationInfo: i18n.global.t('database.restartNowHelper'),
|
||||
submitInputInfo: i18n.global.t('database.restartNow'),
|
||||
};
|
||||
confirmDialogRefCgroup.value!.acceptParams(params);
|
||||
};
|
||||
const onSubmitSaveCgroup = () => {
|
||||
save('Dirver', form.cgroupDriver);
|
||||
};
|
||||
|
||||
const save = async (key: string, value: string) => {
|
||||
loading.value = true;
|
||||
await updateDaemonJson(key, value)
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
search();
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
})
|
||||
.catch(() => {
|
||||
search();
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
const toDoc = () => {
|
||||
window.open('https://1panel.cn/docs/user_manual/containers/setting/', '_blank');
|
||||
};
|
||||
|
||||
const onOperator = async (operation: string) => {
|
||||
@ -281,53 +392,18 @@ const onOperator = async (operation: string) => {
|
||||
});
|
||||
};
|
||||
|
||||
const onSubmitSave = async () => {
|
||||
if (confShowType.value === 'all') {
|
||||
let param = { file: dockerConf.value };
|
||||
loading.value = true;
|
||||
await updateDaemonJsonByfile(param)
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
return;
|
||||
}
|
||||
let itemMirrors = form.mirrors.split('\n');
|
||||
let itemRegistries = form.registries.split('\n');
|
||||
let param = {
|
||||
isSwarm: form.isSwarm,
|
||||
status: form.status,
|
||||
version: '',
|
||||
registryMirrors: itemMirrors.filter(function (el) {
|
||||
return el !== null && el !== '' && el !== undefined;
|
||||
}),
|
||||
insecureRegistries: itemRegistries.filter(function (el) {
|
||||
return el !== null && el !== '' && el !== undefined;
|
||||
}),
|
||||
liveRestore: form.liveRestore,
|
||||
iptables: form.iptables,
|
||||
cgroupDriver: form.cgroupDriver,
|
||||
logMaxSize: form.logMaxSize + form.sizeUnit,
|
||||
logMaxFile: form.logMaxFile + '',
|
||||
};
|
||||
if (!form.logOptionShow) {
|
||||
param.logMaxFile = '';
|
||||
param.logMaxSize = '';
|
||||
}
|
||||
|
||||
const onSubmitSaveFile = async () => {
|
||||
let param = { file: dockerConf.value };
|
||||
loading.value = true;
|
||||
await updateDaemonJson(param)
|
||||
await updateDaemonJsonByfile(param)
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
search();
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
return;
|
||||
};
|
||||
|
||||
const loadDockerConf = async () => {
|
||||
@ -349,49 +425,21 @@ const changeMode = async () => {
|
||||
};
|
||||
|
||||
const search = async () => {
|
||||
loading.value = true;
|
||||
await loadDaemonJson()
|
||||
.then((res) => {
|
||||
loading.value = false;
|
||||
form.isSwarm = res.data.isSwarm;
|
||||
form.status = res.data.status;
|
||||
form.version = res.data.version;
|
||||
form.cgroupDriver = res.data.cgroupDriver;
|
||||
form.liveRestore = res.data.liveRestore;
|
||||
form.iptables = res.data.iptables;
|
||||
form.mirrors = res.data.registryMirrors ? res.data.registryMirrors.join('\n') : '';
|
||||
form.registries = res.data.insecureRegistries ? res.data.insecureRegistries.join('\n') : '';
|
||||
if (res.data.logMaxFile || res.data.logMaxSize) {
|
||||
form.logOptionShow = true;
|
||||
}
|
||||
form.logMaxFile = Number(res.data.logMaxFile);
|
||||
form.logMaxSize = loadSize(res.data.logMaxSize);
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
const loadSize = (value: string) => {
|
||||
if (value.indexOf('b') !== -1 || value.indexOf('B') !== -1) {
|
||||
form.sizeUnit = 'b';
|
||||
return Number(value.replaceAll('b', '').replaceAll('B', ''));
|
||||
}
|
||||
if (value.indexOf('k') !== -1 || value.indexOf('K') !== -1) {
|
||||
form.sizeUnit = 'k';
|
||||
return Number(value.replaceAll('k', '').replaceAll('K', ''));
|
||||
}
|
||||
if (value.indexOf('m') !== -1 || value.indexOf('M') !== -1) {
|
||||
form.sizeUnit = 'm';
|
||||
return Number(value.replaceAll('m', '').replaceAll('M', ''));
|
||||
}
|
||||
if (value.indexOf('g') !== -1 || value.indexOf('G') !== -1) {
|
||||
form.sizeUnit = 'g';
|
||||
return Number(value.replaceAll('g', '').replaceAll('G', ''));
|
||||
}
|
||||
if (value.indexOf('t') !== -1 || value.indexOf('T') !== -1) {
|
||||
form.sizeUnit = 't';
|
||||
return Number(value.replaceAll('t', '').replaceAll('T', ''));
|
||||
const res = await loadDaemonJson();
|
||||
form.isSwarm = res.data.isSwarm;
|
||||
form.status = res.data.status;
|
||||
form.version = res.data.version;
|
||||
form.cgroupDriver = res.data.cgroupDriver || 'cgroupfs';
|
||||
form.liveRestore = res.data.liveRestore;
|
||||
form.iptables = res.data.iptables;
|
||||
form.mirrors = res.data.registryMirrors ? res.data.registryMirrors.join('\n') : '';
|
||||
form.registries = res.data.insecureRegistries ? res.data.insecureRegistries.join('\n') : '';
|
||||
if (res.data.logMaxFile || res.data.logMaxSize) {
|
||||
form.logOptionShow = true;
|
||||
form.logMaxFile = Number(res.data.logMaxFile);
|
||||
form.logMaxSize = res.data.logMaxSize;
|
||||
} else {
|
||||
form.logOptionShow = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
147
frontend/src/views/container/setting/log/index.vue
Normal file
147
frontend/src/views/container/setting/log/index.vue
Normal file
@ -0,0 +1,147 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-drawer
|
||||
v-model="drawerVisiable"
|
||||
:destroy-on-close="true"
|
||||
:close-on-click-modal="false"
|
||||
@close="handleClose"
|
||||
size="30%"
|
||||
>
|
||||
<template #header>
|
||||
<DrawerHeader :header="$t('container.cutLog')" :back="handleClose" />
|
||||
</template>
|
||||
<el-form :model="form" ref="formRef" :rules="rules" v-loading="loading" label-position="top">
|
||||
<el-row type="flex" justify="center">
|
||||
<el-col :span="22">
|
||||
<el-form-item prop="logMaxSize" :label="$t('container.maxSize')">
|
||||
<el-input v-model.number="form.logMaxSize">
|
||||
<template #append>
|
||||
<el-select v-model="form.sizeUnit" style="width: 70px">
|
||||
<el-option label="B" value="B"></el-option>
|
||||
<el-option label="KB" value="KB"></el-option>
|
||||
<el-option label="MB" value="MB"></el-option>
|
||||
<el-option label="GB" value="GB"></el-option>
|
||||
</el-select>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="logMaxFile" :label="$t('container.maxFile')">
|
||||
<el-input v-model.number="form.logMaxFile" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="handleClose">{{ $t('commons.button.cancel') }}</el-button>
|
||||
<el-button :disabled="loading" type="primary" @click="onSave(formRef)">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-drawer>
|
||||
|
||||
<ConfirmDialog ref="confirmDialogRef" @confirm="onSubmitSave"></ConfirmDialog>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue';
|
||||
import { Rules, checkNumberRange } from '@/global/form-rules';
|
||||
import i18n from '@/lang';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { FormInstance } from 'element-plus';
|
||||
import { updateLogOption } from '@/api/modules/container';
|
||||
|
||||
const loading = ref();
|
||||
const drawerVisiable = ref();
|
||||
const confirmDialogRef = ref();
|
||||
const formRef = ref();
|
||||
|
||||
interface DialogProps {
|
||||
logMaxSize: string;
|
||||
logMaxFile: number;
|
||||
}
|
||||
|
||||
const form = reactive({
|
||||
logMaxSize: 10,
|
||||
logMaxFile: 3,
|
||||
sizeUnit: 'MB',
|
||||
});
|
||||
const rules = reactive({
|
||||
logMaxSize: [checkNumberRange(1, 1024000), Rules.number],
|
||||
logMaxFile: [checkNumberRange(1, 100), Rules.number],
|
||||
});
|
||||
|
||||
const emit = defineEmits<{ (e: 'search'): void }>();
|
||||
|
||||
const acceptParams = (params: DialogProps): void => {
|
||||
form.logMaxFile = params.logMaxFile || 3;
|
||||
if (params.logMaxSize) {
|
||||
form.logMaxSize = loadSize(params.logMaxSize);
|
||||
} else {
|
||||
form.logMaxSize = 10;
|
||||
form.sizeUnit = 'MB';
|
||||
}
|
||||
drawerVisiable.value = true;
|
||||
};
|
||||
|
||||
const onSave = 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 onSubmitSave = async () => {
|
||||
loading.value = true;
|
||||
await updateLogOption(form.logMaxSize + '', form.logMaxFile + '')
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
drawerVisiable.value = false;
|
||||
emit('search');
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
const loadSize = (value: string) => {
|
||||
if (value.indexOf('b') !== -1 || value.indexOf('B') !== -1) {
|
||||
form.sizeUnit = 'B';
|
||||
return Number(value.replaceAll('b', '').replaceAll('B', ''));
|
||||
}
|
||||
if (value.indexOf('k') !== -1 || value.indexOf('K') !== -1) {
|
||||
form.sizeUnit = 'KB';
|
||||
return Number(value.replaceAll('k', '').replaceAll('K', ''));
|
||||
}
|
||||
if (value.indexOf('m') !== -1 || value.indexOf('M') !== -1) {
|
||||
form.sizeUnit = 'MB';
|
||||
return Number(value.replaceAll('m', '').replaceAll('M', ''));
|
||||
}
|
||||
if (value.indexOf('g') !== -1 || value.indexOf('G') !== -1) {
|
||||
form.sizeUnit = 'GB';
|
||||
return Number(value.replaceAll('g', '').replaceAll('G', ''));
|
||||
}
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
emit('search');
|
||||
drawerVisiable.value = false;
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
acceptParams,
|
||||
});
|
||||
</script>
|
||||
<style scoped>
|
||||
.help-ul {
|
||||
color: #8f959e;
|
||||
}
|
||||
</style>
|
86
frontend/src/views/container/setting/mirror/index.vue
Normal file
86
frontend/src/views/container/setting/mirror/index.vue
Normal file
@ -0,0 +1,86 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-drawer v-model="drawerVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="30%">
|
||||
<template #header>
|
||||
<DrawerHeader :header="$t('container.mirrors')" :back="handleClose" />
|
||||
</template>
|
||||
<el-form label-position="top" @submit.prevent v-loading="loading">
|
||||
<el-row type="flex" justify="center">
|
||||
<el-col :span="22">
|
||||
<el-form-item :label="$t('container.mirrors')">
|
||||
<el-input
|
||||
type="textarea"
|
||||
:placeholder="$t('container.mirrorHelper')"
|
||||
:autosize="{ minRows: 8, maxRows: 10 }"
|
||||
v-model="mirrors"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="drawerVisiable = false">{{ $t('commons.button.cancel') }}</el-button>
|
||||
<el-button :disabled="loading" type="primary" @click="onSave">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-drawer>
|
||||
|
||||
<ConfirmDialog ref="confirmDialogRef" @confirm="onSubmit" />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import i18n from '@/lang';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import ConfirmDialog from '@/components/confirm-dialog/index.vue';
|
||||
import { updateDaemonJson } from '@/api/modules/container';
|
||||
|
||||
const emit = defineEmits<{ (e: 'search'): void }>();
|
||||
|
||||
const confirmDialogRef = ref();
|
||||
|
||||
const mirrors = ref();
|
||||
interface DialogProps {
|
||||
mirrors: string;
|
||||
}
|
||||
const drawerVisiable = ref();
|
||||
const loading = ref();
|
||||
|
||||
const acceptParams = (params: DialogProps): void => {
|
||||
mirrors.value = params.mirrors || params.mirrors.replaceAll(',', '\n');
|
||||
drawerVisiable.value = true;
|
||||
};
|
||||
|
||||
const onSave = async () => {
|
||||
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 onSubmit = async () => {
|
||||
loading.value = true;
|
||||
await updateDaemonJson('Mirrors', mirrors.value.replaceAll('\n', ','))
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
emit('search');
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
drawerVisiable.value = false;
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
acceptParams,
|
||||
});
|
||||
</script>
|
86
frontend/src/views/container/setting/registry/index.vue
Normal file
86
frontend/src/views/container/setting/registry/index.vue
Normal file
@ -0,0 +1,86 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-drawer v-model="drawerVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="30%">
|
||||
<template #header>
|
||||
<DrawerHeader :header="$t('container.registries')" :back="handleClose" />
|
||||
</template>
|
||||
<el-form label-position="top" @submit.prevent v-loading="loading">
|
||||
<el-row type="flex" justify="center">
|
||||
<el-col :span="22">
|
||||
<el-form-item :label="$t('container.registries')">
|
||||
<el-input
|
||||
type="textarea"
|
||||
:placeholder="$t('container.registrieHelper')"
|
||||
:autosize="{ minRows: 8, maxRows: 10 }"
|
||||
v-model="registries"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="drawerVisiable = false">{{ $t('commons.button.cancel') }}</el-button>
|
||||
<el-button :disabled="loading" type="primary" @click="onSave">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-drawer>
|
||||
|
||||
<ConfirmDialog ref="confirmDialogRef" @confirm="onSubmit" />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import i18n from '@/lang';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import ConfirmDialog from '@/components/confirm-dialog/index.vue';
|
||||
import { updateDaemonJson } from '@/api/modules/container';
|
||||
|
||||
const emit = defineEmits<{ (e: 'search'): void }>();
|
||||
|
||||
const confirmDialogRef = ref();
|
||||
|
||||
const registries = ref();
|
||||
interface DialogProps {
|
||||
registries: string;
|
||||
}
|
||||
const drawerVisiable = ref();
|
||||
const loading = ref();
|
||||
|
||||
const acceptParams = (params: DialogProps): void => {
|
||||
registries.value = params.registries || params.registries.replaceAll(',', '\n');
|
||||
drawerVisiable.value = true;
|
||||
};
|
||||
|
||||
const onSave = async () => {
|
||||
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 onSubmit = async () => {
|
||||
loading.value = true;
|
||||
await updateDaemonJson('Registries', registries.value.replaceAll('\n', ','))
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
emit('search');
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
drawerVisiable.value = false;
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
acceptParams,
|
||||
});
|
||||
</script>
|
Loading…
Reference in New Issue
Block a user