From 0ac2b9df7a03048aca18460958c425154ac74fd7 Mon Sep 17 00:00:00 2001 From: ssongliu <73214554+ssongliu@users.noreply.github.com> Date: Thu, 6 Jul 2023 18:04:22 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E5=AE=B9=E5=99=A8?= =?UTF-8?q?=E7=95=8C=E9=9D=A2=E5=8A=A0=E8=BD=BD=E9=80=9F=E5=BA=A6=20(#1565?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app/api/v1/app_install.go | 6 +- backend/app/api/v1/backup.go | 6 +- backend/app/api/v1/compose_template.go | 2 +- backend/app/api/v1/container.go | 16 +- backend/app/api/v1/database_mysql.go | 4 +- backend/app/api/v1/file.go | 4 +- backend/app/api/v1/host.go | 4 +- backend/app/api/v1/image.go | 2 +- backend/app/api/v1/image_repo.go | 2 +- backend/app/api/v1/nginx.go | 2 +- backend/app/api/v1/website.go | 8 +- backend/app/api/v1/website_ssl.go | 2 +- backend/app/dto/container.go | 12 +- backend/app/service/container.go | 94 +++-- backend/router/ro_container.go | 1 + cmd/server/docs/docs.go | 387 +++++++++++++++--- cmd/server/docs/swagger.json | 387 +++++++++++++++--- cmd/server/docs/swagger.yaml | 269 ++++++++++-- frontend/src/api/interface/container.ts | 11 +- frontend/src/api/modules/container.ts | 3 + .../src/views/container/container/index.vue | 29 +- frontend/src/views/home/index.vue | 2 +- 22 files changed, 1052 insertions(+), 201 deletions(-) diff --git a/backend/app/api/v1/app_install.go b/backend/app/api/v1/app_install.go index b8c67c1a5..29165893a 100644 --- a/backend/app/api/v1/app_install.go +++ b/backend/app/api/v1/app_install.go @@ -118,7 +118,7 @@ func (b *BaseApi) LoadConnInfo(c *gin.Context) { // @Description 删除前检查 // @Accept json // @Param appInstallId path integer true "App install id" -// @Success 200 {anrry} dto.AppResource +// @Success 200 {array} dto.AppResource // @Security ApiKeyAuth // @Router /apps/installed/delete/check/:appInstallId [get] func (b *BaseApi) DeleteCheck(c *gin.Context) { @@ -178,7 +178,7 @@ func (b *BaseApi) OperateInstalled(c *gin.Context) { // @Description 通过 key 获取应用 service // @Accept json // @Param key path string true "request" -// @Success 200 {anrry} response.AppService +// @Success 200 {array} response.AppService // @Security ApiKeyAuth // @Router /apps/services/:key [get] func (b *BaseApi) GetServices(c *gin.Context) { @@ -196,7 +196,7 @@ func (b *BaseApi) GetServices(c *gin.Context) { // @Description 通过 install id 获取应用更新版本 // @Accept json // @Param appInstallId path integer true "request" -// @Success 200 {anrry} dto.AppVersion +// @Success 200 {array} dto.AppVersion // @Security ApiKeyAuth // @Router /apps/installed/:appInstallId/versions [get] func (b *BaseApi) GetUpdateVersions(c *gin.Context) { diff --git a/backend/app/api/v1/backup.go b/backend/app/api/v1/backup.go index 95452ae23..d9853b5f5 100644 --- a/backend/app/api/v1/backup.go +++ b/backend/app/api/v1/backup.go @@ -60,7 +60,7 @@ func (b *BaseApi) CreateBackup(c *gin.Context) { // @Description 获取 bucket 列表 // @Accept json // @Param request body dto.ForBuckets true "request" -// @Success 200 {anrry} string +// @Success 200 {array} string // @Security ApiKeyAuth // @Router /settings/backup/search [post] func (b *BaseApi) ListBuckets(c *gin.Context) { @@ -269,7 +269,7 @@ func (b *BaseApi) UpdateBackup(c *gin.Context) { // @Tags Backup Account // @Summary List backup accounts // @Description 获取备份账号列表 -// @Success 200 {anrry} dto.BackupInfo +// @Success 200 {array} dto.BackupInfo // @Security ApiKeyAuth // @Router /settings/backup/search [get] func (b *BaseApi) ListBackup(c *gin.Context) { @@ -287,7 +287,7 @@ func (b *BaseApi) ListBackup(c *gin.Context) { // @Description 获取备份账号内文件列表 // @Accept json // @Param request body dto.BackupSearchFile true "request" -// @Success 200 {anrry} string +// @Success 200 {array} string // @Security ApiKeyAuth // @Router /settings/backup/search/files [post] func (b *BaseApi) LoadFilesFromBackup(c *gin.Context) { diff --git a/backend/app/api/v1/compose_template.go b/backend/app/api/v1/compose_template.go index ce7cf8728..a2db26498 100644 --- a/backend/app/api/v1/compose_template.go +++ b/backend/app/api/v1/compose_template.go @@ -66,7 +66,7 @@ func (b *BaseApi) SearchComposeTemplate(c *gin.Context) { // @Summary List compose templates // @Description 获取容器编排模版列表 // @Produce json -// @Success 200 {anrry} dto.ComposeTemplateInfo +// @Success 200 {array} dto.ComposeTemplateInfo // @Security ApiKeyAuth // @Router /containers/template [get] func (b *BaseApi) ListComposeTemplate(c *gin.Context) { diff --git a/backend/app/api/v1/container.go b/backend/app/api/v1/container.go index 0be334b41..83c93b880 100644 --- a/backend/app/api/v1/container.go +++ b/backend/app/api/v1/container.go @@ -236,6 +236,20 @@ func (b *BaseApi) LoadResouceLimit(c *gin.Context) { helper.SuccessWithData(c, data) } +// @Summary Load container stats +// @Description 获取容器列表资源占用 +// @Success 200 {array} dto.ContainerListStats +// @Security ApiKeyAuth +// @Router /containers/list/stats [get] +func (b *BaseApi) ContainerListStats(c *gin.Context) { + datas, err := containerService.ContainerListStats() + if err != nil { + helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) + return + } + helper.SuccessWithData(c, datas) +} + // @Tags Container // @Summary Create container // @Description 创建容器 @@ -371,7 +385,7 @@ func (b *BaseApi) ContainerOperation(c *gin.Context) { // @Summary Container stats // @Description 容器监控信息 // @Param id path integer true "容器id" -// @Success 200 {object} dto.ContainterStats +// @Success 200 {object} dto.ContainerStats // @Security ApiKeyAuth // @Router /containers/stats/:id [get] func (b *BaseApi) ContainerStats(c *gin.Context) { diff --git a/backend/app/api/v1/database_mysql.go b/backend/app/api/v1/database_mysql.go index d26b4f6ad..8602436c9 100644 --- a/backend/app/api/v1/database_mysql.go +++ b/backend/app/api/v1/database_mysql.go @@ -216,7 +216,7 @@ func (b *BaseApi) SearchMysql(c *gin.Context) { // @Description 获取 mysql 数据库列表 // @Accept json // @Param request body dto.PageInfo true "request" -// @Success 200 {anrry} string +// @Success 200 {array} string // @Security ApiKeyAuth // @Router /databases/options [get] func (b *BaseApi) ListDBName(c *gin.Context) { @@ -234,7 +234,7 @@ func (b *BaseApi) ListDBName(c *gin.Context) { // @Description Mysql 数据库删除前检查 // @Accept json // @Param request body dto.OperateByID true "request" -// @Success 200 {anrry} string +// @Success 200 {array} string // @Security ApiKeyAuth // @Router /databases/del/check [post] func (b *BaseApi) DeleteCheckMysql(c *gin.Context) { diff --git a/backend/app/api/v1/file.go b/backend/app/api/v1/file.go index b0fe5e341..35e34fcfd 100644 --- a/backend/app/api/v1/file.go +++ b/backend/app/api/v1/file.go @@ -52,7 +52,7 @@ func (b *BaseApi) ListFiles(c *gin.Context) { // @Description 分页获取上传文件 // @Accept json // @Param request body request.SearchUploadWithPage true "request" -// @Success 200 {anrry} response.FileInfo +// @Success 200 {array} response.FileInfo // @Security ApiKeyAuth // @Router /files/upload/search [post] func (b *BaseApi) SearchUploadWithPage(c *gin.Context) { @@ -81,7 +81,7 @@ func (b *BaseApi) SearchUploadWithPage(c *gin.Context) { // @Description 加载文件树 // @Accept json // @Param request body request.FileOption true "request" -// @Success 200 {anrry} response.FileTree +// @Success 200 {array} response.FileTree // @Security ApiKeyAuth // @Router /files/tree [post] func (b *BaseApi) GetFileTree(c *gin.Context) { diff --git a/backend/app/api/v1/host.go b/backend/app/api/v1/host.go index ac266a714..ff34eccf3 100644 --- a/backend/app/api/v1/host.go +++ b/backend/app/api/v1/host.go @@ -124,7 +124,7 @@ func (b *BaseApi) TestByID(c *gin.Context) { // @Description 加载主机树 // @Accept json // @Param request body dto.SearchForTree true "request" -// @Success 200 {anrry} dto.HostTree +// @Success 200 {array} dto.HostTree // @Security ApiKeyAuth // @Router /hosts/tree [post] func (b *BaseApi) HostTree(c *gin.Context) { @@ -148,7 +148,7 @@ func (b *BaseApi) HostTree(c *gin.Context) { // @Description 获取主机列表分页 // @Accept json // @Param request body dto.SearchHostWithPage true "request" -// @Success 200 {anrry} dto.HostTree +// @Success 200 {array} dto.HostTree // @Security ApiKeyAuth // @Router /hosts/search [post] func (b *BaseApi) SearchHost(c *gin.Context) { diff --git a/backend/app/api/v1/image.go b/backend/app/api/v1/image.go index b55b76d08..f69d57178 100644 --- a/backend/app/api/v1/image.go +++ b/backend/app/api/v1/image.go @@ -44,7 +44,7 @@ func (b *BaseApi) SearchImage(c *gin.Context) { // @Summary List images // @Description 获取镜像列表 // @Produce json -// @Success 200 {anrry} dto.Options +// @Success 200 {array} dto.Options // @Security ApiKeyAuth // @Router /containers/image [get] func (b *BaseApi) ListImage(c *gin.Context) { diff --git a/backend/app/api/v1/image_repo.go b/backend/app/api/v1/image_repo.go index 76cd598ca..6ec3819b8 100644 --- a/backend/app/api/v1/image_repo.go +++ b/backend/app/api/v1/image_repo.go @@ -44,7 +44,7 @@ func (b *BaseApi) SearchRepo(c *gin.Context) { // @Summary List image repos // @Description 获取镜像仓库列表 // @Produce json -// @Success 200 {anrry} dto.ImageRepoOption +// @Success 200 {array} dto.ImageRepoOption // @Security ApiKeyAuth // @Router /containers/repo [get] func (b *BaseApi) ListRepo(c *gin.Context) { diff --git a/backend/app/api/v1/nginx.go b/backend/app/api/v1/nginx.go index a646702bc..d79e24f45 100644 --- a/backend/app/api/v1/nginx.go +++ b/backend/app/api/v1/nginx.go @@ -27,7 +27,7 @@ func (b *BaseApi) GetNginx(c *gin.Context) { // @Description 获取部分 OpenResty 配置信息 // @Accept json // @Param request body request.NginxScopeReq true "request" -// @Success 200 {anrry} response.NginxParam +// @Success 200 {array} response.NginxParam // @Security ApiKeyAuth // @Router /openResty/scope [post] func (b *BaseApi) GetNginxConfigByScope(c *gin.Context) { diff --git a/backend/app/api/v1/website.go b/backend/app/api/v1/website.go index 76c41d0c7..c641b11c6 100644 --- a/backend/app/api/v1/website.go +++ b/backend/app/api/v1/website.go @@ -36,7 +36,7 @@ func (b *BaseApi) PageWebsite(c *gin.Context) { // @Tags Website // @Summary List websites // @Description 获取网站列表 -// @Success 200 {anrry} response.WebsiteDTO +// @Success 200 {array} response.WebsiteDTO // @Security ApiKeyAuth // @Router /websites/list [get] func (b *BaseApi) GetWebsites(c *gin.Context) { @@ -51,7 +51,7 @@ func (b *BaseApi) GetWebsites(c *gin.Context) { // @Tags Website // @Summary List website names // @Description 获取网站列表 -// @Success 200 {anrry} string +// @Success 200 {array} string // @Security ApiKeyAuth // @Router /websites/options [get] func (b *BaseApi) GetWebsiteOptions(c *gin.Context) { @@ -207,7 +207,7 @@ func (b *BaseApi) GetWebsiteNginx(c *gin.Context) { // @Description 通过网站 id 查询域名 // @Accept json // @Param websiteId path integer true "request" -// @Success 200 {anrry} model.WebsiteDomain +// @Success 200 {array} model.WebsiteDomain // @Security ApiKeyAuth // @Router /websites/domains/:websiteId [get] func (b *BaseApi) GetWebDomains(c *gin.Context) { @@ -367,7 +367,7 @@ func (b *BaseApi) UpdateHTTPSConfig(c *gin.Context) { // @Description 网站创建前检查 // @Accept json // @Param request body request.WebsiteInstallCheckReq true "request" -// @Success 200 {anrry} request.WebsitePreInstallCheck +// @Success 200 {array} response.WebsitePreInstallCheck // @Security ApiKeyAuth // @Router /websites/check [post] func (b *BaseApi) CreateWebsiteCheck(c *gin.Context) { diff --git a/backend/app/api/v1/website_ssl.go b/backend/app/api/v1/website_ssl.go index c3d34d435..a382866cd 100644 --- a/backend/app/api/v1/website_ssl.go +++ b/backend/app/api/v1/website_ssl.go @@ -94,7 +94,7 @@ func (b *BaseApi) RenewWebsiteSSL(c *gin.Context) { // @Description 解析网站 ssl // @Accept json // @Param request body request.WebsiteDNSReq true "request" -// @Success 200 {anrry} response.WebsiteDNSRes +// @Success 200 {array} response.WebsiteDNSRes // @Security ApiKeyAuth // @Router /websites/ssl/resolve [post] func (b *BaseApi) GetDNSResolve(c *gin.Context) { diff --git a/backend/app/dto/container.go b/backend/app/dto/container.go index 356eeb304..eb7b2027b 100644 --- a/backend/app/dto/container.go +++ b/backend/app/dto/container.go @@ -24,9 +24,7 @@ type ContainerInfo struct { State string `json:"state"` RunTime string `json:"runTime"` - CPUPercent float64 `json:"cpuPercent"` - MemoryPercent float64 `json:"memoryPercent"` - Ports []string `json:"ports"` + Ports []string `json:"ports"` IsFromApp bool `json:"isFromApp"` IsFromCompose bool `json:"isFromCompose"` @@ -59,7 +57,13 @@ type ContainerUpgrade struct { Image string `json:"image" validate:"required"` } -type ContainterStats struct { +type ContainerListStats struct { + ContainerID string `json:"containerID"` + CPUPercent float64 `json:"cpuPercent"` + MemoryPercent float64 `json:"memoryPercent"` +} + +type ContainerStats struct { CPUPercent float64 `json:"cpuPercent"` Memory float64 `json:"memory"` Cache float64 `json:"cache"` diff --git a/backend/app/service/container.go b/backend/app/service/container.go index f1c6b1e4f..2fb124f2c 100644 --- a/backend/app/service/container.go +++ b/backend/app/service/container.go @@ -46,11 +46,12 @@ type IContainerService interface { ContainerUpdate(req dto.ContainerOperate) error ContainerUpgrade(req dto.ContainerUpgrade) error ContainerInfo(req dto.OperationWithName) (*dto.ContainerOperate, error) + ContainerListStats() ([]dto.ContainerListStats, error) LoadResouceLimit() (*dto.ResourceLimit, error) ContainerLogClean(req dto.OperationWithName) error ContainerOperation(req dto.ContainerOperation) error ContainerLogs(wsConn *websocket.Conn, container, since, tail string, follow bool) error - ContainerStats(id string) (*dto.ContainterStats, error) + ContainerStats(id string) (*dto.ContainerStats, error) Inspect(req dto.InspectReq) (string, error) DeleteNetwork(req dto.BatchDelete) error CreateNetwork(req dto.NetworkCreate) error @@ -129,46 +130,38 @@ func (u *ContainerService) Page(req dto.PageContainer) (int64, interface{}, erro } backDatas := make([]dto.ContainerInfo, len(records)) - var wg sync.WaitGroup - wg.Add(len(records)) for i := 0; i < len(records); i++ { - go func(item types.Container, i int) { - IsFromCompose := false - if _, ok := item.Labels[composeProjectLabel]; ok { - IsFromCompose = true - } - IsFromApp := false - if created, ok := item.Labels[composeCreatedBy]; ok && created == "Apps" { - IsFromApp = true - } + item := records[i] + IsFromCompose := false + if _, ok := item.Labels[composeProjectLabel]; ok { + IsFromCompose = true + } + IsFromApp := false + if created, ok := item.Labels[composeCreatedBy]; ok && created == "Apps" { + IsFromApp = true + } - var ports []string - for _, port := range item.Ports { - itemPortStr := fmt.Sprintf("%v/%s", port.PrivatePort, port.Type) - if port.PublicPort != 0 { - itemPortStr = fmt.Sprintf("%s:%v->%v/%s", port.IP, port.PublicPort, port.PrivatePort, port.Type) - } - ports = append(ports, itemPortStr) - } - cpu, mem := loadCpuAndMem(client, item.ID) - backDatas[i] = dto.ContainerInfo{ - ContainerID: item.ID, - CreateTime: time.Unix(item.Created, 0).Format("2006-01-02 15:04:05"), - Name: item.Names[0][1:], - ImageId: strings.Split(item.ImageID, ":")[1], - ImageName: item.Image, - State: item.State, - RunTime: item.Status, - CPUPercent: cpu, - MemoryPercent: mem, - Ports: ports, - IsFromApp: IsFromApp, - IsFromCompose: IsFromCompose, + var ports []string + for _, port := range item.Ports { + itemPortStr := fmt.Sprintf("%v/%s", port.PrivatePort, port.Type) + if port.PublicPort != 0 { + itemPortStr = fmt.Sprintf("%s:%v->%v/%s", port.IP, port.PublicPort, port.PrivatePort, port.Type) } - wg.Done() - }(records[i], i) + ports = append(ports, itemPortStr) + } + backDatas[i] = dto.ContainerInfo{ + ContainerID: item.ID, + CreateTime: time.Unix(item.Created, 0).Format("2006-01-02 15:04:05"), + Name: item.Names[0][1:], + ImageId: strings.Split(item.ImageID, ":")[1], + ImageName: item.Image, + State: item.State, + RunTime: item.Status, + Ports: ports, + IsFromApp: IsFromApp, + IsFromCompose: IsFromCompose, + } } - wg.Wait() return int64(total), backDatas, nil } @@ -194,6 +187,29 @@ func (u *ContainerService) List() ([]string, error) { return datas, nil } +func (u *ContainerService) ContainerListStats() ([]dto.ContainerListStats, error) { + client, err := docker.NewDockerClient() + if err != nil { + return nil, err + } + list, err := client.ContainerList(context.Background(), types.ContainerListOptions{All: true}) + if err != nil { + return nil, err + } + var datas []dto.ContainerListStats + var wg sync.WaitGroup + wg.Add(len(list)) + for i := 0; i < len(list); i++ { + go func(item types.Container) { + cpu, mem := loadCpuAndMem(client, item.ID) + datas = append(datas, dto.ContainerListStats{CPUPercent: cpu, MemoryPercent: mem, ContainerID: item.ID}) + wg.Done() + }(list[i]) + } + wg.Wait() + return datas, nil +} + func (u *ContainerService) Inspect(req dto.InspectReq) (string, error) { client, err := docker.NewDockerClient() if err != nil { @@ -541,7 +557,7 @@ func (u *ContainerService) ContainerLogs(wsConn *websocket.Conn, container, sinc return nil } -func (u *ContainerService) ContainerStats(id string) (*dto.ContainterStats, error) { +func (u *ContainerService) ContainerStats(id string) (*dto.ContainerStats, error) { client, err := docker.NewDockerClient() if err != nil { return nil, err @@ -562,7 +578,7 @@ func (u *ContainerService) ContainerStats(id string) (*dto.ContainterStats, erro if err := json.Unmarshal(body, &stats); err != nil { return nil, err } - var data dto.ContainterStats + var data dto.ContainerStats data.CPUPercent = calculateCPUPercentUnix(stats) data.IORead, data.IOWrite = calculateBlockIO(stats.BlkioStats) data.Memory = float64(stats.MemoryStats.Usage) / 1024 / 1024 diff --git a/backend/router/ro_container.go b/backend/router/ro_container.go index df5fc4cbb..a36069179 100644 --- a/backend/router/ro_container.go +++ b/backend/router/ro_container.go @@ -24,6 +24,7 @@ func (s *ContainerRouter) InitContainerRouter(Router *gin.RouterGroup) { baRouter.POST("/info", baseApi.ContainerInfo) baRouter.POST("/search", baseApi.SearchContainer) baRouter.POST("/list", baseApi.ListContainer) + baRouter.GET("/list/stats", baseApi.ContainerListStats) baRouter.GET("/search/log", baseApi.ContainerLogs) baRouter.GET("/limit", baseApi.LoadResouceLimit) baRouter.POST("/clean/log", baseApi.CleanContainerLog) diff --git a/cmd/server/docs/docs.go b/cmd/server/docs/docs.go index 0cb79b2c2..b7174b877 100644 --- a/cmd/server/docs/docs.go +++ b/cmd/server/docs/docs.go @@ -252,7 +252,10 @@ var doc = `{ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "$ref": "#/definitions/dto.AppVersion" + } } } } @@ -388,7 +391,10 @@ var doc = `{ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "$ref": "#/definitions/dto.AppResource" + } } } } @@ -778,7 +784,10 @@ var doc = `{ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "$ref": "#/definitions/response.AppService" + } } } } @@ -1442,7 +1451,10 @@ var doc = `{ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "$ref": "#/definitions/dto.Options" + } } } } @@ -1939,6 +1951,28 @@ var doc = `{ } } }, + "/containers/list/stats": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "获取容器列表资源占用", + "summary": "Load container stats", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/dto.ContainerListStats" + } + } + } + } + } + }, "/containers/network": { "post": { "security": [ @@ -2170,7 +2204,10 @@ var doc = `{ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "$ref": "#/definitions/dto.ImageRepoOption" + } } } } @@ -2507,7 +2544,7 @@ var doc = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/dto.ContainterStats" + "$ref": "#/definitions/dto.ContainerStats" } } } @@ -2532,7 +2569,10 @@ var doc = `{ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "$ref": "#/definitions/dto.ComposeTemplateInfo" + } } } } @@ -3756,7 +3796,10 @@ var doc = `{ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "type": "string" + } } } } @@ -3844,7 +3887,10 @@ var doc = `{ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "type": "string" + } } } } @@ -5064,7 +5110,10 @@ var doc = `{ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "$ref": "#/definitions/response.FileTree" + } } } } @@ -5137,7 +5186,10 @@ var doc = `{ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "$ref": "#/definitions/response.FileInfo" + } } } } @@ -6227,7 +6279,10 @@ var doc = `{ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "$ref": "#/definitions/dto.HostTree" + } } } } @@ -6330,7 +6385,10 @@ var doc = `{ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "$ref": "#/definitions/dto.HostTree" + } } } } @@ -6640,7 +6698,10 @@ var doc = `{ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "$ref": "#/definitions/response.NginxParam" + } } } } @@ -7343,7 +7404,10 @@ var doc = `{ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "$ref": "#/definitions/dto.BackupInfo" + } } } } @@ -7377,7 +7441,10 @@ var doc = `{ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "type": "string" + } } } } @@ -7413,7 +7480,10 @@ var doc = `{ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "type": "string" + } } } } @@ -8738,7 +8808,10 @@ var doc = `{ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "$ref": "#/definitions/response.WebsitePreInstallCheck" + } } } } @@ -9280,7 +9353,10 @@ var doc = `{ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "$ref": "#/definitions/model.WebsiteDomain" + } } } } @@ -9419,7 +9495,10 @@ var doc = `{ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "$ref": "#/definitions/response.WebsiteDTO" + } } } } @@ -9599,7 +9678,10 @@ var doc = `{ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "type": "string" + } } } } @@ -10204,7 +10286,10 @@ var doc = `{ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "$ref": "#/definitions/response.WebsiteDNSRes" + } } } } @@ -10494,6 +10579,51 @@ var doc = `{ } } }, + "dto.AppResource": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + } + } + }, + "dto.AppVersion": { + "type": "object", + "properties": { + "detailId": { + "type": "integer" + }, + "version": { + "type": "string" + } + } + }, + "dto.BackupInfo": { + "type": "object", + "properties": { + "backupPath": { + "type": "string" + }, + "bucket": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "type": { + "type": "string" + }, + "vars": { + "type": "string" + } + } + }, "dto.BackupOperate": { "type": "object", "required": [ @@ -10801,6 +10931,26 @@ var doc = `{ } } }, + "dto.ComposeTemplateInfo": { + "type": "object", + "properties": { + "content": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "description": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "name": { + "type": "string" + } + } + }, "dto.ComposeTemplateUpdate": { "type": "object", "properties": { @@ -10834,6 +10984,20 @@ var doc = `{ } } }, + "dto.ContainerListStats": { + "type": "object", + "properties": { + "containerID": { + "type": "string" + }, + "cpuPercent": { + "type": "number" + }, + "memoryPercent": { + "type": "number" + } + } + }, "dto.ContainerOperate": { "type": "object", "properties": { @@ -10846,6 +11010,9 @@ var doc = `{ "type": "string" } }, + "containerID": { + "type": "string" + }, "cpuShares": { "type": "integer" }, @@ -10952,22 +11119,7 @@ var doc = `{ } } }, - "dto.ContainerUpgrade": { - "type": "object", - "required": [ - "image", - "name" - ], - "properties": { - "image": { - "type": "string" - }, - "name": { - "type": "string" - } - } - }, - "dto.ContainterStats": { + "dto.ContainerStats": { "type": "object", "properties": { "cache": { @@ -10996,6 +11148,21 @@ var doc = `{ } } }, + "dto.ContainerUpgrade": { + "type": "object", + "required": [ + "image", + "name" + ], + "properties": { + "image": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, "dto.CronjobBatchDelete": { "type": "object", "properties": { @@ -11728,6 +11895,23 @@ var doc = `{ } } }, + "dto.HostTree": { + "type": "object", + "properties": { + "children": { + "type": "array", + "items": { + "$ref": "#/definitions/dto.TreeChild" + } + }, + "id": { + "type": "integer" + }, + "label": { + "type": "string" + } + } + }, "dto.ImageBuild": { "type": "object", "required": [ @@ -11811,6 +11995,20 @@ var doc = `{ } } }, + "dto.ImageRepoOption": { + "type": "object", + "properties": { + "downloadUrl": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "name": { + "type": "string" + } + } + }, "dto.ImageRepoUpdate": { "type": "object", "properties": { @@ -12257,6 +12455,14 @@ var doc = `{ } } }, + "dto.Options": { + "type": "object", + "properties": { + "option": { + "type": "string" + } + } + }, "dto.PageContainer": { "type": "object", "required": [ @@ -13028,6 +13234,17 @@ var doc = `{ } } }, + "dto.TreeChild": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "label": { + "type": "string" + } + } + }, "dto.UpdateDescription": { "type": "object", "required": [ @@ -14580,14 +14797,6 @@ var doc = `{ "websiteId" ], "properties": { - "HttpConfig": { - "type": "string", - "enum": [ - "HTTPSOnly", - "HTTPAlso", - "HTTPToHTTPS" - ] - }, "SSLProtocol": { "type": "array", "items": { @@ -14600,12 +14809,29 @@ var doc = `{ "certificate": { "type": "string" }, + "certificatePath": { + "type": "string" + }, "enable": { "type": "boolean" }, + "httpConfig": { + "type": "string", + "enum": [ + "HTTPSOnly", + "HTTPAlso", + "HTTPToHTTPS" + ] + }, + "importType": { + "type": "string" + }, "privateKey": { "type": "string" }, + "privateKeyPath": { + "type": "string" + }, "type": { "type": "string", "enum": [ @@ -14865,6 +15091,9 @@ var doc = `{ "pageSize" ], "properties": { + "acmeAccountId": { + "type": "integer" + }, "page": { "type": "integer" }, @@ -15215,6 +15444,18 @@ var doc = `{ "values": {} } }, + "response.AppService": { + "type": "object", + "properties": { + "config": {}, + "label": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, "response.FileInfo": { "type": "object", "properties": { @@ -15277,6 +15518,26 @@ var doc = `{ } } }, + "response.FileTree": { + "type": "object", + "properties": { + "children": { + "type": "array", + "items": { + "$ref": "#/definitions/response.FileTree" + } + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "path": { + "type": "string" + } + } + }, "response.NginxParam": { "type": "object", "properties": { @@ -15357,6 +15618,23 @@ var doc = `{ } } }, + "response.WebsiteDNSRes": { + "type": "object", + "properties": { + "domain": { + "type": "string" + }, + "err": { + "type": "string" + }, + "resolve": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, "response.WebsiteDTO": { "type": "object", "properties": { @@ -15509,6 +15787,23 @@ var doc = `{ } } }, + "response.WebsitePreInstallCheck": { + "type": "object", + "properties": { + "appName": { + "type": "string" + }, + "name": { + "type": "string" + }, + "status": { + "type": "string" + }, + "version": { + "type": "string" + } + } + }, "response.WebsiteWafConfig": { "type": "object", "properties": { diff --git a/cmd/server/docs/swagger.json b/cmd/server/docs/swagger.json index 27597d570..1745bbcb4 100644 --- a/cmd/server/docs/swagger.json +++ b/cmd/server/docs/swagger.json @@ -238,7 +238,10 @@ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "$ref": "#/definitions/dto.AppVersion" + } } } } @@ -374,7 +377,10 @@ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "$ref": "#/definitions/dto.AppResource" + } } } } @@ -764,7 +770,10 @@ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "$ref": "#/definitions/response.AppService" + } } } } @@ -1428,7 +1437,10 @@ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "$ref": "#/definitions/dto.Options" + } } } } @@ -1925,6 +1937,28 @@ } } }, + "/containers/list/stats": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "获取容器列表资源占用", + "summary": "Load container stats", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/dto.ContainerListStats" + } + } + } + } + } + }, "/containers/network": { "post": { "security": [ @@ -2156,7 +2190,10 @@ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "$ref": "#/definitions/dto.ImageRepoOption" + } } } } @@ -2493,7 +2530,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/dto.ContainterStats" + "$ref": "#/definitions/dto.ContainerStats" } } } @@ -2518,7 +2555,10 @@ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "$ref": "#/definitions/dto.ComposeTemplateInfo" + } } } } @@ -3742,7 +3782,10 @@ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "type": "string" + } } } } @@ -3830,7 +3873,10 @@ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "type": "string" + } } } } @@ -5050,7 +5096,10 @@ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "$ref": "#/definitions/response.FileTree" + } } } } @@ -5123,7 +5172,10 @@ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "$ref": "#/definitions/response.FileInfo" + } } } } @@ -6213,7 +6265,10 @@ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "$ref": "#/definitions/dto.HostTree" + } } } } @@ -6316,7 +6371,10 @@ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "$ref": "#/definitions/dto.HostTree" + } } } } @@ -6626,7 +6684,10 @@ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "$ref": "#/definitions/response.NginxParam" + } } } } @@ -7329,7 +7390,10 @@ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "$ref": "#/definitions/dto.BackupInfo" + } } } } @@ -7363,7 +7427,10 @@ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "type": "string" + } } } } @@ -7399,7 +7466,10 @@ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "type": "string" + } } } } @@ -8724,7 +8794,10 @@ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "$ref": "#/definitions/response.WebsitePreInstallCheck" + } } } } @@ -9266,7 +9339,10 @@ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "$ref": "#/definitions/model.WebsiteDomain" + } } } } @@ -9405,7 +9481,10 @@ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "$ref": "#/definitions/response.WebsiteDTO" + } } } } @@ -9585,7 +9664,10 @@ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "type": "string" + } } } } @@ -10190,7 +10272,10 @@ "200": { "description": "OK", "schema": { - "type": "anrry" + "type": "array", + "items": { + "$ref": "#/definitions/response.WebsiteDNSRes" + } } } } @@ -10480,6 +10565,51 @@ } } }, + "dto.AppResource": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + } + } + }, + "dto.AppVersion": { + "type": "object", + "properties": { + "detailId": { + "type": "integer" + }, + "version": { + "type": "string" + } + } + }, + "dto.BackupInfo": { + "type": "object", + "properties": { + "backupPath": { + "type": "string" + }, + "bucket": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "type": { + "type": "string" + }, + "vars": { + "type": "string" + } + } + }, "dto.BackupOperate": { "type": "object", "required": [ @@ -10787,6 +10917,26 @@ } } }, + "dto.ComposeTemplateInfo": { + "type": "object", + "properties": { + "content": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "description": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "name": { + "type": "string" + } + } + }, "dto.ComposeTemplateUpdate": { "type": "object", "properties": { @@ -10820,6 +10970,20 @@ } } }, + "dto.ContainerListStats": { + "type": "object", + "properties": { + "containerID": { + "type": "string" + }, + "cpuPercent": { + "type": "number" + }, + "memoryPercent": { + "type": "number" + } + } + }, "dto.ContainerOperate": { "type": "object", "properties": { @@ -10832,6 +10996,9 @@ "type": "string" } }, + "containerID": { + "type": "string" + }, "cpuShares": { "type": "integer" }, @@ -10938,22 +11105,7 @@ } } }, - "dto.ContainerUpgrade": { - "type": "object", - "required": [ - "image", - "name" - ], - "properties": { - "image": { - "type": "string" - }, - "name": { - "type": "string" - } - } - }, - "dto.ContainterStats": { + "dto.ContainerStats": { "type": "object", "properties": { "cache": { @@ -10982,6 +11134,21 @@ } } }, + "dto.ContainerUpgrade": { + "type": "object", + "required": [ + "image", + "name" + ], + "properties": { + "image": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, "dto.CronjobBatchDelete": { "type": "object", "properties": { @@ -11714,6 +11881,23 @@ } } }, + "dto.HostTree": { + "type": "object", + "properties": { + "children": { + "type": "array", + "items": { + "$ref": "#/definitions/dto.TreeChild" + } + }, + "id": { + "type": "integer" + }, + "label": { + "type": "string" + } + } + }, "dto.ImageBuild": { "type": "object", "required": [ @@ -11797,6 +11981,20 @@ } } }, + "dto.ImageRepoOption": { + "type": "object", + "properties": { + "downloadUrl": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "name": { + "type": "string" + } + } + }, "dto.ImageRepoUpdate": { "type": "object", "properties": { @@ -12243,6 +12441,14 @@ } } }, + "dto.Options": { + "type": "object", + "properties": { + "option": { + "type": "string" + } + } + }, "dto.PageContainer": { "type": "object", "required": [ @@ -13014,6 +13220,17 @@ } } }, + "dto.TreeChild": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "label": { + "type": "string" + } + } + }, "dto.UpdateDescription": { "type": "object", "required": [ @@ -14566,14 +14783,6 @@ "websiteId" ], "properties": { - "HttpConfig": { - "type": "string", - "enum": [ - "HTTPSOnly", - "HTTPAlso", - "HTTPToHTTPS" - ] - }, "SSLProtocol": { "type": "array", "items": { @@ -14586,12 +14795,29 @@ "certificate": { "type": "string" }, + "certificatePath": { + "type": "string" + }, "enable": { "type": "boolean" }, + "httpConfig": { + "type": "string", + "enum": [ + "HTTPSOnly", + "HTTPAlso", + "HTTPToHTTPS" + ] + }, + "importType": { + "type": "string" + }, "privateKey": { "type": "string" }, + "privateKeyPath": { + "type": "string" + }, "type": { "type": "string", "enum": [ @@ -14851,6 +15077,9 @@ "pageSize" ], "properties": { + "acmeAccountId": { + "type": "integer" + }, "page": { "type": "integer" }, @@ -15201,6 +15430,18 @@ "values": {} } }, + "response.AppService": { + "type": "object", + "properties": { + "config": {}, + "label": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, "response.FileInfo": { "type": "object", "properties": { @@ -15263,6 +15504,26 @@ } } }, + "response.FileTree": { + "type": "object", + "properties": { + "children": { + "type": "array", + "items": { + "$ref": "#/definitions/response.FileTree" + } + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "path": { + "type": "string" + } + } + }, "response.NginxParam": { "type": "object", "properties": { @@ -15343,6 +15604,23 @@ } } }, + "response.WebsiteDNSRes": { + "type": "object", + "properties": { + "domain": { + "type": "string" + }, + "err": { + "type": "string" + }, + "resolve": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, "response.WebsiteDTO": { "type": "object", "properties": { @@ -15495,6 +15773,23 @@ } } }, + "response.WebsitePreInstallCheck": { + "type": "object", + "properties": { + "appName": { + "type": "string" + }, + "name": { + "type": "string" + }, + "status": { + "type": "string" + }, + "version": { + "type": "string" + } + } + }, "response.WebsiteWafConfig": { "type": "object", "properties": { diff --git a/cmd/server/docs/swagger.yaml b/cmd/server/docs/swagger.yaml index b8626ff6c..136f5ad3f 100644 --- a/cmd/server/docs/swagger.yaml +++ b/cmd/server/docs/swagger.yaml @@ -26,6 +26,35 @@ definitions: oldRule: $ref: '#/definitions/dto.AddrRuleOperate' type: object + dto.AppResource: + properties: + name: + type: string + type: + type: string + type: object + dto.AppVersion: + properties: + detailId: + type: integer + version: + type: string + type: object + dto.BackupInfo: + properties: + backupPath: + type: string + bucket: + type: string + createdAt: + type: string + id: + type: integer + type: + type: string + vars: + type: string + type: object dto.BackupOperate: properties: accessKey: @@ -233,6 +262,19 @@ definitions: required: - name type: object + dto.ComposeTemplateInfo: + properties: + content: + type: string + createdAt: + type: string + description: + type: string + id: + type: integer + name: + type: string + type: object dto.ComposeTemplateUpdate: properties: content: @@ -255,6 +297,15 @@ definitions: - name - path type: object + dto.ContainerListStats: + properties: + containerID: + type: string + cpuPercent: + type: number + memoryPercent: + type: number + type: object dto.ContainerOperate: properties: autoRemove: @@ -263,6 +314,8 @@ definitions: items: type: string type: array + containerID: + type: string cpuShares: type: integer env: @@ -336,17 +389,7 @@ definitions: spaceReclaimed: type: integer type: object - dto.ContainerUpgrade: - properties: - image: - type: string - name: - type: string - required: - - image - - name - type: object - dto.ContainterStats: + dto.ContainerStats: properties: cache: type: number @@ -365,6 +408,16 @@ definitions: shotTime: type: string type: object + dto.ContainerUpgrade: + properties: + image: + type: string + name: + type: string + required: + - image + - name + type: object dto.CronjobBatchDelete: properties: cleanData: @@ -859,6 +912,17 @@ definitions: - port - user type: object + dto.HostTree: + properties: + children: + items: + $ref: '#/definitions/dto.TreeChild' + type: array + id: + type: integer + label: + type: string + type: object dto.ImageBuild: properties: dockerfile: @@ -914,6 +978,15 @@ definitions: required: - ids type: object + dto.ImageRepoOption: + properties: + downloadUrl: + type: string + id: + type: integer + name: + type: string + type: object dto.ImageRepoUpdate: properties: auth: @@ -1209,6 +1282,11 @@ definitions: required: - name type: object + dto.Options: + properties: + option: + type: string + type: object dto.PageContainer: properties: filters: @@ -1723,6 +1801,13 @@ definitions: ntpSite: type: string type: object + dto.TreeChild: + properties: + id: + type: integer + label: + type: string + type: object dto.UpdateDescription: properties: description: @@ -2754,12 +2839,6 @@ definitions: type: object request.WebsiteHTTPSOp: properties: - HttpConfig: - enum: - - HTTPSOnly - - HTTPAlso - - HTTPToHTTPS - type: string SSLProtocol: items: type: string @@ -2768,10 +2847,22 @@ definitions: type: string certificate: type: string + certificatePath: + type: string enable: type: boolean + httpConfig: + enum: + - HTTPSOnly + - HTTPAlso + - HTTPToHTTPS + type: string + importType: + type: string privateKey: type: string + privateKeyPath: + type: string type: enum: - existed @@ -2948,6 +3039,8 @@ definitions: type: object request.WebsiteSSLSearch: properties: + acmeAccountId: + type: integer page: type: integer pageSize: @@ -3185,6 +3278,14 @@ definitions: value: {} values: {} type: object + response.AppService: + properties: + config: {} + label: + type: string + value: + type: string + type: object response.FileInfo: properties: content: @@ -3226,6 +3327,19 @@ definitions: user: type: string type: object + response.FileTree: + properties: + children: + items: + $ref: '#/definitions/response.FileTree' + type: array + id: + type: string + name: + type: string + path: + type: string + type: object response.NginxParam: properties: name: @@ -3278,6 +3392,17 @@ definitions: url: type: string type: object + response.WebsiteDNSRes: + properties: + domain: + type: string + err: + type: string + resolve: + type: string + value: + type: string + type: object response.WebsiteDTO: properties: IPV6: @@ -3378,6 +3503,17 @@ definitions: $ref: '#/definitions/response.NginxParam' type: array type: object + response.WebsitePreInstallCheck: + properties: + appName: + type: string + name: + type: string + status: + type: string + version: + type: string + type: object response.WebsiteWafConfig: properties: content: @@ -3537,7 +3673,9 @@ paths: "200": description: OK schema: - type: anrry + items: + $ref: '#/definitions/dto.AppVersion' + type: array security: - ApiKeyAuth: [] summary: Search app update version by install id @@ -3621,7 +3759,9 @@ paths: "200": description: OK schema: - type: anrry + items: + $ref: '#/definitions/dto.AppResource' + type: array security: - ApiKeyAuth: [] summary: Check before delete @@ -3870,7 +4010,9 @@ paths: "200": description: OK schema: - type: anrry + items: + $ref: '#/definitions/response.AppService' + type: array security: - ApiKeyAuth: [] summary: Search app service by key @@ -4292,7 +4434,9 @@ paths: "200": description: OK schema: - type: anrry + items: + $ref: '#/definitions/dto.Options' + type: array security: - ApiKeyAuth: [] summary: List images @@ -4611,6 +4755,19 @@ paths: summary: List containers tags: - Container + /containers/list/stats: + get: + description: 获取容器列表资源占用 + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/dto.ContainerListStats' + type: array + security: + - ApiKeyAuth: [] + summary: Load container stats /containers/network: post: consumes: @@ -4756,7 +4913,9 @@ paths: "200": description: OK schema: - type: anrry + items: + $ref: '#/definitions/dto.ImageRepoOption' + type: array security: - ApiKeyAuth: [] summary: List image repos @@ -4969,7 +5128,7 @@ paths: "200": description: OK schema: - $ref: '#/definitions/dto.ContainterStats' + $ref: '#/definitions/dto.ContainerStats' security: - ApiKeyAuth: [] summary: Container stats @@ -4984,7 +5143,9 @@ paths: "200": description: OK schema: - type: anrry + items: + $ref: '#/definitions/dto.ComposeTemplateInfo' + type: array security: - ApiKeyAuth: [] summary: List compose templates @@ -5767,7 +5928,9 @@ paths: "200": description: OK schema: - type: anrry + items: + type: string + type: array security: - ApiKeyAuth: [] summary: Check before delete mysql database @@ -5823,7 +5986,9 @@ paths: "200": description: OK schema: - type: anrry + items: + type: string + type: array security: - ApiKeyAuth: [] summary: List mysql database names @@ -6597,7 +6762,9 @@ paths: "200": description: OK schema: - type: anrry + items: + $ref: '#/definitions/response.FileTree' + type: array security: - ApiKeyAuth: [] summary: Load files tree @@ -6643,7 +6810,9 @@ paths: "200": description: OK schema: - type: anrry + items: + $ref: '#/definitions/response.FileInfo' + type: array security: - ApiKeyAuth: [] summary: Page file @@ -7336,7 +7505,9 @@ paths: "200": description: OK schema: - type: anrry + items: + $ref: '#/definitions/dto.HostTree' + type: array security: - ApiKeyAuth: [] summary: Page host @@ -7399,7 +7570,9 @@ paths: "200": description: OK schema: - type: anrry + items: + $ref: '#/definitions/dto.HostTree' + type: array security: - ApiKeyAuth: [] summary: Load host tree @@ -7595,7 +7768,9 @@ paths: "200": description: OK schema: - type: anrry + items: + $ref: '#/definitions/response.NginxParam' + type: array security: - ApiKeyAuth: [] summary: Load partial OpenResty conf @@ -8044,7 +8219,9 @@ paths: "200": description: OK schema: - type: anrry + items: + $ref: '#/definitions/dto.BackupInfo' + type: array security: - ApiKeyAuth: [] summary: List backup accounts @@ -8065,7 +8242,9 @@ paths: "200": description: OK schema: - type: anrry + items: + type: string + type: array security: - ApiKeyAuth: [] summary: List buckets @@ -8087,7 +8266,9 @@ paths: "200": description: OK schema: - type: anrry + items: + type: string + type: array security: - ApiKeyAuth: [] summary: List files from backup accounts @@ -8927,7 +9108,9 @@ paths: "200": description: OK schema: - type: anrry + items: + $ref: '#/definitions/response.WebsitePreInstallCheck' + type: array security: - ApiKeyAuth: [] summary: Check before create website @@ -9274,7 +9457,9 @@ paths: "200": description: OK schema: - type: anrry + items: + $ref: '#/definitions/model.WebsiteDomain' + type: array security: - ApiKeyAuth: [] summary: Search website domains by websiteId @@ -9360,7 +9545,9 @@ paths: "200": description: OK schema: - type: anrry + items: + $ref: '#/definitions/response.WebsiteDTO' + type: array security: - ApiKeyAuth: [] summary: List websites @@ -9476,7 +9663,9 @@ paths: "200": description: OK schema: - type: anrry + items: + type: string + type: array security: - ApiKeyAuth: [] summary: List website names @@ -9860,7 +10049,9 @@ paths: "200": description: OK schema: - type: anrry + items: + $ref: '#/definitions/response.WebsiteDNSRes' + type: array security: - ApiKeyAuth: [] summary: Resolve website ssl diff --git a/frontend/src/api/interface/container.ts b/frontend/src/api/interface/container.ts index 5db2daf64..5c295c1fb 100644 --- a/frontend/src/api/interface/container.ts +++ b/frontend/src/api/interface/container.ts @@ -55,11 +55,18 @@ export namespace Container { createTime: string; state: string; runTime: string; - cpuPercent: number; - memoryPercent: number; ports: Array; isFromApp: boolean; isFromCompose: boolean; + + hasLoad: boolean; + cpuPercent: number; + memoryPercent: number; + } + export interface ContainerListStats { + containerID: string; + cpuPercent: number; + memoryPercent: number; } export interface ContainerStats { cpuPercent: number; diff --git a/frontend/src/api/modules/container.ts b/frontend/src/api/modules/container.ts index dac6b8612..a76249ff2 100644 --- a/frontend/src/api/modules/container.ts +++ b/frontend/src/api/modules/container.ts @@ -26,6 +26,9 @@ export const loadContainerInfo = (name: string) => { export const cleanContainerLog = (containerName: string) => { return http.post(`/containers/clean/log`, { name: containerName }); }; +export const containerListStats = () => { + return http.get>(`/containers/list/stats`); +}; export const containerStats = (id: string) => { return http.get(`/containers/stats/${id}`); }; diff --git a/frontend/src/views/container/container/index.vue b/frontend/src/views/container/container/index.vue index 943c634a4..88ed796e1 100644 --- a/frontend/src/views/container/container/index.vue +++ b/frontend/src/views/container/container/index.vue @@ -82,8 +82,13 @@ @@ -160,6 +165,7 @@ import PortJumpDialog from '@/components/port-jump/index.vue'; import Status from '@/components/status/index.vue'; import { reactive, onMounted, ref } from 'vue'; import { + containerListStats, containerOperator, containerPrune, inspect, @@ -244,6 +250,7 @@ const search = async (column?: any) => { order: column?.order ? column.order : 'null', }; loading.value = true; + loadStats(); await searchContainer(params) .then((res) => { loading.value = false; @@ -255,6 +262,24 @@ const search = async (column?: any) => { }); }; +const loadStats = async () => { + const res = await containerListStats(); + let stats = res.data || []; + if (stats.length === 0) { + return; + } + for (const container of data.value) { + for (const item of stats) { + if (container.containerID === item.containerID) { + container.hasLoad = true; + container.cpuPercent = item.cpuPercent; + container.memoryPercent = item.memoryPercent; + break; + } + } + } +}; + const dialogOperateRef = ref(); const onEdit = async (container: string) => { const res = await loadContainerInfo(container); diff --git a/frontend/src/views/home/index.vue b/frontend/src/views/home/index.vue index 063151e90..b860d45fa 100644 --- a/frontend/src/views/home/index.vue +++ b/frontend/src/views/home/index.vue @@ -119,7 +119,7 @@ {{ $t('monitor.write') }}: {{ currentChartInfo.ioWriteBytes }} MB {{ $t('home.rwPerSecond') }}: {{ currentChartInfo.ioCount }} - {{ $t('commons.units.time') }} + {{ $t('commons.units.time') }}/s {{ $t('home.ioDelay') }}: {{ currentChartInfo.ioTime }} ms