diff --git a/agent/app/api/v2/container.go b/agent/app/api/v2/container.go index ed7f9d3b3..02d8de4fc 100644 --- a/agent/app/api/v2/container.go +++ b/agent/app/api/v2/container.go @@ -54,6 +54,24 @@ func (b *BaseApi) ListContainer(c *gin.Context) { helper.SuccessWithData(c, list) } + +// @Tags Container +// @Summary Load containers status +// @Description 获取容器状态 +// @Accept json +// @Produce json +// @Success 200 +// @Security ApiKeyAuth +// @Router /containers/status [get] +func (b *BaseApi) LoadContainerStatus(c *gin.Context) { + data, err := containerService.LoadStatus() + if err != nil { + helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) + return + } + helper.SuccessWithData(c, data) +} + // @Tags Container Compose // @Summary Page composes // @Description 获取编排列表分页 diff --git a/agent/app/dto/container.go b/agent/app/dto/container.go index 90a351768..e5c06c764 100644 --- a/agent/app/dto/container.go +++ b/agent/app/dto/container.go @@ -8,7 +8,7 @@ type PageContainer struct { PageInfo Name string `json:"name"` State string `json:"state" validate:"required,oneof=all created running paused restarting removing exited dead"` - OrderBy string `json:"orderBy" validate:"required,oneof=name state created_at"` + OrderBy string `json:"orderBy" validate:"required,oneof=name created_at"` Order string `json:"order" validate:"required,oneof=null ascending descending"` Filters string `json:"filters"` ExcludeAppStore bool `json:"excludeAppStore"` @@ -39,6 +39,16 @@ type ContainerInfo struct { Websites []string `json:"websites"` } +type ContainerStatus struct { + All uint `json:"all"` + Created uint `json:"created"` + Running uint `json:"running"` + Paused uint `json:"paused"` + Restarting uint `json:"restarting"` + Removing uint `json:"removing"` + Exited uint `json:"exited"` + Dead uint `json:"dead"` +} type ResourceLimit struct { CPU int `json:"cpu"` Memory uint64 `json:"memory"` diff --git a/agent/app/service/container.go b/agent/app/service/container.go index aac779099..0c8f241ee 100644 --- a/agent/app/service/container.go +++ b/agent/app/service/container.go @@ -51,6 +51,7 @@ type ContainerService struct{} type IContainerService interface { Page(req dto.PageContainer) (int64, interface{}, error) List() ([]string, error) + LoadStatus() (dto.ContainerStatus, error) PageNetwork(req dto.SearchWithPage) (int64, interface{}, error) ListNetwork() ([]dto.Options, error) PageVolume(req dto.SearchWithPage) (int64, interface{}, error) @@ -149,13 +150,6 @@ func (u *ContainerService) Page(req dto.PageContainer) (int64, interface{}, erro } return list[i].Names[0][1:] > list[j].Names[0][1:] }) - case "state": - sort.Slice(list, func(i, j int) bool { - if req.Order == constant.OrderAsc { - return list[i].State < list[j].State - } - return list[i].State > list[j].State - }) default: sort.Slice(list, func(i, j int) bool { if req.Order == constant.OrderAsc { @@ -245,6 +239,38 @@ func (u *ContainerService) List() ([]string, error) { return datas, nil } +func (u *ContainerService) LoadStatus() (dto.ContainerStatus, error) { + var data dto.ContainerStatus + client, err := docker.NewDockerClient() + if err != nil { + return data, err + } + defer client.Close() + containers, err := client.ContainerList(context.Background(), container.ListOptions{All: true}) + if err != nil { + return data, err + } + data.All = uint(len(containers)) + for _, item := range containers { + switch item.State { + case "created": + data.Created++ + case "running": + data.Running++ + case "paused": + data.Paused++ + case "restarting": + data.Restarting++ + case "dead": + data.Dead++ + case "exited": + data.Exited++ + case "removing": + data.Removing++ + } + } + return data, nil +} func (u *ContainerService) ContainerListStats() ([]dto.ContainerListStats, error) { client, err := docker.NewDockerClient() if err != nil { diff --git a/agent/router/ro_container.go b/agent/router/ro_container.go index eaabbbfec..508550465 100644 --- a/agent/router/ro_container.go +++ b/agent/router/ro_container.go @@ -20,6 +20,7 @@ func (s *ContainerRouter) InitRouter(Router *gin.RouterGroup) { baRouter.POST("/info", baseApi.ContainerInfo) baRouter.POST("/search", baseApi.SearchContainer) baRouter.POST("/list", baseApi.ListContainer) + baRouter.GET("/status", baseApi.LoadContainerStatus) baRouter.GET("/list/stats", baseApi.ContainerListStats) baRouter.GET("/search/log", baseApi.ContainerLogs) baRouter.POST("/download/log", baseApi.DownloadContainerLogs) diff --git a/frontend/src/api/interface/container.ts b/frontend/src/api/interface/container.ts index fb9563405..6a4a1e209 100644 --- a/frontend/src/api/interface/container.ts +++ b/frontend/src/api/interface/container.ts @@ -24,6 +24,16 @@ export namespace Container { orderBy: string; order: string; } + export interface ContainerStatus { + all: number; + created: number; + running: number; + paused: number; + restarting: number; + removing: number; + exited: number; + dead: number; + } export interface ResourceLimit { cpu: number; memory: number; diff --git a/frontend/src/api/modules/container.ts b/frontend/src/api/modules/container.ts index c84e35cb9..e044d74a3 100644 --- a/frontend/src/api/modules/container.ts +++ b/frontend/src/api/modules/container.ts @@ -9,6 +9,9 @@ export const searchContainer = (params: Container.ContainerSearch) => { export const listContainer = () => { return http.post>(`/containers/list`, {}); }; +export const loadContainerStatus = () => { + return http.get(`/containers/status`); +}; export const loadResourceLimit = () => { return http.get(`/containers/limit`); }; diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index 98ab6e635..6fe519874 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -318,7 +318,7 @@ const message = { host: '主机', files: '文件', monitor: '监控', - terminal: '终端', + terminal: 'WEB终端', settings: '面板设置', toolbox: '工具箱', logs: '日志审计', @@ -1137,7 +1137,7 @@ const message = { role: '权限', info: '属性', linkFile: '软连接文件', - terminal: 'Web终端', + terminal: '终端', shareList: '分享列表', zip: '压缩', group: '用户组', diff --git a/frontend/src/routers/modules/container.ts b/frontend/src/routers/modules/container.ts index c4c3cacd7..b10373e09 100644 --- a/frontend/src/routers/modules/container.ts +++ b/frontend/src/routers/modules/container.ts @@ -28,6 +28,17 @@ const containerRouter = { requiresAuth: false, }, }, + { + path: 'container/operate', + name: 'ContainerCreate', + component: () => import('@/views/container/container/operate/index.vue'), + props: true, + hidden: true, + meta: { + activeMenu: '/containers', + requiresAuth: false, + }, + }, { path: 'composeDetail/:filters?', name: 'ComposeDetail', diff --git a/frontend/src/views/container/container/index.vue b/frontend/src/views/container/container/index.vue index 37534814e..9a6898521 100644 --- a/frontend/src/views/container/container/index.vue +++ b/frontend/src/views/container/container/index.vue @@ -5,9 +5,73 @@ 【 {{ $t('container.setting') }} 】 {{ $t('container.startIn') }} + +
+ + {{ $t('commons.table.all') }} * {{ countItem.all }} + + + {{ $t('commons.status.running') }} * {{ countItem.running }} + + + {{ $t('commons.status.created') }} * {{ countItem.created }} + + + {{ $t('commons.status.paused') }} * {{ countItem.paused }} + + + {{ $t('commons.status.restarting') }} * {{ countItem.restarting }} + + + {{ $t('commons.status.removing') }} * {{ countItem.removing }} + + + {{ $t('commons.status.exited') }} * {{ countItem.exited }} + + + {{ $t('commons.status.dead') }} * {{ countItem.dead }} + +
+