import contextlib
from vrtManager import util
from vrtManager.connection import wvmConnect
class wvmStorages(wvmConnect):
def get_storages_info(self):
get_storages = self.get_storages()
storages = []
for pool in get_storages:
stg = self.get_storage(pool)
stg_status = stg.isActive()
stg_type = util.get_xml_path(stg.XMLDesc(0), "/pool/@type")
stg_vol = len(stg.listVolumes()) if stg_status else None
stg_size = stg.info()[1]
storages.append(
{"name": pool, "status": stg_status, "type": stg_type, "volumes": stg_vol, "size": stg_size}
)
return storages
def define_storage(self, xml, flag):
self.wvm.storagePoolDefineXML(xml, flag)
def create_storage(self, stg_type, name, source, target):
xml = f"""
{name}"""
if stg_type == "logical":
xml += f""""""
if stg_type == "logical":
target = f"/dev/{name}"
xml += f"""
{target}
"""
self.define_storage(xml, 0)
stg = self.get_storage(name)
if stg_type == "logical":
stg.build(0)
stg.create(0)
stg.setAutostart(1)
return stg
def create_storage_ceph(self, stg_type, name, ceph_pool, ceph_host, ceph_user, secret):
xml = f"""
{name}
"""
self.define_storage(xml, 0)
stg = self.get_storage(name)
stg.create(0)
stg.setAutostart(1)
def create_storage_netfs(self, stg_type, name, netfs_host, source, source_format, target):
xml = f"""
{name}
{target}
"""
self.define_storage(xml, 0)
stg = self.get_storage(name)
stg.create(0)
stg.setAutostart(1)
return stg
class wvmStorage(wvmConnect):
def __init__(self, host, login, passwd, conn, pool):
wvmConnect.__init__(self, host, login, passwd, conn)
self.pool = self.get_storage(pool)
def get_name(self):
return self.pool.name()
def get_status(self):
status = ["Not running", "Initializing pool, not available", "Running normally", "Running degraded"]
try:
return status[self.pool.info()[0]]
except ValueError:
return "Unknown"
def get_size(self):
return [self.pool.info()[1], self.pool.info()[3]]
def _XMLDesc(self, flags):
return self.pool.XMLDesc(flags)
def _createXML(self, xml, flags):
self.pool.createXML(xml, flags)
def _createXMLFrom(self, xml, vol, flags):
self.pool.createXMLFrom(xml, vol, flags)
def _define(self, xml):
return self.wvm.storagePoolDefineXML(xml, 0)
def is_active(self):
return self.pool.isActive()
def get_uuid(self):
return self.pool.UUIDString()
def start(self):
return self.pool.create(0)
def stop(self):
return self.pool.destroy()
def delete(self):
self.pool.undefine()
def get_autostart(self):
return self.pool.autostart()
def set_autostart(self, value):
self.pool.setAutostart(value)
def get_type(self):
return util.get_xml_path(self._XMLDesc(0), "/pool/@type")
def get_target_path(self):
return util.get_xml_path(self._XMLDesc(0), "/pool/target/path")
def get_source_name(self):
return util.get_xml_path(self._XMLDesc(0), "/pool/source/name")
def get_allocation(self):
return int(util.get_xml_path(self._XMLDesc(0), "/pool/allocation"))
def get_available(self):
return int(util.get_xml_path(self._XMLDesc(0), "/pool/available"))
def get_capacity(self):
return int(util.get_xml_path(self._XMLDesc(0), "/pool/capacity"))
def get_rbd_source(self):
def hosts(doc):
hosts_array = []
for host in doc.xpath("/pool/source/host"):
name = host.get('name')
if name:
port = host.get('port')
if port:
hosts_array.append({"hostname": name, "hostport": port})
else:
hosts_array.append({"hostname": name})
name = doc.get('name')
auth = doc.xpath("/pool/source/auth")
auth_type = auth[0].get("type")
auth_user = auth[0].get("username")
auth_uuid = auth[0].xpath("secret/@uuid")[0]
return({
"name": name,
"auth_type": auth_type,
"auth_user": auth_user,
"auth_uuid": auth_uuid,
"hosts": hosts_array
})
return util.get_xml_path(self._XMLDesc(0), func=hosts)
def get_pretty_allocation(self):
return util.pretty_bytes(self.get_allocation())
def get_pretty_available(self):
return util.pretty_bytes(self.get_available())
def get_pretty_capacity(self):
return util.pretty_bytes(self.get_capacity())
def get_volumes(self):
return self.pool.listVolumes()
def get_volume(self, name):
return self.pool.storageVolLookupByName(name)
def get_volume_size(self, name):
vol = self.get_volume(name)
return vol.info()[1]
def get_volume_allocation(self, name):
vol = self.get_volume(name)
return vol.info()[2]
def _vol_XMLDesc(self, name):
vol = self.get_volume(name)
return vol.XMLDesc(0)
def del_volume(self, name):
vol = self.pool.storageVolLookupByName(name)
vol.delete(0)
def get_volume_format_type(self, name):
vol_xml = self._vol_XMLDesc(name)
return util.get_xml_path(vol_xml, "/volume/target/format/@type")
def get_volume_type(self, name):
vol_xml = self._vol_XMLDesc(name)
return util.get_xml_path(vol_xml, "/volume/@type")
def refresh(self):
return self.pool.refresh(0)
def get_volume_details(self, volname):
with contextlib.suppress(Exception):
self.refresh()
vols = self.get_volumes()
return [{"name": volname,
"size": self.get_volume_size(volname),
"allocation": self.get_volume_allocation(volname),
"type": self.get_volume_format_type(volname)} for volname in vols]
def get_volume_details(self, volname):
with contextlib.suppress(Exception):
self.refresh()
return {
"name": volname,
"size": self.get_volume_size(volname),
"allocation": self.get_volume_allocation(volname),
"type": self.get_volume_format_type(volname),
}
def update_volumes(self):
with contextlib.suppress(Exception):
self.refresh()
vols = self.get_volumes()
return [{"name": volname, "size": self.get_volume_size(volname),
"allocation": self.get_volume_allocation(volname),
"type": self.get_volume_format_type(volname)} for volname in vols]
def create_volume(self, name, size, vol_fmt="qcow2", metadata=False, disk_owner_uid=0, disk_owner_gid=0):
size = int(size) * 1073741824
storage_type = self.get_type()
alloc = size
if vol_fmt == "unknown":
vol_fmt = "raw"
if storage_type == "dir":
name += f".{vol_fmt}" if vol_fmt in ("qcow", "qcow2") else ".img"
alloc = 0
xml = f"""
{name}
{size}
{alloc}
{disk_owner_uid}
{disk_owner_gid}
0644
"""
if vol_fmt == "qcow2":
xml += """
1.1
"""
xml += """
"""
self._createXML(xml, metadata)
return name
def clone_volume(
self,
name,
target_file,
vol_fmt=None,
metadata=False,
mode="0644",
file_suffix="img",
disk_owner_uid=0,
disk_owner_gid=0,
):
vol = self.get_volume(name)
if not vol_fmt:
vol_fmt = self.get_volume_format_type(name)
storage_type = self.get_type()
if storage_type == "dir":
if vol_fmt in ["qcow", "qcow2"]:
target_file += f".{vol_fmt}"
else:
suffix = f".{file_suffix}"
target_file += suffix if len(suffix) > 1 else ""
xml = f"""
{target_file}
0
0
{disk_owner_uid}
{disk_owner_gid}
{mode}
"""
if vol_fmt == "qcow2":
xml += """
1.1
"""
xml += """
"""
self._createXMLFrom(xml, vol, metadata)
return target_file