102 lines
5.3 KiB
Plaintext
102 lines
5.3 KiB
Plaintext
def card(title, value, subtitle, bgcolor, color):
|
|
return {
|
|
'widgettype': 'VBox',
|
|
'options': {'bgcolor': bgcolor, 'padding': '16px', 'width': '25%', 'border': '1px solid ' + color, 'borderRadius': '8px'},
|
|
'subwidgets': [
|
|
{'widgettype': 'Text', 'options': {'text': title, 'cfontsize': 0.7, 'color': '#64748b'}},
|
|
{'widgettype': 'Text', 'options': {'text': value, 'cfontsize': 2, 'fontWeight': 'bold', 'color': color}},
|
|
{'widgettype': 'Text', 'options': {'text': subtitle, 'cfontsize': 0.7, 'color': '#94a3b8'}}
|
|
]
|
|
}
|
|
|
|
pool_cards = []
|
|
cluster_cards = []
|
|
storage_txt = ''
|
|
image_txt = ''
|
|
|
|
# 算力池统计
|
|
try:
|
|
async with DBPools().sqlorContext(get_module_dbname('pcpool')) as sor:
|
|
pools = await sor.R('compute_pool', {})
|
|
total_pools = len(pools or [])
|
|
active = sum(1 for p in (pools or []) if str(getattr(p,'status','')) == '1')
|
|
total_cpu = 0; total_gpu = 0; total_mem = 0
|
|
alloc_cpu = 0; alloc_gpu = 0; alloc_mem = 0
|
|
for p in (pools or []):
|
|
nodes = await sor.R('compute_node', {'pool_id': p.id})
|
|
for n in (nodes or []):
|
|
cpu = int(getattr(n,'cpu_cores',0) or 0)
|
|
gpu = int(getattr(n,'gpu_count',0) or 0)
|
|
mem = int(getattr(n,'memory_gb',0) or 0)
|
|
total_cpu += cpu; total_gpu += gpu; total_mem += mem
|
|
if getattr(n,'status','') == 'allocated':
|
|
alloc_cpu += cpu; alloc_gpu += gpu; alloc_mem += mem
|
|
pool_cards = [
|
|
card('算力池', str(total_pools) + ' 个', str(active) + ' 运行中', '#eff6ff', '#2563eb'),
|
|
card('CPU', str(total_cpu) + ' 核', '已分配 ' + str(alloc_cpu) + ' 核', '#f5f3ff', '#7c3aed'),
|
|
card('GPU', str(total_gpu) + ' 个', '已分配 ' + str(alloc_gpu) + ' 个', '#ecfdf5', '#059669'),
|
|
card('内存', str(total_mem) + ' GB', '已分配 ' + str(alloc_mem) + ' GB', '#fff7ed', '#ea580c')
|
|
]
|
|
except:
|
|
pool_cards = [card('算力池', '0', '加载失败', '#f1f5f9', '#94a3b8') for _ in range(4)]
|
|
|
|
# 集群统计
|
|
try:
|
|
async with DBPools().sqlorContext(get_module_dbname('pcc')) as sor:
|
|
clusters = await sor.R('cluster', {})
|
|
total = len(clusters or [])
|
|
running = sum(1 for c in (clusters or []) if getattr(c,'status','') == 'running')
|
|
deploying = sum(1 for c in (clusters or []) if getattr(c,'status','') == 'deploying')
|
|
stopped = sum(1 for c in (clusters or []) if getattr(c,'status','') == 'stopped')
|
|
total_nodes = 0; total_cpu = 0; total_gpu = 0; total_mem = 0
|
|
for c in (clusters or []):
|
|
nodes = await sor.R('cluster_node', {'cluster_id': c.id})
|
|
total_nodes += len(nodes or [])
|
|
for n in (nodes or []):
|
|
total_cpu += int(getattr(n,'cpu_cores',0) or 0)
|
|
total_gpu += int(getattr(n,'gpu_count',0) or 0)
|
|
total_mem += int(getattr(n,'memory_gb',0) or 0)
|
|
cluster_cards = [
|
|
card('集群', str(total) + ' 个', str(running) + '运行/' + str(deploying) + '部署/' + str(stopped) + '停', '#eff6ff', '#2563eb'),
|
|
card('节点', str(total_nodes) + ' 个', '已加入集群', '#f5f3ff', '#7c3aed'),
|
|
card('CPU', str(total_cpu) + ' 核', '集群总核数', '#ecfdf5', '#059669'),
|
|
card('GPU/内存', str(total_gpu) + ' GPU', str(total_mem) + ' GB 内存', '#fff7ed', '#ea580c')
|
|
]
|
|
except:
|
|
cluster_cards = [card('集群', '0', '加载失败', '#f1f5f9', '#94a3b8') for _ in range(4)]
|
|
|
|
# 存储统计
|
|
try:
|
|
async with DBPools().sqlorContext(get_module_dbname('storage_mgr')) as sor:
|
|
servers = await sor.R('storage_server', {})
|
|
exports = await sor.R('storage_export', {})
|
|
storage_txt = '存储: ' + str(len(servers or [])) + ' 服务器, ' + str(len(exports or [])) + ' 导出'
|
|
except:
|
|
storage_txt = '存储: 加载失败'
|
|
|
|
# 镜像统计
|
|
try:
|
|
async with DBPools().sqlorContext(get_module_dbname('image_mgr')) as sor:
|
|
registries = await sor.R('image_registry', {})
|
|
images = await sor.R('container_image', {})
|
|
image_txt = '镜像: ' + str(len(registries or [])) + ' 仓库, ' + str(len(images or [])) + ' 镜像'
|
|
except:
|
|
image_txt = '镜像: 加载失败'
|
|
|
|
return {
|
|
'widgettype': 'VBox',
|
|
'options': {'padding': '24px', 'spacing': '24px', 'bgcolor': '#f8fafc'},
|
|
'subwidgets': [
|
|
{'widgettype': 'Text', 'options': {'text': '资源概览', 'cfontsize': 1.3, 'fontWeight': 'bold', 'color': '#1e293b'}},
|
|
{'widgettype': 'Text', 'options': {'text': '算力池', 'cfontsize': 0.9, 'fontWeight': 'bold', 'color': '#64748b'}},
|
|
{'widgettype': 'HBox', 'options': {'gap': '16px'}, 'subwidgets': pool_cards},
|
|
{'widgettype': 'Text', 'options': {'text': '集群', 'cfontsize': 0.9, 'fontWeight': 'bold', 'color': '#64748b'}},
|
|
{'widgettype': 'HBox', 'options': {'gap': '16px'}, 'subwidgets': cluster_cards},
|
|
{'widgettype': 'Text', 'options': {'text': '存储与镜像', 'cfontsize': 0.9, 'fontWeight': 'bold', 'color': '#64748b'}},
|
|
{'widgettype': 'HBox', 'options': {'gap': '16px'}, 'subwidgets': [
|
|
{'widgettype': 'Text', 'options': {'text': storage_txt, 'cfontsize': 0.9, 'color': '#1e293b'}},
|
|
{'widgettype': 'Text', 'options': {'text': image_txt, 'cfontsize': 0.9, 'color': '#1e293b'}}
|
|
]}
|
|
]
|
|
}
|