feat: 多主机纳管、用户认证、noVNC控制台、深色主题
主要功能: - 多主机管理: 支持TCP/SSH方式纳管远程KVM主机 - 用户认证: JWT token认证, 默认admin/admin123 - noVNC控制台: 前端集成noVNC, WebSocket代理VNC连接 - 深色主题: 全局Element Plus深色主题覆盖 - 虚拟机操作: 克隆、迁移、XML编辑、快照管理 - 资源监控: CPU/内存/磁盘IO/网络流量实时监控 Bug修复: - libvirt getInfo()内存单位修正(MiB非KiB) - 远程主机VNC 0.0.0.0监听地址连接策略修复 - Dashboard定时器内存泄漏修复 - bcrypt版本兼容性修复
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
"""存储池管理路由"""
|
||||
from fastapi import APIRouter, HTTPException
|
||||
from fastapi import APIRouter, HTTPException, Query
|
||||
from pydantic import BaseModel, Field
|
||||
from typing import Optional
|
||||
from lxml import etree
|
||||
import os
|
||||
|
||||
from app.libvirt_conn import libvirt_conn
|
||||
from app.libvirt_conn import conn_pool
|
||||
import libvirt
|
||||
|
||||
router = APIRouter()
|
||||
@@ -24,9 +24,9 @@ class VolCreate(BaseModel):
|
||||
|
||||
|
||||
@router.get("/pools")
|
||||
async def list_pools():
|
||||
async def list_pools(host_id: str = Query("local")):
|
||||
"""列出所有存储池"""
|
||||
conn = libvirt_conn.conn
|
||||
conn = conn_pool.get_conn(host_id)
|
||||
pools = conn.listAllStoragePools(0)
|
||||
result = []
|
||||
for pool in pools:
|
||||
@@ -47,9 +47,9 @@ async def list_pools():
|
||||
|
||||
|
||||
@router.get("/pool/{name}")
|
||||
async def get_pool(name: str):
|
||||
async def get_pool(name: str, host_id: str = Query("local")):
|
||||
"""获取存储池详情"""
|
||||
conn = libvirt_conn.conn
|
||||
conn = conn_pool.get_conn(host_id)
|
||||
try:
|
||||
pool = conn.storagePoolLookupByName(name)
|
||||
except libvirt.libvirtError:
|
||||
@@ -58,7 +58,6 @@ async def get_pool(name: str):
|
||||
info = pool.info()
|
||||
xml = etree.fromstring(pool.XMLDesc(0).encode())
|
||||
|
||||
# 获取卷列表
|
||||
volumes = []
|
||||
try:
|
||||
for vol_name in pool.listVolumes():
|
||||
@@ -89,9 +88,9 @@ async def get_pool(name: str):
|
||||
|
||||
|
||||
@router.post("/pool/create")
|
||||
async def create_pool(pool: PoolCreate):
|
||||
async def create_pool(pool: PoolCreate, host_id: str = Query("local")):
|
||||
"""创建存储池"""
|
||||
with libvirt_conn.get_rw() as rw_conn:
|
||||
with conn_pool.get_rw(host_id) as rw_conn:
|
||||
xml = f"""<pool type='{pool.type}'>
|
||||
<name>{pool.name}</name>
|
||||
<target>
|
||||
@@ -109,9 +108,9 @@ async def create_pool(pool: PoolCreate):
|
||||
|
||||
|
||||
@router.delete("/pool/{name}")
|
||||
async def delete_pool(name: str):
|
||||
async def delete_pool(name: str, host_id: str = Query("local")):
|
||||
"""删除存储池"""
|
||||
with libvirt_conn.get_rw() as rw_conn:
|
||||
with conn_pool.get_rw(host_id) as rw_conn:
|
||||
try:
|
||||
pool = rw_conn.storagePoolLookupByName(name)
|
||||
except libvirt.libvirtError:
|
||||
@@ -125,9 +124,9 @@ async def delete_pool(name: str):
|
||||
|
||||
|
||||
@router.post("/pool/{name}/volume")
|
||||
async def create_volume(name: str, vol: VolCreate):
|
||||
async def create_volume(name: str, vol: VolCreate, host_id: str = Query("local")):
|
||||
"""在存储池中创建卷"""
|
||||
with libvirt_conn.get_rw() as rw_conn:
|
||||
with conn_pool.get_rw(host_id) as rw_conn:
|
||||
try:
|
||||
pool = rw_conn.storagePoolLookupByName(name)
|
||||
except libvirt.libvirtError:
|
||||
@@ -149,9 +148,9 @@ async def create_volume(name: str, vol: VolCreate):
|
||||
|
||||
|
||||
@router.delete("/pool/{pool_name}/volume/{vol_name}")
|
||||
async def delete_volume(pool_name: str, vol_name: str):
|
||||
async def delete_volume(pool_name: str, vol_name: str, host_id: str = Query("local")):
|
||||
"""删除卷"""
|
||||
with libvirt_conn.get_rw() as rw_conn:
|
||||
with conn_pool.get_rw(host_id) as rw_conn:
|
||||
try:
|
||||
pool = rw_conn.storagePoolLookupByName(pool_name)
|
||||
vol = pool.storageVolLookupByName(vol_name)
|
||||
@@ -162,7 +161,7 @@ async def delete_volume(pool_name: str, vol_name: str):
|
||||
|
||||
|
||||
@router.get("/isos")
|
||||
async def list_isos():
|
||||
async def list_isos(host_id: str = Query("local")):
|
||||
"""列出可用的ISO镜像"""
|
||||
iso_dirs = ["/var/lib/libvirt/iso", "/isos", "/mnt/isos"]
|
||||
isos = []
|
||||
|
||||
Reference in New Issue
Block a user