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
16 changes: 10 additions & 6 deletions agent/app/dto/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,19 +209,23 @@ type NetworkCreate struct {
}

type Volume struct {
Name string `json:"name"`
Labels []string `json:"labels"`
Driver string `json:"driver"`
Mountpoint string `json:"mountpoint"`
CreatedAt time.Time `json:"createdAt"`
Name string `json:"name"`
Labels []VolumeOption `json:"labels"`
Driver string `json:"driver"`
Mountpoint string `json:"mountpoint"`
CreatedAt time.Time `json:"createdAt"`
Options []VolumeOption `json:"options"`
}
type VolumeCreate struct {
Name string `json:"name" validate:"required"`
Driver string `json:"driver" validate:"required"`
Options []string `json:"options"`
Labels []string `json:"labels"`
}

type VolumeOption struct {
Key string `json:"key"`
Value string `json:"value"`
}
type BatchDelete struct {
TaskID string `json:"taskID"`
Force bool `json:"force"`
Expand Down
44 changes: 30 additions & 14 deletions agent/app/service/container_volume.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"sort"
"strings"
"time"
"unicode"

"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/1Panel-dev/1Panel/agent/buserr"
Expand Down Expand Up @@ -53,25 +54,27 @@ func (u *ContainerService) PageVolume(req dto.SearchWithPage) (int64, interface{

nyc, _ := time.LoadLocation(common.LoadTimeZoneByCmd())
for _, item := range records {
tag := make([]string, 0)
for _, val := range item.Labels {
tag = append(tag, val)
var volume dto.Volume
volume.Driver = item.Driver
volume.Mountpoint = item.Mountpoint
volume.Name = simplifyVolumeName(item.Name)
for key, val := range item.Labels {
volume.Labels = append(volume.Labels, dto.VolumeOption{Key: key, Value: val})
}
var createTime time.Time
for key, val := range item.Options {
volume.Options = append(volume.Options, dto.VolumeOption{Key: key, Value: val})
}
sort.Slice(volume.Options, func(i, j int) bool {
return volume.Options[i].Key < volume.Options[j].Key
})
if strings.Contains(item.CreatedAt, "Z") {
createTime, _ = time.ParseInLocation("2006-01-02T15:04:05Z", item.CreatedAt, nyc)
volume.CreatedAt, _ = time.ParseInLocation("2006-01-02T15:04:05Z", item.CreatedAt, nyc)
} else if strings.Contains(item.CreatedAt, "+") {
createTime, _ = time.ParseInLocation("2006-01-02T15:04:05+08:00", item.CreatedAt, nyc)
volume.CreatedAt, _ = time.ParseInLocation("2006-01-02T15:04:05+08:00", item.CreatedAt, nyc)
} else {
createTime, _ = time.ParseInLocation("2006-01-02T15:04:05", item.CreatedAt, nyc)
volume.CreatedAt, _ = time.ParseInLocation("2006-01-02T15:04:05", item.CreatedAt, nyc)
}
data = append(data, dto.Volume{
CreatedAt: createTime,
Name: item.Name,
Driver: item.Driver,
Mountpoint: item.Mountpoint,
Labels: tag,
})
data = append(data, volume)
}

return int64(total), data, nil
Expand Down Expand Up @@ -140,3 +143,16 @@ func (u *ContainerService) CreateVolume(req dto.VolumeCreate) error {
}
return nil
}

func simplifyVolumeName(name string) string {
if len(name) != 64 {
return name
}

for _, char := range name {
if !unicode.Is(unicode.ASCII_Hex_Digit, char) {
return name
}
}
return name[:12]
}
59 changes: 51 additions & 8 deletions frontend/src/views/container/volume/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -47,23 +47,54 @@
</el-text>
</template>
</el-table-column>
<el-table-column :label="$t('container.volumeDir')" min-width="100">
<el-table-column label="Options" min-width="160">
<template #default="{ row }">
<el-tooltip :content="row.mountpoint">
<el-button type="primary" link @click="routerToFileWithPath(row.mountpoint)">
<el-icon>
<FolderOpened />
</el-icon>
<div v-for="(item, index) in row.options" :key="index">
<div v-if="row.expand || (!row.expand && index < 3)">
<el-button
v-if="item.key === 'device'"
@click="jumpTo(item.value)"
class="mt-0.5"
icon="Position"
plain
size="small"
>
{{ item.key + ': ' + item.value }}
</el-button>
<el-button v-else class="mt-0.5" plain size="small">
{{ item.key + ': ' + item.value }}
</el-button>
</div>
</div>
<div v-if="!row.expand && row.options.length > 3">
<el-button type="primary" link @click="row.expand = true">
{{ $t('commons.button.expand') }}...
</el-button>
</el-tooltip>
</div>
<div v-if="row.expand && row.options.length > 3">
<el-button type="primary" link @click="row.expand = false">
{{ $t('commons.button.collapse') }}
</el-button>
</div>
</template>
</el-table-column>
<el-table-column
:label="$t('container.mountpoint')"
show-overflow-tooltip
min-width="120"
prop="mountpoint"
/>
>
<template #default="{ row }">
<el-tooltip :content="row.mountpoint">
<el-button
type="primary"
icon="FolderOpened"
link
@click="routerToFileWithPath(row.mountpoint)"
/>
</el-tooltip>
</template>
</el-table-column>
<el-table-column
:label="$t('container.driver')"
show-overflow-tooltip
Expand Down Expand Up @@ -102,6 +133,8 @@ import i18n from '@/lang';
import { ElMessageBox } from 'element-plus';
import { GlobalStore } from '@/store';
import { routerToFileWithPath } from '@/utils/router';
import { checkFile } from '@/api/modules/files';
import { MsgError } from '@/utils/message';
const globalStore = GlobalStore();

const taskLogRef = ref();
Expand Down Expand Up @@ -193,6 +226,16 @@ const openTaskLog = (taskID: string) => {
taskLogRef.value.openWithTaskID(taskID);
};

const jumpTo = async (path: any) => {
await checkFile(path, false).then((res) => {
if (res.data) {
routerToFileWithPath(path);
} else {
MsgError(i18n.global.t('file.noSuchFile'));
}
});
};

const batchDelete = async (row: Container.VolumeInfo | null) => {
let names = [];
if (row) {
Expand Down
Loading