Browse Source

feat: 优化容器界面加载速度 (#1565)

pull/1566/head
ssongliu 1 year ago committed by GitHub
parent
commit
0ac2b9df7a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      backend/app/api/v1/app_install.go
  2. 6
      backend/app/api/v1/backup.go
  3. 2
      backend/app/api/v1/compose_template.go
  4. 16
      backend/app/api/v1/container.go
  5. 4
      backend/app/api/v1/database_mysql.go
  6. 4
      backend/app/api/v1/file.go
  7. 4
      backend/app/api/v1/host.go
  8. 2
      backend/app/api/v1/image.go
  9. 2
      backend/app/api/v1/image_repo.go
  10. 2
      backend/app/api/v1/nginx.go
  11. 8
      backend/app/api/v1/website.go
  12. 2
      backend/app/api/v1/website_ssl.go
  13. 10
      backend/app/dto/container.go
  14. 40
      backend/app/service/container.go
  15. 1
      backend/router/ro_container.go
  16. 387
      cmd/server/docs/docs.go
  17. 387
      cmd/server/docs/swagger.json
  18. 269
      cmd/server/docs/swagger.yaml
  19. 11
      frontend/src/api/interface/container.ts
  20. 3
      frontend/src/api/modules/container.ts
  21. 25
      frontend/src/views/container/container/index.vue
  22. 2
      frontend/src/views/home/index.vue

6
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) {

6
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) {

2
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) {

16
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) {

4
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) {

4
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) {

4
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) {

2
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) {

2
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) {

2
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) {

8
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) {

2
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) {

10
backend/app/dto/container.go

@ -24,8 +24,6 @@ type ContainerInfo struct {
State string `json:"state"`
RunTime string `json:"runTime"`
CPUPercent float64 `json:"cpuPercent"`
MemoryPercent float64 `json:"memoryPercent"`
Ports []string `json:"ports"`
IsFromApp bool `json:"isFromApp"`
@ -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"`

40
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,10 +130,8 @@ 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) {
item := records[i]
IsFromCompose := false
if _, ok := item.Labels[composeProjectLabel]; ok {
IsFromCompose = true
@ -150,7 +149,6 @@ func (u *ContainerService) Page(req dto.PageContainer) (int64, interface{}, erro
}
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"),
@ -159,16 +157,11 @@ func (u *ContainerService) Page(req dto.PageContainer) (int64, interface{}, erro
ImageName: item.Image,
State: item.State,
RunTime: item.Status,
CPUPercent: cpu,
MemoryPercent: mem,
Ports: ports,
IsFromApp: IsFromApp,
IsFromCompose: IsFromCompose,
}
wg.Done()
}(records[i], i)
}
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

1
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)

387
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": {

387
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": {

269
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

11
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<string>;
isFromApp: boolean;
isFromCompose: boolean;
hasLoad: boolean;
cpuPercent: number;
memoryPercent: number;
}
export interface ContainerListStats {
containerID: string;
cpuPercent: number;
memoryPercent: number;
}
export interface ContainerStats {
cpuPercent: number;

3
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<Array<Container.ContainerListStats>>(`/containers/list/stats`);
};
export const containerStats = (id: string) => {
return http.get<Container.ContainerStats>(`/containers/stats/${id}`);
};

25
frontend/src/views/container/container/index.vue

@ -82,8 +82,13 @@
</el-table-column>
<el-table-column :label="$t('container.source')" show-overflow-tooltip min-width="75" fix>
<template #default="{ row }">
<div v-if="row.hasLoad">
<div>CPU: {{ row.cpuPercent.toFixed(2) }}%</div>
<div>{{ $t('monitor.memory') }}: {{ row.memoryPercent.toFixed(2) }}%</div>
</div>
<div v-if="!row.hasLoad">
<el-button link loading></el-button>
</div>
</template>
</el-table-column>
<el-table-column :label="$t('commons.table.port')" min-width="120" prop="ports" fix>
@ -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);

2
frontend/src/views/home/index.vue

@ -119,7 +119,7 @@
<el-tag>{{ $t('monitor.write') }}: {{ currentChartInfo.ioWriteBytes }} MB</el-tag>
<el-tag>
{{ $t('home.rwPerSecond') }}: {{ currentChartInfo.ioCount }}
{{ $t('commons.units.time') }}
{{ $t('commons.units.time') }}/s
</el-tag>
<el-tag>{{ $t('home.ioDelay') }}: {{ currentChartInfo.ioTime }} ms</el-tag>
</div>

Loading…
Cancel
Save