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 get_pool_by_target(self, target): pool_names = self.get_storages() for pool_name in pool_names: stg = wvmStorage(self.host, self.login, self.passwd, self.conn, pool_name) if stg.get_target_path() == target: return self.get_storage(pool_name) return None def create_storage(self, stg_type, name, source, target): xml = f""" {name}""" if stg_type == "logical": xml += f""" {name} """ 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} {ceph_pool} """ 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_volumes_details(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 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