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,10 +1,10 @@
|
||||
"""快照管理路由"""
|
||||
from fastapi import APIRouter, HTTPException
|
||||
from fastapi import APIRouter, HTTPException, Query
|
||||
from pydantic import BaseModel, Field
|
||||
from typing import Optional
|
||||
from lxml import etree
|
||||
|
||||
from app.libvirt_conn import libvirt_conn
|
||||
from app.libvirt_conn import conn_pool
|
||||
import libvirt
|
||||
|
||||
router = APIRouter()
|
||||
@@ -16,9 +16,9 @@ class SnapshotCreate(BaseModel):
|
||||
|
||||
|
||||
@router.get("/list/{vm_name}")
|
||||
async def list_snapshots(vm_name: str):
|
||||
async def list_snapshots(vm_name: str, host_id: str = Query("local")):
|
||||
"""列出虚拟机的所有快照"""
|
||||
conn = libvirt_conn.conn
|
||||
conn = conn_pool.get_conn(host_id)
|
||||
try:
|
||||
dom = conn.lookupByName(vm_name)
|
||||
except libvirt.libvirtError:
|
||||
@@ -40,15 +40,15 @@ async def list_snapshots(vm_name: str):
|
||||
"is_current": snap.isCurrent() == 1,
|
||||
})
|
||||
except libvirt.libvirtError:
|
||||
pass # 没有快照
|
||||
pass
|
||||
|
||||
return {"vm": vm_name, "snapshots": snapshots, "total": len(snapshots)}
|
||||
|
||||
|
||||
@router.post("/create/{vm_name}")
|
||||
async def create_snapshot(vm_name: str, snap: SnapshotCreate):
|
||||
async def create_snapshot(vm_name: str, snap: SnapshotCreate, host_id: str = Query("local")):
|
||||
"""创建快照"""
|
||||
with libvirt_conn.get_rw() as rw_conn:
|
||||
with conn_pool.get_rw(host_id) as rw_conn:
|
||||
try:
|
||||
dom = rw_conn.lookupByName(vm_name)
|
||||
except libvirt.libvirtError:
|
||||
@@ -68,9 +68,9 @@ async def create_snapshot(vm_name: str, snap: SnapshotCreate):
|
||||
|
||||
|
||||
@router.post("/revert/{vm_name}/{snap_name}")
|
||||
async def revert_snapshot(vm_name: str, snap_name: str):
|
||||
async def revert_snapshot(vm_name: str, snap_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:
|
||||
dom = rw_conn.lookupByName(vm_name)
|
||||
snap = dom.snapshotLookupByName(snap_name)
|
||||
@@ -85,9 +85,9 @@ async def revert_snapshot(vm_name: str, snap_name: str):
|
||||
|
||||
|
||||
@router.delete("/delete/{vm_name}/{snap_name}")
|
||||
async def delete_snapshot(vm_name: str, snap_name: str):
|
||||
async def delete_snapshot(vm_name: str, snap_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:
|
||||
dom = rw_conn.lookupByName(vm_name)
|
||||
snap = dom.snapshotLookupByName(snap_name)
|
||||
@@ -102,9 +102,9 @@ async def delete_snapshot(vm_name: str, snap_name: str):
|
||||
|
||||
|
||||
@router.get("/detail/{vm_name}/{snap_name}")
|
||||
async def get_snapshot_detail(vm_name: str, snap_name: str):
|
||||
async def get_snapshot_detail(vm_name: str, snap_name: str, host_id: str = Query("local")):
|
||||
"""获取快照详情"""
|
||||
conn = libvirt_conn.conn
|
||||
conn = conn_pool.get_conn(host_id)
|
||||
try:
|
||||
dom = conn.lookupByName(vm_name)
|
||||
snap = dom.snapshotLookupByName(snap_name)
|
||||
|
||||
Reference in New Issue
Block a user