79 lines
2.3 KiB
Python
79 lines
2.3 KiB
Python
"""libvirt 连接管理 - 使用连接池模式"""
|
|
import libvirt
|
|
from contextlib import contextmanager
|
|
from app.config import settings
|
|
import logging
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class LibvirtConnection:
|
|
"""libvirt 连接管理器(只读连接保持,写操作用短连接)"""
|
|
|
|
def __init__(self):
|
|
self._conn = None
|
|
|
|
def _connect(self):
|
|
"""建立新的 libvirt 连接"""
|
|
try:
|
|
conn = libvirt.openReadOnly(settings.LIBVIRT_URI)
|
|
if conn is None:
|
|
raise ConnectionError(f"无法连接到 libvirt: {settings.LIBVIRT_URI}")
|
|
return conn
|
|
except libvirt.libvirtError as e:
|
|
logger.error(f"libvirt 连接错误: {e}")
|
|
raise
|
|
|
|
def _connect_rw(self):
|
|
"""建立可读写连接"""
|
|
try:
|
|
conn = libvirt.open(settings.LIBVIRT_URI)
|
|
if conn is None:
|
|
raise ConnectionError(f"无法连接到 libvirt (RW): {settings.LIBVIRT_URI}")
|
|
return conn
|
|
except libvirt.libvirtError as e:
|
|
logger.error(f"libvirt RW 连接错误: {e}")
|
|
raise
|
|
|
|
@property
|
|
def conn(self):
|
|
"""获取只读连接(带自动重连)"""
|
|
try:
|
|
if self._conn is None or not self._conn.isAlive():
|
|
self._conn = self._connect()
|
|
except Exception:
|
|
self._conn = self._connect()
|
|
return self._conn
|
|
|
|
@contextmanager
|
|
def get_rw(self):
|
|
"""获取读写连接(短连接,用完关闭)"""
|
|
conn = None
|
|
try:
|
|
conn = self._connect_rw()
|
|
yield conn
|
|
finally:
|
|
if conn is not None:
|
|
try:
|
|
conn.close()
|
|
except Exception:
|
|
pass
|
|
|
|
def get_host_info(self):
|
|
"""获取宿主机信息"""
|
|
c = self.conn
|
|
return {
|
|
"hostname": c.getHostname(),
|
|
"hypervisor": c.getType(),
|
|
"libvirt_version": c.getLibVersion(),
|
|
"hypervisor_version": c.getVersion(),
|
|
"cpu_model": c.getInfo()[5] if len(c.getInfo()) > 5 else "Unknown",
|
|
"cpu_cores": c.getInfo()[2],
|
|
"memory_total": c.getInfo()[1], # KB
|
|
"cpu_speed": c.getInfo()[3], # MHz
|
|
}
|
|
|
|
|
|
# 全局单例
|
|
libvirt_conn = LibvirtConnection()
|