加入图形

main
陈博文 5 days ago
parent 46ce7503a9
commit 67719c5547

@ -3,18 +3,36 @@ import { useRouter } from 'vue-router';
export default function useParentAction() { export default function useParentAction() {
const router = useRouter(); const router = useRouter();
const sendRouteChange = (url) => { const sendRouteChange = (url, type) => {
if (window.parent !== window) { if (window.parent !== window) {
// 在 iframe 中,通知父窗口 // 在 iframe 中,通知父窗口
const message = { let message = {
type: 'ChangeThePath', type: 'ChangeThePath',
data: url data: url,
}; };
if (type === 'open') {
message = {
type: 'OpenThePath',
data: url,
};
}
if (type === 'back') {
message = {
type: 'BackThePath',
data: url,
};
}
window.parent.postMessage(JSON.stringify(message), '*'); window.parent.postMessage(JSON.stringify(message), '*');
} else { } else {
// 不在 iframe 中,直接使用 router 跳转 // 不在 iframe 中,直接使用 router 跳转
if (type === 'open') {
window.open(url);
} else if (type === 'back') {
router.go(-1);
} else {
router.push(url); router.push(url);
} }
}
}; };
const hasParentWindow = window.parent !== window; const hasParentWindow = window.parent !== window;

@ -33,6 +33,9 @@ import searchSchema from '~/vgpu/views/card/admin/searchSchema';
import PreviewBar from '~/vgpu/components/previewBar.vue'; import PreviewBar from '~/vgpu/components/previewBar.vue';
import { defineProps, ref, watch } from 'vue'; import { defineProps, ref, watch } from 'vue';
import { roundToDecimal } from '@/utils'; import { roundToDecimal } from '@/utils';
import useParentAction from '~/vgpu/hooks/useParentAction';
const { sendRouteChange } = useParentAction();
const props = defineProps(['hideTitle', 'filters']); const props = defineProps(['hideTitle', 'filters']);
@ -41,9 +44,7 @@ const router = useRouter();
const tableRef = ref({}); const tableRef = ref({});
const handleClick = (params) => { const handleClick = (params) => {
router.push({ sendRouteChange(`/admin/vgpu/card/admin/${params.data.name}`);
path: `/admin/vgpu/card/admin/${params.data.name}`,
});
}; };
const columns = [ const columns = [
@ -76,6 +77,11 @@ const columns = [
title: '所属节点', title: '所属节点',
dataIndex: 'nodeName', dataIndex: 'nodeName',
}, },
{
title: '所属资源池',
dataIndex: 'resourcePools',
render: ({ resourcePools }) => `${resourcePools.join('、')}`,
},
{ {
title: '显卡型号', title: '显卡型号',
dataIndex: 'type', dataIndex: 'type',
@ -114,9 +120,7 @@ const rowAction = [
{ {
title: '查看详情', title: '查看详情',
onClick: (row) => { onClick: (row) => {
router.push({ sendRouteChange(`/admin/vgpu/card/admin/${row.uuid}`);
path: `/admin/vgpu/card/admin/${row.uuid}`,
});
}, },
}, },
]; ];

@ -106,7 +106,7 @@ export const rangeConfigInit = [
}, },
{ {
name: 'CPU', name: 'CPU',
query: `sum(hami_container_cpu_allocated) / sum(hami_cpu_count) * 100`, query: `sum(hami_container_vcore_allocated) / sum(hami_core_size) * 100`,
data: [], data: [],
type: 'line', type: 'line',
areaStyle: { areaStyle: {
@ -140,7 +140,7 @@ export const rangeConfigInit = [
}, },
{ {
name: '内存', name: '内存',
query: `sum(hami_container_memory_allocated) / sum(hami_memory_capacity) * 100`, query: `sum(hami_container_vmemory_allocated) / sum(hami_memory_size) * 100`,
data: [], data: [],
type: 'line', type: 'line',
areaStyle: { areaStyle: {
@ -245,7 +245,7 @@ export const rangeConfigInit = [
}, },
{ {
name: 'CPU', name: 'CPU',
query: `sum(hami_container_cpu_allocated) / sum(hami_cpu_count) * 100`, query: `100 * (1 - sum(irate(node_cpu_seconds_total{mode="idle"}[1m])) / count(node_cpu_seconds_total{mode="idle"}))`,
data: [], data: [],
type: 'line', type: 'line',
areaStyle: { areaStyle: {
@ -279,7 +279,7 @@ export const rangeConfigInit = [
}, },
{ {
name: '内存', name: '内存',
query: `sum(hami_container_memory_allocated) / sum(hami_memory_capacity) * 100`, query: `(1 - sum(node_memory_MemAvailable_bytes) / sum(node_memory_MemTotal_bytes)) * 100`,
data: [], data: [],
type: 'line', type: 'line',
areaStyle: { areaStyle: {

@ -416,18 +416,18 @@ const nodeTotalTop = {
key: 'used', key: 'used',
config: [ config: [
{ {
tab: 'GPU', tab: 'CPU',
key: 'gpu', key: 'cpu',
nameKey: 'node', nameKey: 'instance',
data: [], data: [],
query: `topk(5, avg(hami_container_vgpu_allocated{}) by (node) / avg(hami_vgpu_count{}) by (node) * 100)`, query: `topk(5, sum(hami_container_vcore_allocated) by (instance) / sum(hami_core_size) by (instance) * 100)`,
}, },
{ {
tab: '内存', tab: '内存',
key: 'internal', key: 'internal',
nameKey: 'node', nameKey: 'instance',
data: [], data: [],
query: `topk(5, avg(hami_container_vgpu_allocated{}) by (node) / avg(hami_vgpu_count{}) by (node) * 100)`, query: `topk(5, sum(hami_container_vmemory_allocated) by (instance) / sum(hami_memory_size) by (instance) * 100)`,
}, },
{ {
tab: 'vGPU', tab: 'vGPU',

@ -250,7 +250,7 @@ const gaugeConfig = useInstantVector(
percent: 0, percent: 0,
query: ``, query: ``,
totalQuery: ``, totalQuery: ``,
percentQuery: `avg(sum(hami_container_memory_allocated{node=~"$node"}) by (instance) / sum(hami_memory_size{node=~"$node"}) by (instance) * 100)`, percentQuery: `avg(sum(hami_container_vmemory_allocated{node=~"$node"}) by (instance) / sum(hami_memory_size{node=~"$node"}) by (instance) * 100)`,
total: 0, total: 0,
used: 0, used: 0,
unit: 'GiB', unit: 'GiB',

@ -393,7 +393,7 @@ const gaugeConfig = useInstantVector(
percent: 0, percent: 0,
query: ``, query: ``,
totalQuery: ``, totalQuery: ``,
percentQuery: `avg(sum(hami_container_memory_allocated{node=~"$node"}) by (instance) / sum(hami_memory_size{node=~"$node"}) by (instance) * 100)`, percentQuery: `avg(sum(hami_container_vmemory_allocated{node=~"$node"}) by (instance) / sum(hami_memory_size{node=~"$node"}) by (instance) * 100)`,
total: 0, total: 0,
used: 0, used: 0,
unit: 'GiB', unit: 'GiB',

@ -26,7 +26,7 @@
<el-button type="text">配置</el-button> <el-button type="text">配置</el-button>
</template> </template>
<template v-else> <template v-else>
<el-button @click="dialogVisible = true; editId = poolId; nodeSelect = nodeList; input = poolName" <el-button @click="dialogVisible = true; editId = poolId; nodeSelect = nodeList.map(e=>e.nodeIp); input = poolName"
type="text">编辑</el-button> type="text">编辑</el-button>
<el-button @click="() => handleDelete(poolId)" type="text">删除</el-button> <el-button @click="() => handleDelete(poolId)" type="text">删除</el-button>
</template> </template>

@ -1,30 +1,14 @@
<template> <template>
<list-header <list-header v-if="!hideTitle" description="任务管理用于监控物理显卡的状态。它用于监控物理显卡的分配使用情况,以及查看物理显卡上运行的所有任务。" />
v-if="!hideTitle"
description="任务管理用于监控物理显卡的状态。它用于监控物理显卡的分配使用情况,以及查看物理显卡上运行的所有任务。"
/>
<Top v-if="!hideTitle" /> <Top v-if="!hideTitle" />
<table-plus <table-plus :api="taskApi.getTaskList({ filters })" :columns="columns" :rowAction="rowAction"
:api="taskApi.getTaskList({ filters })" :searchSchema="searchSchema" ref="table" :style="{ height: 'auto', ...style }" hideTag staticPage>
:columns="columns"
:rowAction="rowAction"
:searchSchema="searchSchema"
ref="table"
:style="style"
hideTag
staticPage
>
</table-plus> </table-plus>
<form-plus-drawer <form-plus-drawer v-model="state.visible" v-model:form="state.formValues" :schema="state.schema" :title="state.title"
v-model="state.visible" @ok="state.ok" />
v-model:form="state.formValues"
:schema="state.schema"
:title="state.title"
@ok="state.ok"
/>
</template> </template>
<script setup lang="jsx"> <script setup lang="jsx">
@ -39,6 +23,9 @@ import { mapValues, isNumber, pick } from 'lodash';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import searchSchema from './searchSchema'; import searchSchema from './searchSchema';
import Top from './top.vue'; import Top from './top.vue';
import useParentAction from '~/vgpu/hooks/useParentAction';
const { sendRouteChange, hasParentWindow } = useParentAction();
const props = defineProps(['hideTitle', 'filters', 'style']); const props = defineProps(['hideTitle', 'filters', 'style']);
@ -62,6 +49,11 @@ const columns = [
<text-plus text={name} to={`/admin/vgpu/task/admin/detail?name=${name}&podUid=${podUid}`} /> <text-plus text={name} to={`/admin/vgpu/task/admin/detail?name=${name}&podUid=${podUid}`} />
), ),
}, },
{
title: '类型',
dataIndex: 'nataskTypeme',
render: ({ taskType }) => taskType === 'big_model' ? '大模型' : '实训',
},
{ {
title: '任务状态', title: '任务状态',
dataIndex: 'status', dataIndex: 'status',
@ -110,6 +102,24 @@ const columns = [
); );
}, },
}, },
{
title: '实训名称',
dataIndex: 'shixunName',
},
{
title: '使用者角色',
dataIndex: 'nataskTypeme',
render: ({ taskType }) => taskType === 'big_model' ? '大模型' : '实训',
},
{
title: '用户名',
dataIndex: 'role',
},
{
title: '所属资源池',
dataIndex: 'resourcePools',
render: ({ resourcePools }) => `${resourcePools.join('、')}`,
},
{ {
title: '所属节点', title: '所属节点',
dataIndex: 'nodeName', dataIndex: 'nodeName',
@ -166,10 +176,14 @@ const rowAction = [
{ {
title: '查看详情', title: '查看详情',
onClick: (row) => { onClick: (row) => {
router.push({ sendRouteChange(`/admin/vgpu/task/admin/detail?name=${row.name}&podUid=${row.podUid}`);
path: '/admin/vgpu/task/admin/detail', },
query: pick(row, ['name', 'podUid']), },
}); {
title: '查看实训',
hidden: (row) => !hasParentWindow || row.taskType === 'big_model',
onClick: (row) => {
sendRouteChange(`/admins/running_pods?pod_name=${row.podName}`, 'open');
}, },
}, },
]; ];

@ -11,11 +11,14 @@
<script setup lang="jsx"> <script setup lang="jsx">
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import useParentAction from '~/vgpu/hooks/useParentAction';
const router = useRouter(); const router = useRouter();
const { sendRouteChange } = useParentAction();
const goBack = () => { const goBack = () => {
router.go(-1); sendRouteChange('', 'back')
}; };
</script> </script>

@ -11,6 +11,7 @@ import '@tabler/core/dist/css/tabler.min.css';
import { AppMain, Sidebar, TopBar } from './components'; import { AppMain, Sidebar, TopBar } from './components';
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import useParentAction from '~/vgpu/hooks/useParentAction'; import useParentAction from '~/vgpu/hooks/useParentAction';
import { parseUrl } from '@/utils';
export default { export default {
@ -48,9 +49,13 @@ export default {
try { try {
const messageData = JSON.parse(event.data); const messageData = JSON.parse(event.data);
if (messageData.type === "ChangeTheRoute") { if (messageData.type === "ChangeTheRoute") {
this.router.push({ // const { pathname, query } = parseUrl(messageData.data)
path: messageData.data, // console.log(messageData.data, 'messageData.data')
}); // this.router.push({
// path: pathname,
// query
// });
this.router.replace(messageData.data)
} }
} catch (e) { } } catch (e) { }
}, },

@ -571,3 +571,17 @@ export const clearEdges = (items) =>
export const bytesToGB = (bytes) => { export const bytesToGB = (bytes) => {
return Math.round(bytes / (1024 * 1024 * 1024)); return Math.round(bytes / (1024 * 1024 * 1024));
} }
export function parseUrl(url) {
const [pathname, queryString] = url.split('?');
const query = {};
if (queryString) {
queryString.split('&').forEach(pair => {
const [key, value] = pair.split('=');
query[decodeURIComponent(key)] = decodeURIComponent(value || '');
});
}
return { pathname, query };
}

Loading…
Cancel
Save