main
youys 4 days ago
commit caddb7a08d

@ -1,12 +1,12 @@
<template>
<div class="home">
<div class="home-left">
<Block title="显卡资源">
<template #extra>
<Block title="资源使用率">
<!-- <template #extra>
<div class="all-btn" @click="sendRouteChange('/admin/vgpu/card/admin')">
全部<svg-icon icon="more" style="margin-left: 4px" />
</div>
</template>
</template> -->
<div class="card-overview">
<div v-for="item in cardGaugeConfig.slice(0, 5)" :key="item.title">
<Gauge v-bind="item" />
@ -19,11 +19,11 @@
</div>
</Block>
<Block title="资源总览">
<template #extra>
<!-- <template #extra>
<div class="all-btn" @click="sendRouteChange('/admin/vgpu/card/admin')">
全部<svg-icon icon="more" style="margin-left: 4px" />
</div>
</template>
</template> -->
<ul class="resourceOverview">
<li v-for="{ title, count, icon, to, unit } in resourceOverview" :key="title"
:style="{ cursor: to ? 'pointer' : 'default' }" @click="sendRouteChange(to)">
@ -156,7 +156,7 @@ const cardGaugeConfig = useInstantVector([
title: '磁盘 使用率',
percent: 0,
query: `(sum(node_filesystem_size_bytes{fstype!~"tmpfs|overlay"})-sum(node_filesystem_free_bytes{fstype!~"tmpfs|overlay"})) / 1024 / 1024 / 1024`,
totalQuery: `avg(node_filesystem_size_bytes{fstype!~"tmpfs|overlay"}) / 1024 / 1024 / 1024`,
totalQuery: `sum(node_filesystem_size_bytes{fstype!~"tmpfs|overlay"}) / 1024 / 1024 / 1024`,
percentQuery: ``,
total: 0,
used: 0,
@ -227,7 +227,7 @@ const resourceOverview = ref([
count: 0,
icon: 'vgpu-pool-tab',
unit: '个',
to: '/admin/vgpu/resource/admin'
to: '/admin/vgpu/poll/admin'
},
{
title: 'CPU',
@ -379,20 +379,20 @@ const nodeUsedTop = {
title: '节点资源使用率 Top5',
key: 'used',
config: [
{
tab: 'CPU',
key: 'cpu',
nameKey: 'instance',
data: [],
query: 'topk(5, avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])))',
},
{
tab: '内存',
key: 'internal',
nameKey: 'instance',
data: [],
query: 'topk(5, ((node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes))',
},
// {
// tab: 'CPU',
// key: 'cpu',
// nameKey: 'instance',
// data: [],
// query: 'topk(5, avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])))',
// },
// {
// tab: '',
// key: 'internal',
// nameKey: 'instance',
// data: [],
// query: 'topk(5, ((node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes))',
// },
{
tab: '算力',
key: 'core',
@ -415,20 +415,20 @@ const nodeTotalTop = {
title: '节点资源分配率 Top5',
key: 'used',
config: [
{
tab: 'CPU',
key: 'cpu',
nameKey: 'instance',
data: [],
query: `topk(5, sum(hami_container_vcore_allocated) by (instance) / sum(hami_core_size) by (instance) * 100)`,
},
{
tab: '内存',
key: 'internal',
nameKey: 'instance',
data: [],
query: `topk(5, sum(hami_container_vmemory_allocated) by (instance) / sum(hami_memory_size) by (instance) * 100)`,
},
// {
// tab: 'CPU',
// key: 'cpu',
// nameKey: 'instance',
// data: [],
// query: `topk(5, sum(hami_container_vcore_allocated) by (instance) / sum(hami_core_size) by (instance) * 100)`,
// },
// {
// tab: '',
// key: 'internal',
// nameKey: 'instance',
// data: [],
// query: `topk(5, sum(hami_container_vmemory_allocated) by (instance) / sum(hami_memory_size) by (instance) * 100)`,
// },
{
tab: 'vGPU',
key: 'vgpu',

@ -46,7 +46,7 @@
:title="editId ? '编辑资源池' : '创建资源池'" width="1180" :before-close="handleClose">
<el-row :wrap="false" style="align-items: center;">
<span style="flex-shrink: 0; margin-right: 14px;">资源池名称</span>
<el-input style="flex: 1;" v-model="input" size="large" />
<el-input style="flex: 1;" v-model="input" size="large" maxlength="20" />
</el-row>
<div style="margin-top: 20px; margin-bottom: 10px;">
<span>选择节点</span>
@ -70,7 +70,9 @@
</div>
</div>
</div>
<div class="wrap-center"></div>
<div class="wrap-center">
<svg-icon icon="arrow" />
</div>
<div class="wrap-right">
<div style="margin-top: 12px;"
v-for="{ nodeIp, cpuCores, gpuNum, gpuMemory, totalMemory, diskSize }, index in nodeList.filter(e => nodeSelect.includes(e.nodeIp))"
@ -304,5 +306,8 @@ onMounted(async () => {
.wrap-center {
width: 60px;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
}
</style>

@ -298,6 +298,9 @@ onMounted(async () => {
if (foundCard) {
detail.value.type = foundCard.type;
}
if (!detail.value.deviceIds?.length) {
lineConfig.value.splice(0, 2);
}
// const start = new Date();
// start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);

@ -13,7 +13,7 @@
<script setup lang="jsx">
import taskApi from '~/vgpu/api/task';
import { calculateDuration, roundToDecimal, timeParse } from '@/utils';
import { calculateDuration, roundToDecimal, timeParse, bytesToGB } from '@/utils';
import { QuestionFilled } from '@element-plus/icons-vue';
import api from '~/vgpu/api/task';
import { ElMessage, ElMessageBox, ElPopover } from 'element-plus';
@ -126,6 +126,16 @@ const columns = [
title: '所属节点',
dataIndex: 'nodeName',
},
{
title: 'CPU',
dataIndex: 'requestedCpuCores',
render: ({ requestedCpuCores }) => `${requestedCpuCores}`,
},
{
title: '内存',
dataIndex: 'requestedMemory',
render: ({ requestedMemory }) => `${bytesToGB(requestedMemory)}GiB`,
},
{
title: '分配 vGPU',
dataIndex: 'deviceIds',

@ -1,5 +1,6 @@
<template>
<el-date-picker
ref="pickerRef"
v-model="value"
:type="type"
range-separator="至"
@ -9,22 +10,32 @@
:shortcuts="type.includes('range') && shortcuts"
class="date-picker"
:disabled-date="disabledDate"
@visible-change="onVisibleChange"
v-bind="$attrs"
></el-date-picker>
/>
</template>
<script setup lang="jsx">
import { computed, defineProps, defineEmits } from 'vue';
import { ElDatePicker } from 'element-plus';
import { computed, defineProps, defineEmits, ref } from 'vue';
// Props Emits
const props = defineProps({
modelValue: {},
type: { type: String, default: 'date' },
parse: { type: Function, default: (times) => times },
});
const emits = defineEmits(['update:modelValue']);
// picker
const pickerRef = ref();
const visible = ref(false);
//
const onVisibleChange = (val) => {
visible.value = val;
};
//
const value = computed({
get() {
return props.modelValue;
@ -34,105 +45,44 @@ const value = computed({
},
});
const shortcuts = [
{
text: '前 1 小时',
//
function genShortcut(text, hoursAgo) {
return {
text,
value: () => {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 1);
return [start, end];
},
},
{
text: '前 6 小时',
value: () => {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 6);
return [start, end];
},
},
{
text: '前 12 小时',
value: () => {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 12);
return [start, end];
},
},
{
text: '前 1 天',
value: () => {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24);
return [start, end];
},
},
{
text: '前 2 天',
value: () => {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 2);
return [start, end];
},
},
{
text: '前 3 天',
value: () => {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 3);
return [start, end];
},
},
{
text: '前 1 周',
value: () => {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
const start = new Date(end.getTime() - hoursAgo * 3600 * 1000);
// time-picker
setTimeout(() => {
if (visible.value) {
pickerRef.value?.handleClose?.();
}
}, 0);
return [start, end];
},
},
// {
// text: '',
// value: () => {
// const end = new Date();
// const start = new Date();
// start.setTime(start.getTime() - 3600 * 1000 * 24 * 14);
// return [start, end];
// },
// },
// {
// text: '',
// value: () => {
// const end = new Date();
// const start = new Date();
// start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
// return [start, end];
// },
// },
// {
// text: '',
// value: () => {
// const end = new Date();
// const start = new Date();
// start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
// return [start, end];
// },
// },
};
}
//
const shortcuts = [
genShortcut('前 1 小时', 1),
genShortcut('前 6 小时', 6),
genShortcut('前 12 小时', 12),
genShortcut('前 1 天', 24),
genShortcut('前 2 天', 48),
genShortcut('前 3 天', 72),
genShortcut('前 1 周', 168),
];
//
const disabledDate = (time) => {
return time.getTime() >= Date.now();
};
</script>
<style>
<style scoped>
.date-picker {
max-width: 450px;
}

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="20px" height="7px" viewBox="0 0 20 7" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>路径</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="创建资源池" transform="translate(-711.000000, -482.000000)" fill="#9D9FA3" fill-rule="nonzero">
<g id="编组" transform="translate(711.000000, 482.000000)">
<path d="M0.714289965,6.66666667 C0.31979851,6.66666667 0,6.34215813 0,5.94185657 C0,5.54155501 0.31979851,5.21704647 0.714289965,5.21704647 L17.5615331,5.21704647 L13.6479384,1.24581195 C13.4623852,1.06369645 13.3881074,0.794158347 13.4536531,0.540793105 C13.5191988,0.287427863 13.7143679,0.0896642326 13.9641482,0.0235115646 C14.2139285,-0.0426411034 14.4794491,0.0331118821 14.6586587,0.221655283 L19.7086887,5.34678748 C19.7220221,5.36031727 19.7346412,5.37408866 19.7465461,5.38810166 C19.9756258,5.58441432 20.0594944,5.90500799 19.9565255,6.19076343 C19.8535566,6.47651887 19.5856717,6.66666667 19.285829,6.66666667 L0.714289965,6.66666667 Z" id="路径"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

Loading…
Cancel
Save