2023-07-22 23:59:49 +03:00
|
|
|
from contextlib import AbstractContextManager
|
|
|
|
|
2023-06-17 20:07:50 +03:00
|
|
|
import libvirt
|
|
|
|
|
2023-08-31 20:37:41 +03:00
|
|
|
from .vm import GuestAgent, VirtualMachine, VMNotFound
|
|
|
|
from .volume import StoragePool
|
2023-07-29 15:35:36 +03:00
|
|
|
|
|
|
|
|
|
|
|
class LibvirtSessionError(Exception):
|
2023-08-24 22:36:12 +03:00
|
|
|
"""Something went wrong while connecting to libvirtd."""
|
2023-07-22 23:59:49 +03:00
|
|
|
|
|
|
|
|
|
|
|
class LibvirtSession(AbstractContextManager):
|
2023-08-24 22:36:12 +03:00
|
|
|
|
2023-08-31 20:37:41 +03:00
|
|
|
def __init__(self, uri: str = 'qemu:///system'):
|
|
|
|
self.connection = self._connect(uri)
|
2023-07-22 23:59:49 +03:00
|
|
|
|
|
|
|
def __enter__(self):
|
|
|
|
return self
|
|
|
|
|
|
|
|
def __exit__(self, exception_type, exception_value, exception_traceback):
|
|
|
|
self.close()
|
2023-06-17 20:07:50 +03:00
|
|
|
|
2023-08-31 20:37:41 +03:00
|
|
|
def _connect(self, connection_uri: str) -> libvirt.virConnect:
|
2023-07-22 23:59:49 +03:00
|
|
|
try:
|
|
|
|
return libvirt.open(connection_uri)
|
|
|
|
except libvirt.libvirtError as err:
|
|
|
|
raise LibvirtSessionError(
|
2023-08-24 22:36:12 +03:00
|
|
|
f'Failed to open connection to the hypervisor: {err}') from err
|
2023-06-17 20:07:50 +03:00
|
|
|
|
2023-08-31 20:37:41 +03:00
|
|
|
def _get_domain(self, name: str) -> libvirt.virDomain:
|
2023-08-27 23:42:56 +03:00
|
|
|
try:
|
2023-08-31 20:37:41 +03:00
|
|
|
return self.connection.lookupByName(name)
|
2023-08-27 23:42:56 +03:00
|
|
|
except libvirt.libvirtError as err:
|
|
|
|
if err.get_error_code() == libvirt.VIR_ERR_NO_DOMAIN:
|
2023-08-31 20:37:41 +03:00
|
|
|
raise VMNotFound(name) from err
|
|
|
|
raise LibvirtSessionError(err) from err
|
2023-08-27 23:42:56 +03:00
|
|
|
|
2023-08-31 20:37:41 +03:00
|
|
|
def _list_all_domains(self) -> list[libvirt.virDomain]:
|
2023-08-27 23:42:56 +03:00
|
|
|
try:
|
2023-08-31 20:37:41 +03:00
|
|
|
return self.connection.listAllDomains()
|
2023-08-27 23:42:56 +03:00
|
|
|
except libvirt.libvirtError as err:
|
2023-08-31 20:37:41 +03:00
|
|
|
raise LibvirtSessionError(err) from err
|
|
|
|
|
|
|
|
def _get_storage_pool(self, name: str) -> libvirt.virStoragePool:
|
|
|
|
try:
|
|
|
|
return self.connection.storagePoolLookupByName(name)
|
|
|
|
except libvirt.libvirtError as err:
|
|
|
|
raise LibvirtSessionError(err) from err
|
|
|
|
|
|
|
|
def get_machine(self, name: str) -> VirtualMachine:
|
|
|
|
return VirtualMachine(self._get_domain(name))
|
|
|
|
|
|
|
|
def list_machines(self) -> list[VirtualMachine]:
|
|
|
|
return [VirtualMachine(dom) for dom in self._list_all_domains()]
|
|
|
|
|
|
|
|
def get_guest_agent(self, name: str, timeout: int | None = None,
|
|
|
|
flags: int | None = None) -> GuestAgent:
|
|
|
|
return GuestAgent(self._get_domain(name), timeout, flags)
|
|
|
|
|
|
|
|
def get_storage_pool(self, name: str) -> StoragePool:
|
|
|
|
return StoragePool(self._get_storage_pool(name))
|
|
|
|
|
|
|
|
def list_storage_pools(self):
|
|
|
|
return [StoragePool(p) for p in self.connection.listStoragePools()]
|
|
|
|
|
|
|
|
def close(self) -> None:
|
|
|
|
self.connection.close()
|