1
0
mirror of https://github.com/1Panel-dev/1Panel.git synced 2025-03-15 02:04:46 +08:00

fix: 镜像仓库增加同步功能

This commit is contained in:
ssongliu 2023-02-27 11:46:23 +08:00 committed by ssongliu
parent 8b9cc1bee8
commit b3a69725bf
12 changed files with 280 additions and 165 deletions

View File

@ -57,11 +57,37 @@ func (b *BaseApi) ListRepo(c *gin.Context) {
helper.SuccessWithData(c, list) helper.SuccessWithData(c, list)
} }
// @Tags Container Image-repo
// @Summary Load repo status
// @Description 获取 docker 仓库状态
// @Accept json
// @Param request body dto.OperateByID true "request"
// @Produce json
// @Success 200
// @Security ApiKeyAuth
// @Router /containers/repo/status [get]
func (b *BaseApi) CheckRepoStatus(c *gin.Context) {
var req dto.OperateByID
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := imageRepoService.Login(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
// @Tags Container Image-repo // @Tags Container Image-repo
// @Summary Create image repo // @Summary Create image repo
// @Description 创建镜像仓库 // @Description 创建镜像仓库
// @Accept json // @Accept json
// @Param request body dto.ImageRepoCreate true "request" // @Param request body dto.ImageRepoDelete true "request"
// @Produce json // @Produce json
// @Success 200 // @Success 200
// @Security ApiKeyAuth // @Security ApiKeyAuth

View File

@ -23,6 +23,7 @@ type ImageRepoService struct{}
type IImageRepoService interface { type IImageRepoService interface {
Page(search dto.SearchWithPage) (int64, interface{}, error) Page(search dto.SearchWithPage) (int64, interface{}, error)
List() ([]dto.ImageRepoOption, error) List() ([]dto.ImageRepoOption, error)
Login(req dto.OperateByID) error
Create(req dto.ImageRepoCreate) error Create(req dto.ImageRepoCreate) error
Update(req dto.ImageRepoUpdate) error Update(req dto.ImageRepoUpdate) error
BatchDelete(req dto.ImageRepoDelete) error BatchDelete(req dto.ImageRepoDelete) error
@ -45,6 +46,19 @@ func (u *ImageRepoService) Page(req dto.SearchWithPage) (int64, interface{}, err
return total, dtoOps, err return total, dtoOps, err
} }
func (u *ImageRepoService) Login(req dto.OperateByID) error {
repo, err := imageRepoRepo.Get(commonRepo.WithByID(req.ID))
if err != nil {
return err
}
if err := u.CheckConn(repo.DownloadUrl, repo.Username, repo.Password); err != nil {
_ = imageRepoRepo.Update(repo.ID, map[string]interface{}{"status": constant.StatusFailed, "message": err.Error})
return err
}
_ = imageRepoRepo.Update(repo.ID, map[string]interface{}{"status": constant.StatusSuccess})
return nil
}
func (u *ImageRepoService) List() ([]dto.ImageRepoOption, error) { func (u *ImageRepoService) List() ([]dto.ImageRepoOption, error) {
ops, err := imageRepoRepo.List(commonRepo.WithOrderBy("created_at desc")) ops, err := imageRepoRepo.List(commonRepo.WithOrderBy("created_at desc"))
var dtoOps []dto.ImageRepoOption var dtoOps []dto.ImageRepoOption
@ -67,22 +81,30 @@ func (u *ImageRepoService) Create(req dto.ImageRepoCreate) error {
} }
if req.Protocol == "http" { if req.Protocol == "http" {
_ = u.handleRegistries(req.DownloadUrl, "", "create") _ = u.handleRegistries(req.DownloadUrl, "", "create")
stdout, err := cmd.Exec("systemctl restart docker")
if err != nil {
return errors.New(string(stdout))
}
ticker := time.NewTicker(3 * time.Second) ticker := time.NewTicker(3 * time.Second)
ctx, cancle := context.WithTimeout(context.Background(), time.Second*20) ctx, cancle := context.WithTimeout(context.Background(), time.Second*20)
for range ticker.C { if err := func() error {
select { for range ticker.C {
case <-ctx.Done(): select {
cancle() case <-ctx.Done():
return errors.New("the docker service cannot be restarted")
default:
stdout, err := cmd.Exec("systemctl is-active docker")
if string(stdout) == "active\n" && err == nil {
global.LOG.Info("docker restart with new conf successful!")
cancle() cancle()
return errors.New("the docker service cannot be restarted")
default:
stdout, err := cmd.Exec("systemctl is-active docker")
if string(stdout) == "active\n" && err == nil {
global.LOG.Info("docker restart with new conf successful!")
return nil
}
} }
} }
return nil
}(); err != nil {
return err
} }
cancle()
} }
if err := copier.Copy(&imageRepo, &req); err != nil { if err := copier.Copy(&imageRepo, &req); err != nil {
@ -90,7 +112,7 @@ func (u *ImageRepoService) Create(req dto.ImageRepoCreate) error {
} }
imageRepo.Status = constant.StatusSuccess imageRepo.Status = constant.StatusSuccess
if err := u.checkConn(req.DownloadUrl, req.Username, req.Password); err != nil { if err := u.CheckConn(req.DownloadUrl, req.Username, req.Password); err != nil {
imageRepo.Status = constant.StatusFailed imageRepo.Status = constant.StatusFailed
imageRepo.Message = err.Error() imageRepo.Message = err.Error()
} }
@ -141,14 +163,14 @@ func (u *ImageRepoService) Update(req dto.ImageRepoUpdate) error {
upMap["status"] = constant.StatusSuccess upMap["status"] = constant.StatusSuccess
upMap["message"] = "" upMap["message"] = ""
if err := u.checkConn(req.DownloadUrl, req.Username, req.Password); err != nil { if err := u.CheckConn(req.DownloadUrl, req.Username, req.Password); err != nil {
upMap["status"] = constant.StatusFailed upMap["status"] = constant.StatusFailed
upMap["message"] = err.Error() upMap["message"] = err.Error()
} }
return imageRepoRepo.Update(req.ID, upMap) return imageRepoRepo.Update(req.ID, upMap)
} }
func (u *ImageRepoService) checkConn(host, user, password string) error { func (u *ImageRepoService) CheckConn(host, user, password string) error {
stdout, err := cmd.Execf("docker login -u %s -p %s %s", user, password, host) stdout, err := cmd.Execf("docker login -u %s -p %s %s", user, password, host)
if err != nil { if err != nil {
return errors.New(string(stdout)) return errors.New(string(stdout))

View File

@ -25,6 +25,7 @@ func (s *ContainerRouter) InitContainerRouter(Router *gin.RouterGroup) {
baRouter.POST("/operate", baseApi.ContainerOperation) baRouter.POST("/operate", baseApi.ContainerOperation)
baRouter.GET("/repo", baseApi.ListRepo) baRouter.GET("/repo", baseApi.ListRepo)
baRouter.POST("/repo/status", baseApi.CheckRepoStatus)
baRouter.POST("/repo/search", baseApi.SearchRepo) baRouter.POST("/repo/search", baseApi.SearchRepo)
baRouter.POST("/repo/update", baseApi.UpdateRepo) baRouter.POST("/repo/update", baseApi.UpdateRepo)
baRouter.POST("/repo", baseApi.CreateRepo) baRouter.POST("/repo", baseApi.CreateRepo)

View File

@ -1947,7 +1947,7 @@ var doc = `{
"in": "body", "in": "body",
"required": true, "required": true,
"schema": { "schema": {
"$ref": "#/definitions/dto.ImageRepoCreate" "$ref": "#/definitions/dto.ImageRepoDelete"
} }
} }
], ],
@ -2060,6 +2060,42 @@ var doc = `{
} }
} }
}, },
"/containers/repo/status": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "获取 docker 仓库状态",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Container Image-repo"
],
"summary": "Load repo status",
"parameters": [
{
"description": "request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.OperateByID"
}
}
],
"responses": {
"200": {
"description": ""
}
}
}
},
"/containers/repo/update": { "/containers/repo/update": {
"post": { "post": {
"security": [ "security": [
@ -5475,18 +5511,18 @@ var doc = `{
} }
} }
}, },
"/nginx": { "/openResty": {
"get": { "get": {
"security": [ "security": [
{ {
"ApiKeyAuth": [] "ApiKeyAuth": []
} }
], ],
"description": "获取 nginx 配置信息", "description": "获取 OpenResty 配置信息",
"tags": [ "tags": [
"Nginx" "OpenResty"
], ],
"summary": "Load nginx conf", "summary": "Load OpenResty conf",
"responses": { "responses": {
"200": { "200": {
"description": "OK", "description": "OK",
@ -5497,21 +5533,21 @@ var doc = `{
} }
} }
}, },
"/nginx/file": { "/openResty/file": {
"post": { "post": {
"security": [ "security": [
{ {
"ApiKeyAuth": [] "ApiKeyAuth": []
} }
], ],
"description": "上传更新 nginx 配置文件", "description": "上传更新 OpenResty 配置文件",
"consumes": [ "consumes": [
"application/json" "application/json"
], ],
"tags": [ "tags": [
"Nginx" "OpenResty"
], ],
"summary": "Update nginx conf by upload file", "summary": "Update OpenResty conf by upload file",
"parameters": [ "parameters": [
{ {
"description": "request", "description": "request",
@ -5537,21 +5573,21 @@ var doc = `{
} }
} }
}, },
"/nginx/scope": { "/openResty/scope": {
"post": { "post": {
"security": [ "security": [
{ {
"ApiKeyAuth": [] "ApiKeyAuth": []
} }
], ],
"description": "获取部分 nginx 配置信息", "description": "获取部分 OpenResty 配置信息",
"consumes": [ "consumes": [
"application/json" "application/json"
], ],
"tags": [ "tags": [
"Nginx" "OpenResty"
], ],
"summary": "Load partial nginx conf", "summary": "Load partial OpenResty conf",
"parameters": [ "parameters": [
{ {
"description": "request", "description": "request",
@ -5573,18 +5609,18 @@ var doc = `{
} }
} }
}, },
"/nginx/status": { "/openResty/status": {
"get": { "get": {
"security": [ "security": [
{ {
"ApiKeyAuth": [] "ApiKeyAuth": []
} }
], ],
"description": "获取 nginx 状态信息", "description": "获取 OpenResty 状态信息",
"tags": [ "tags": [
"Nginx" "OpenResty"
], ],
"summary": "Load nginx status info", "summary": "Load OpenResty status info",
"responses": { "responses": {
"200": { "200": {
"description": "OK", "description": "OK",
@ -5595,21 +5631,21 @@ var doc = `{
} }
} }
}, },
"/nginx/update": { "/openResty/update": {
"post": { "post": {
"security": [ "security": [
{ {
"ApiKeyAuth": [] "ApiKeyAuth": []
} }
], ],
"description": "更新 nginx 配置信息", "description": "更新 OpenResty 配置信息",
"consumes": [ "consumes": [
"application/json" "application/json"
], ],
"tags": [ "tags": [
"Nginx" "OpenResty"
], ],
"summary": "Update nginx conf", "summary": "Update OpenResty conf",
"parameters": [ "parameters": [
{ {
"description": "request", "description": "request",
@ -9589,41 +9625,12 @@ var doc = `{
} }
} }
}, },
"dto.ImageRepoCreate": {
"type": "object",
"required": [
"name"
],
"properties": {
"auth": {
"type": "boolean"
},
"downloadUrl": {
"type": "string"
},
"name": {
"type": "string"
},
"password": {
"type": "string"
},
"protocol": {
"type": "string"
},
"username": {
"type": "string"
}
}
},
"dto.ImageRepoDelete": { "dto.ImageRepoDelete": {
"type": "object", "type": "object",
"required": [ "required": [
"ids" "ids"
], ],
"properties": { "properties": {
"deleteInsecure": {
"type": "boolean"
},
"ids": { "ids": {
"type": "array", "type": "array",
"items": { "items": {
@ -10785,7 +10792,10 @@ var doc = `{
"required": { "required": {
"type": "string" "type": "string"
}, },
"shortDesc": { "shortDescEn": {
"type": "string"
},
"shortDescZh": {
"type": "string" "type": "string"
}, },
"status": { "status": {
@ -12108,7 +12118,10 @@ var doc = `{
"required": { "required": {
"type": "string" "type": "string"
}, },
"shortDesc": { "shortDescEn": {
"type": "string"
},
"shortDescZh": {
"type": "string" "type": "string"
}, },
"status": { "status": {

View File

@ -1933,7 +1933,7 @@
"in": "body", "in": "body",
"required": true, "required": true,
"schema": { "schema": {
"$ref": "#/definitions/dto.ImageRepoCreate" "$ref": "#/definitions/dto.ImageRepoDelete"
} }
} }
], ],
@ -2046,6 +2046,42 @@
} }
} }
}, },
"/containers/repo/status": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "获取 docker 仓库状态",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Container Image-repo"
],
"summary": "Load repo status",
"parameters": [
{
"description": "request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.OperateByID"
}
}
],
"responses": {
"200": {
"description": ""
}
}
}
},
"/containers/repo/update": { "/containers/repo/update": {
"post": { "post": {
"security": [ "security": [
@ -5461,18 +5497,18 @@
} }
} }
}, },
"/nginx": { "/openResty": {
"get": { "get": {
"security": [ "security": [
{ {
"ApiKeyAuth": [] "ApiKeyAuth": []
} }
], ],
"description": "获取 nginx 配置信息", "description": "获取 OpenResty 配置信息",
"tags": [ "tags": [
"Nginx" "OpenResty"
], ],
"summary": "Load nginx conf", "summary": "Load OpenResty conf",
"responses": { "responses": {
"200": { "200": {
"description": "OK", "description": "OK",
@ -5483,21 +5519,21 @@
} }
} }
}, },
"/nginx/file": { "/openResty/file": {
"post": { "post": {
"security": [ "security": [
{ {
"ApiKeyAuth": [] "ApiKeyAuth": []
} }
], ],
"description": "上传更新 nginx 配置文件", "description": "上传更新 OpenResty 配置文件",
"consumes": [ "consumes": [
"application/json" "application/json"
], ],
"tags": [ "tags": [
"Nginx" "OpenResty"
], ],
"summary": "Update nginx conf by upload file", "summary": "Update OpenResty conf by upload file",
"parameters": [ "parameters": [
{ {
"description": "request", "description": "request",
@ -5523,21 +5559,21 @@
} }
} }
}, },
"/nginx/scope": { "/openResty/scope": {
"post": { "post": {
"security": [ "security": [
{ {
"ApiKeyAuth": [] "ApiKeyAuth": []
} }
], ],
"description": "获取部分 nginx 配置信息", "description": "获取部分 OpenResty 配置信息",
"consumes": [ "consumes": [
"application/json" "application/json"
], ],
"tags": [ "tags": [
"Nginx" "OpenResty"
], ],
"summary": "Load partial nginx conf", "summary": "Load partial OpenResty conf",
"parameters": [ "parameters": [
{ {
"description": "request", "description": "request",
@ -5559,18 +5595,18 @@
} }
} }
}, },
"/nginx/status": { "/openResty/status": {
"get": { "get": {
"security": [ "security": [
{ {
"ApiKeyAuth": [] "ApiKeyAuth": []
} }
], ],
"description": "获取 nginx 状态信息", "description": "获取 OpenResty 状态信息",
"tags": [ "tags": [
"Nginx" "OpenResty"
], ],
"summary": "Load nginx status info", "summary": "Load OpenResty status info",
"responses": { "responses": {
"200": { "200": {
"description": "OK", "description": "OK",
@ -5581,21 +5617,21 @@
} }
} }
}, },
"/nginx/update": { "/openResty/update": {
"post": { "post": {
"security": [ "security": [
{ {
"ApiKeyAuth": [] "ApiKeyAuth": []
} }
], ],
"description": "更新 nginx 配置信息", "description": "更新 OpenResty 配置信息",
"consumes": [ "consumes": [
"application/json" "application/json"
], ],
"tags": [ "tags": [
"Nginx" "OpenResty"
], ],
"summary": "Update nginx conf", "summary": "Update OpenResty conf",
"parameters": [ "parameters": [
{ {
"description": "request", "description": "request",
@ -9575,41 +9611,12 @@
} }
} }
}, },
"dto.ImageRepoCreate": {
"type": "object",
"required": [
"name"
],
"properties": {
"auth": {
"type": "boolean"
},
"downloadUrl": {
"type": "string"
},
"name": {
"type": "string"
},
"password": {
"type": "string"
},
"protocol": {
"type": "string"
},
"username": {
"type": "string"
}
}
},
"dto.ImageRepoDelete": { "dto.ImageRepoDelete": {
"type": "object", "type": "object",
"required": [ "required": [
"ids" "ids"
], ],
"properties": { "properties": {
"deleteInsecure": {
"type": "boolean"
},
"ids": { "ids": {
"type": "array", "type": "array",
"items": { "items": {
@ -10771,7 +10778,10 @@
"required": { "required": {
"type": "string" "type": "string"
}, },
"shortDesc": { "shortDescEn": {
"type": "string"
},
"shortDescZh": {
"type": "string" "type": "string"
}, },
"status": { "status": {
@ -12094,7 +12104,10 @@
"required": { "required": {
"type": "string" "type": "string"
}, },
"shortDesc": { "shortDescEn": {
"type": "string"
},
"shortDescZh": {
"type": "string" "type": "string"
}, },
"status": { "status": {

View File

@ -717,27 +717,8 @@ definitions:
- repoID - repoID
- tagName - tagName
type: object type: object
dto.ImageRepoCreate:
properties:
auth:
type: boolean
downloadUrl:
type: string
name:
type: string
password:
type: string
protocol:
type: string
username:
type: string
required:
- name
type: object
dto.ImageRepoDelete: dto.ImageRepoDelete:
properties: properties:
deleteInsecure:
type: boolean
ids: ids:
items: items:
type: integer type: integer
@ -1509,7 +1490,9 @@ definitions:
type: integer type: integer
required: required:
type: string type: string
shortDesc: shortDescEn:
type: string
shortDescZh:
type: string type: string
status: status:
type: string type: string
@ -2392,7 +2375,9 @@ definitions:
type: integer type: integer
required: required:
type: string type: string
shortDesc: shortDescEn:
type: string
shortDescZh:
type: string type: string
status: status:
type: string type: string
@ -3860,7 +3845,7 @@ paths:
name: request name: request
required: true required: true
schema: schema:
$ref: '#/definitions/dto.ImageRepoCreate' $ref: '#/definitions/dto.ImageRepoDelete'
produces: produces:
- application/json - application/json
responses: responses:
@ -3937,6 +3922,28 @@ paths:
summary: Page image repos summary: Page image repos
tags: tags:
- Container Image-repo - Container Image-repo
/containers/repo/status:
get:
consumes:
- application/json
description: 获取 docker 仓库状态
parameters:
- description: request
in: body
name: request
required: true
schema:
$ref: '#/definitions/dto.OperateByID'
produces:
- application/json
responses:
"200":
description: ""
security:
- ApiKeyAuth: []
summary: Load repo status
tags:
- Container Image-repo
/containers/repo/update: /containers/repo/update:
post: post:
consumes: consumes:
@ -6111,9 +6118,9 @@ paths:
summary: Page operation logs summary: Page operation logs
tags: tags:
- Logs - Logs
/nginx: /openResty:
get: get:
description: 获取 nginx 配置信息 description: 获取 OpenResty 配置信息
responses: responses:
"200": "200":
description: OK description: OK
@ -6121,14 +6128,14 @@ paths:
$ref: '#/definitions/response.FileInfo' $ref: '#/definitions/response.FileInfo'
security: security:
- ApiKeyAuth: [] - ApiKeyAuth: []
summary: Load nginx conf summary: Load OpenResty conf
tags: tags:
- Nginx - OpenResty
/nginx/file: /openResty/file:
post: post:
consumes: consumes:
- application/json - application/json
description: 上传更新 nginx 配置文件 description: 上传更新 OpenResty 配置文件
parameters: parameters:
- description: request - description: request
in: body in: body
@ -6141,20 +6148,20 @@ paths:
description: "" description: ""
security: security:
- ApiKeyAuth: [] - ApiKeyAuth: []
summary: Update nginx conf by upload file summary: Update OpenResty conf by upload file
tags: tags:
- Nginx - OpenResty
x-panel-log: x-panel-log:
BeforeFuntions: [] BeforeFuntions: []
bodyKeys: [] bodyKeys: []
formatEN: Update nginx conf formatEN: Update nginx conf
formatZH: 更新 nginx 配置 formatZH: 更新 nginx 配置
paramKeys: [] paramKeys: []
/nginx/scope: /openResty/scope:
post: post:
consumes: consumes:
- application/json - application/json
description: 获取部分 nginx 配置信息 description: 获取部分 OpenResty 配置信息
parameters: parameters:
- description: request - description: request
in: body in: body
@ -6169,12 +6176,12 @@ paths:
type: anrry type: anrry
security: security:
- ApiKeyAuth: [] - ApiKeyAuth: []
summary: Load partial nginx conf summary: Load partial OpenResty conf
tags: tags:
- Nginx - OpenResty
/nginx/status: /openResty/status:
get: get:
description: 获取 nginx 状态信息 description: 获取 OpenResty 状态信息
responses: responses:
"200": "200":
description: OK description: OK
@ -6182,14 +6189,14 @@ paths:
$ref: '#/definitions/response.NginxStatus' $ref: '#/definitions/response.NginxStatus'
security: security:
- ApiKeyAuth: [] - ApiKeyAuth: []
summary: Load nginx status info summary: Load OpenResty status info
tags: tags:
- Nginx - OpenResty
/nginx/update: /openResty/update:
post: post:
consumes: consumes:
- application/json - application/json
description: 更新 nginx 配置信息 description: 更新 OpenResty 配置信息
parameters: parameters:
- description: request - description: request
in: body in: body
@ -6202,9 +6209,9 @@ paths:
description: "" description: ""
security: security:
- ApiKeyAuth: [] - ApiKeyAuth: []
summary: Update nginx conf summary: Update OpenResty conf
tags: tags:
- Nginx - OpenResty
x-panel-log: x-panel-log:
BeforeFuntions: BeforeFuntions:
- db: websites - db: websites

View File

@ -76,6 +76,9 @@ export const createVolume = (params: Container.VolumeCreate) => {
}; };
// repo // repo
export const checkRepoStatus = (id: number) => {
return http.post(`/containers/repo/status`, { id: id });
};
export const searchImageRepo = (params: SearchWithPage) => { export const searchImageRepo = (params: SearchWithPage) => {
return http.post<ResPage<Container.RepoInfo>>(`/containers/repo/search`, params); return http.post<ResPage<Container.RepoInfo>>(`/containers/repo/search`, params);
}; };

View File

@ -266,6 +266,7 @@ export default {
loadBackup: 'Import', loadBackup: 'Import',
setting: 'Settings', setting: 'Settings',
remoteAccess: 'Remote access', remoteAccess: 'Remote access',
remoteHelper: 'One in a row, for example:\n172.16.10.111\n172.16.10.112',
remoteConnHelper: remoteConnHelper:
'Remote connection to mysql as user root may have security risks. Therefore, perform this operation with caution.', 'Remote connection to mysql as user root may have security risks. Therefore, perform this operation with caution.',
changePassword: 'Password', changePassword: 'Password',

View File

@ -278,6 +278,7 @@ export default {
loadBackup: '导入备份', loadBackup: '导入备份',
setting: '设置', setting: '设置',
remoteAccess: '远程访问', remoteAccess: '远程访问',
remoteHelper: '一行一个\n172.16.10.111\n172.16.10.112',
remoteConnHelper: 'root 帐号远程连接 mysql 有安全风险开启需谨慎', remoteConnHelper: 'root 帐号远程连接 mysql 有安全风险开启需谨慎',
changePassword: '改密', changePassword: '改密',
changePasswordHelper: '当前数据库已经关联应用修改密码将同步修改应用中数据库密码修改后重启生效', changePasswordHelper: '当前数据库已经关联应用修改密码将同步修改应用中数据库密码修改后重启生效',

View File

@ -82,7 +82,7 @@ import OperatorDialog from '@/views/container/repo/operator/index.vue';
import { reactive, onMounted, ref } from 'vue'; import { reactive, onMounted, ref } from 'vue';
import { dateFormat } from '@/utils/util'; import { dateFormat } from '@/utils/util';
import { Container } from '@/api/interface/container'; import { Container } from '@/api/interface/container';
import { deleteImageRepo, loadDockerStatus, searchImageRepo } from '@/api/modules/container'; import { checkRepoStatus, deleteImageRepo, loadDockerStatus, searchImageRepo } from '@/api/modules/container';
import i18n from '@/lang'; import i18n from '@/lang';
import router from '@/routers'; import router from '@/routers';
import { ElMessageBox } from 'element-plus'; import { ElMessageBox } from 'element-plus';
@ -156,7 +156,25 @@ const onDelete = async (row: Container.RepoInfo) => {
}); });
}; };
const onCheckConn = async (row: Container.RepoInfo) => {
loading.value = true;
await checkRepoStatus(row.id)
.then(() => {
loading.value = false;
search();
})
.catch(() => {
loading.value = false;
});
};
const buttons = [ const buttons = [
{
label: i18n.global.t('commons.button.sync'),
click: (row: Container.RepoInfo) => {
onCheckConn(row);
},
},
{ {
label: i18n.global.t('commons.button.edit'), label: i18n.global.t('commons.button.edit'),
disabled: (row: Container.RepoInfo) => { disabled: (row: Container.RepoInfo) => {

View File

@ -38,7 +38,13 @@
prop="privilegeIPs" prop="privilegeIPs"
:rules="Rules.requiredInput" :rules="Rules.requiredInput"
> >
<el-input clearable v-model="changeForm.privilegeIPs" /> <el-input
:placeholder="$t('database.remoteHelper')"
clearable
:autosize="{ minRows: 2, maxRows: 5 }"
type="textarea"
v-model="changeForm.privilegeIPs"
/>
</el-form-item> </el-form-item>
</div> </div>
</el-col> </el-col>
@ -145,7 +151,11 @@ const submitChangeInfo = async (formEl: FormInstance | undefined) => {
} }
return; return;
} }
param.value = changeForm.privilege; if (changeForm.privilege !== 'ip') {
param.value = changeForm.privilege;
} else {
param.value = changeForm.privilegeIPs.replaceAll('/n', ',');
}
loading.value = true; loading.value = true;
await updateMysqlAccess(param) await updateMysqlAccess(param)
.then(() => { .then(() => {

View File

@ -217,10 +217,10 @@ const onSave = async (formEl: FormInstance | undefined, key: string, val: any) =
}; };
await updateSetting(param) await updateSetting(param)
.then(async () => { .then(async () => {
loading.value = false;
MsgSuccess(i18n.t('commons.msg.operationSuccess'));
if (param.key === 'UserName') { if (param.key === 'UserName') {
await logOutApi(); await logOutApi();
loading.value = false;
MsgSuccess(i18n.t('commons.msg.operationSuccess'));
router.push({ name: 'login', params: { code: '' } }); router.push({ name: 'login', params: { code: '' } });
globalStore.setLogStatus(false); globalStore.setLogStatus(false);
return; return;