Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions agent/app/api/v2/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,13 +264,19 @@
}

// @Summary Load container stats size
// @Accept json
// @Param request body dto.OperationWithName true "request"
// @Success 200 {object} dto.ContainerItemStats
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/item/stats/:id [get]
// @Router /containers/item/stats [post]
func (b *BaseApi) ContainerItemStats(c *gin.Context) {
containerID := c.Param("id")
data, err := containerService.ContainerItemStats(containerID)
var req dto.OperationWithName
if err := helper.CheckBindAndValidate(&req, c); err != nil {

Check warning on line 275 in agent/app/api/v2/container.go

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this unnecessary variable declaration and use the expression directly in the condition.

See more on https://sonarcloud.io/project/issues?id=1Panel-dev_1Panel&issues=AZrc4qs3Yl-qfs2jjbTg&open=AZrc4qs3Yl-qfs2jjbTg&pullRequest=11148
return
}

data, err := containerService.ContainerItemStats(req)
if err != nil {
helper.InternalServer(c, err)
return
Expand Down
18 changes: 9 additions & 9 deletions agent/app/dto/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,6 @@ type ContainerStatus struct {
NetworkCount int `json:"networkCount"`
VolumeCount int `json:"volumeCount"`
RepoCount int `json:"repoCount"`

ContainerUsage int64 `json:"containerUsage"`
ContainerReclaimable int64 `json:"containerReclaimable"`
ImageUsage int64 `json:"imageUsage"`
ImageReclaimable int64 `json:"imageReclaimable"`
VolumeUsage int64 `json:"volumeUsage"`
VolumeReclaimable int64 `json:"volumeReclaimable"`
BuildCacheUsage int64 `json:"buildCacheUsage"`
BuildCacheReclaimable int64 `json:"buildCacheReclaimable"`
}
type ResourceLimit struct {
CPU int `json:"cpu"`
Expand Down Expand Up @@ -129,6 +120,15 @@ type ContainerUpgrade struct {
type ContainerItemStats struct {
SizeRw int64 `json:"sizeRw"`
SizeRootFs int64 `json:"sizeRootFs"`

ContainerUsage int64 `json:"containerUsage"`
ContainerReclaimable int64 `json:"containerReclaimable"`
ImageUsage int64 `json:"imageUsage"`
ImageReclaimable int64 `json:"imageReclaimable"`
VolumeUsage int64 `json:"volumeUsage"`
VolumeReclaimable int64 `json:"volumeReclaimable"`
BuildCacheUsage int64 `json:"buildCacheUsage"`
BuildCacheReclaimable int64 `json:"buildCacheReclaimable"`
}
type ContainerListStats struct {
ContainerID string `json:"containerID"`
Expand Down
76 changes: 40 additions & 36 deletions agent/app/service/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
ContainerUpgrade(req dto.ContainerUpgrade) error
ContainerInfo(req dto.OperationWithName) (*dto.ContainerOperate, error)
ContainerListStats() ([]dto.ContainerListStats, error)
ContainerItemStats(containerID string) (dto.ContainerItemStats, error)
ContainerItemStats(req dto.OperationWithName) (dto.ContainerItemStats, error)
LoadResourceLimit() (*dto.ResourceLimit, error)
ContainerRename(req dto.ContainerRename) error
ContainerCommit(req dto.ContainerCommit) error
Expand Down Expand Up @@ -199,45 +199,20 @@
defer client.Close()
c := context.Background()

usage, err := client.DiskUsage(c, types.DiskUsageOptions{})
if err != nil {
return data, err
}

data.ImageCount = len(usage.Images)
data.VolumeCount = len(usage.Volumes)
for _, item := range usage.Images {
data.ImageUsage += item.Size
if item.Containers < 1 {
data.ImageReclaimable += item.Size
}
}
for _, item := range usage.Containers {
data.ContainerUsage += item.SizeRw
if item.State != "running" {
data.ContainerReclaimable += item.SizeRw
}
}
for _, item := range usage.Volumes {
data.VolumeUsage += item.UsageData.Size
if item.UsageData.RefCount == 0 {
data.VolumeReclaimable += item.UsageData.Size
}
}
for _, item := range usage.BuildCache {
data.BuildCacheUsage += item.Size
}
images, _ := client.ImageList(c, image.ListOptions{All: true})

Check failure on line 202 in agent/app/service/container.go

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Handle this error explicitly or document why it can be safely ignored.

See more on https://sonarcloud.io/project/issues?id=1Panel-dev_1Panel&issues=AZrc4qk2Yl-qfs2jjbTZ&open=AZrc4qk2Yl-qfs2jjbTZ&pullRequest=11148
data.ImageCount = len(images)
repo, _ := imageRepoRepo.List()

Check failure on line 204 in agent/app/service/container.go

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Handle this error explicitly or document why it can be safely ignored.

See more on https://sonarcloud.io/project/issues?id=1Panel-dev_1Panel&issues=AZrc4qk2Yl-qfs2jjbTa&open=AZrc4qk2Yl-qfs2jjbTa&pullRequest=11148
data.RepoCount = len(repo)
templates, _ := composeRepo.List()

Check failure on line 206 in agent/app/service/container.go

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Handle this error explicitly or document why it can be safely ignored.

See more on https://sonarcloud.io/project/issues?id=1Panel-dev_1Panel&issues=AZrc4qk2Yl-qfs2jjbTb&open=AZrc4qk2Yl-qfs2jjbTb&pullRequest=11148
data.ComposeTemplateCount = len(templates)
networks, _ := client.NetworkList(c, network.ListOptions{})

Check failure on line 208 in agent/app/service/container.go

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Handle this error explicitly or document why it can be safely ignored.

See more on https://sonarcloud.io/project/issues?id=1Panel-dev_1Panel&issues=AZrc4qk2Yl-qfs2jjbTc&open=AZrc4qk2Yl-qfs2jjbTc&pullRequest=11148
data.NetworkCount = len(networks)
volumes, _ := client.VolumeList(c, volume.ListOptions{})

Check failure on line 210 in agent/app/service/container.go

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Handle this error explicitly or document why it can be safely ignored.

See more on https://sonarcloud.io/project/issues?id=1Panel-dev_1Panel&issues=AZrc4qk2Yl-qfs2jjbTd&open=AZrc4qk2Yl-qfs2jjbTd&pullRequest=11148
data.VolumeCount = len(volumes.Volumes)
data.ComposeCount = loadComposeCount(client)
data.ContainerCount = len(usage.Containers)
for _, item := range usage.Containers {
containers, _ := client.ContainerList(c, container.ListOptions{All: true})

Check failure on line 213 in agent/app/service/container.go

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Handle this error explicitly or document why it can be safely ignored.

See more on https://sonarcloud.io/project/issues?id=1Panel-dev_1Panel&issues=AZrc4qk2Yl-qfs2jjbTe&open=AZrc4qk2Yl-qfs2jjbTe&pullRequest=11148
data.ContainerCount = len(containers)
for _, item := range containers {
switch item.State {
case "created":
data.Created++
Expand All @@ -257,19 +232,48 @@
}
return data, nil
}
func (u *ContainerService) ContainerItemStats(containerID string) (dto.ContainerItemStats, error) {
func (u *ContainerService) ContainerItemStats(req dto.OperationWithName) (dto.ContainerItemStats, error) {
var data dto.ContainerItemStats
client, err := docker.NewDockerClient()
if err != nil {
return data, err
}
defer client.Close()
containerInfo, _, err := client.ContainerInspectWithRaw(context.Background(), containerID, true)
if req.Name != "system" {
defer client.Close()
containerInfo, _, err := client.ContainerInspectWithRaw(context.Background(), req.Name, true)
if err != nil {
return data, err
}
data.SizeRw = *containerInfo.SizeRw
data.SizeRootFs = *containerInfo.SizeRootFs
return data, nil
}

usage, err := client.DiskUsage(context.Background(), types.DiskUsageOptions{})
if err != nil {
return data, err
}
data.SizeRw = *containerInfo.SizeRw
data.SizeRootFs = *containerInfo.SizeRootFs
for _, item := range usage.Images {
data.ImageUsage += item.Size
if item.Containers < 1 {
data.ImageReclaimable += item.Size
}
}
for _, item := range usage.Containers {
data.ContainerUsage += item.SizeRw
if item.State != "running" {
data.ContainerReclaimable += item.SizeRw
}
}
for _, item := range usage.Volumes {
data.VolumeUsage += item.UsageData.Size
if item.UsageData.RefCount == 0 {
data.VolumeReclaimable += item.UsageData.Size
}
}
for _, item := range usage.BuildCache {
data.BuildCacheUsage += item.Size
}
return data, nil
}
func (u *ContainerService) ContainerListStats() ([]dto.ContainerListStats, error) {
Expand Down
2 changes: 1 addition & 1 deletion agent/router/ro_container.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func (s *ContainerRouter) InitRouter(Router *gin.RouterGroup) {
baRouter.POST("/list/byimage", baseApi.ListContainerByImage)
baRouter.GET("/status", baseApi.LoadContainerStatus)
baRouter.GET("/list/stats", baseApi.ContainerListStats)
baRouter.GET("/item/stats/:id", baseApi.ContainerItemStats)
baRouter.POST("/item/stats", baseApi.ContainerItemStats)
baRouter.GET("/search/log", baseApi.ContainerStreamLogs)
baRouter.POST("/download/log", baseApi.DownloadContainerLogs)
baRouter.GET("/limit", baseApi.LoadResourceLimit)
Expand Down
9 changes: 9 additions & 0 deletions frontend/src/api/interface/container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,15 @@ export namespace Container {
export interface ContainerItemStats {
sizeRw: number;
sizeRootFs: number;

containerUsage: number;
containerReclaimable: number;
imageUsage: number;
imageReclaimable: number;
volumeUsage: number;
volumeReclaimable: number;
buildCacheUsage: number;
buildCacheReclaimable: number;
}
export interface ContainerListStats {
containerID: string;
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/api/modules/container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export const cleanContainerLog = (containerName: string, operateNode?: string) =
return http.post(`/containers/clean/log${params}`, { name: containerName });
};
export const containerItemStats = (containerID: string) => {
return http.get<Container.ContainerItemStats>(`/containers/item/stats/${containerID}`);
return http.post<Container.ContainerItemStats>(`/containers/item/stats`, { name: containerID }, TimeoutEnum.T_60S);
};
export const containerListStats = () => {
return http.get<Array<Container.ContainerListStats>>(`/containers/list/stats`);
Expand Down
30 changes: 28 additions & 2 deletions frontend/src/views/container/dashboard/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,13 @@

<CardWithHeader :header="$t('container.diskUsage')" class="card-interval">
<template #body>
<el-descriptions direction="vertical" align="center" :column="4" class="mt-2">
<el-descriptions
direction="vertical"
align="center"
v-loading="usageLoading"
:column="4"
class="mt-2"
>
<el-descriptions-item label-width="25%" align="center" :label="$t('container.image')">
{{
$t('container.usage', [
Expand Down Expand Up @@ -188,7 +194,7 @@
</template>

<script lang="ts" setup>
import { containerPrune, loadContainerStatus, loadDaemonJson } from '@/api/modules/container';
import { containerItemStats, containerPrune, loadContainerStatus, loadDaemonJson } from '@/api/modules/container';
import DockerStatus from '@/views/container/docker-status/index.vue';
import { getSettingInfo } from '@/api/modules/setting';
import { computeSize2, newUUID } from '@/utils/util';
Expand All @@ -200,6 +206,7 @@ import i18n from '@/lang';
const taskLogRef = ref();

const loading = ref();
const usageLoading = ref(false);
const isActive = ref(false);
const isExist = ref(false);
const countItem = reactive({
Expand Down Expand Up @@ -237,6 +244,7 @@ const search = () => {
return;
}
loadContainerCount();
loadUsage();
loadContainerSetting();
};

Expand Down Expand Up @@ -269,6 +277,24 @@ const loadContainerCount = async () => {
});
};

const loadUsage = async () => {
usageLoading.value = true;
await containerItemStats('system')
.then((res) => {
countItem.containerUsage = res.data.containerUsage;
countItem.containerReclaimable = res.data.containerReclaimable;
countItem.imageUsage = res.data.imageUsage;
countItem.imageReclaimable = res.data.imageReclaimable;
countItem.volumeUsage = res.data.volumeUsage;
countItem.volumeReclaimable = res.data.volumeReclaimable;
countItem.buildCacheUsage = res.data.buildCacheUsage;
countItem.buildCacheReclaimable = res.data.buildCacheReclaimable;
})
.finally(() => {
usageLoading.value = false;
});
};

const loadContainerSetting = async () => {
const res = await loadDaemonJson();
countItem.mirrors = res.data.registryMirrors || [];
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/views/container/template/detail/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
v-model="detailInfo"
mode="yaml"
:heightDiff="160"
:disabled="true"
:readonly="true"
></CodemirrorPro>
<template #footer>
<span class="dialog-footer">
Expand Down
Loading