import string from vrtManager import util from vrtManager.connection import wvmConnect from webvirtcloud.settings import INSTANCE_VOLUME_DEFAULT_OWNER as DEFAULT_OWNER from webvirtcloud.settings import INSTANCE_VOLUME_DEFAULT_FORMAT from webvirtcloud.settings import INSTANCE_VOLUME_DEFAULT_SCSI_CONTROLLER def get_rbd_storage_data(stg): xml = stg.XMLDesc(0) ceph_user = util.get_xml_path(xml, "/pool/source/auth/@username") def get_ceph_hosts(doc): hosts = list() for host in doc.xpath("/pool/source/host"): name = host.prop("name") if name: hosts.append({'name': name, 'port': host.prop("port")}) return hosts ceph_hosts = util.get_xml_path(xml, func=get_ceph_hosts) secret_uuid = util.get_xml_path(xml, "/pool/source/auth/secret/@uuid") return ceph_user, secret_uuid, ceph_hosts class wvmCreate(wvmConnect): image_format = INSTANCE_VOLUME_DEFAULT_FORMAT def get_storages_images(self): """ Function return all images on all storages """ images = list() storages = self.get_storages(only_actives=True) for storage in storages: stg = self.get_storage(storage) try: stg.refresh(0) except: pass for img in stg.listVolumes(): if img.lower().endswith('.iso'): pass else: images.append(img) return images def get_os_type(self): """Get guest os type""" return util.get_xml_path(self.get_cap_xml(), "/capabilities/guest/os_type") def get_host_arch(self): """Get guest capabilities""" return util.get_xml_path(self.get_cap_xml(), "/capabilities/host/cpu/arch") def create_volume(self, storage, name, size, image_format=image_format, metadata=False, owner=DEFAULT_OWNER): size = int(size) * 1073741824 stg = self.get_storage(storage) storage_type = util.get_xml_path(stg.XMLDesc(0), "/pool/@type") if storage_type == 'dir': if image_format in ('qcow', 'qcow2'): name += '.' + image_format else: name += '.img' alloc = 0 else: alloc = size metadata = False xml = """ %s %s %s %s %s 0644 1.1 """ % (name, size, alloc, image_format, owner['uid'], owner['guid']) stg.createXML(xml, metadata) try: stg.refresh(0) except: pass vol = stg.storageVolLookupByName(name) return vol.path() def get_volume_type(self, path): vol = self.get_volume_by_path(path) vol_type = util.get_xml_path(vol.XMLDesc(0), "/volume/target/format/@type") if vol_type == 'unknown' or vol_type == 'iso': return 'raw' if vol_type: return vol_type else: return 'raw' def get_volume_path(self, volume, pool=None): if not pool: storages = self.get_storages(only_actives=True) else: storages = [pool] for storage in storages: stg = self.get_storage(storage) if stg.info()[0] != 0: stg.refresh(0) for img in stg.listVolumes(): if img == volume: vol = stg.storageVolLookupByName(img) return vol.path() def get_storage_by_vol_path(self, vol_path): vol = self.get_volume_by_path(vol_path) return vol.storagePoolLookupByVolume() def clone_from_template(self, clone, template, storage=None, metadata=False, owner=DEFAULT_OWNER): vol = self.get_volume_by_path(template) if not storage: stg = vol.storagePoolLookupByVolume() else: stg = self.get_storage(storage) storage_type = util.get_xml_path(stg.XMLDesc(0), "/pool/@type") format = util.get_xml_path(vol.XMLDesc(0), "/volume/target/format/@type") if storage_type == 'dir': clone += '.img' else: metadata = False xml = """ %s 0 0 %s %s 0644 1.1 """ % (clone, format, owner['uid'], owner['guid']) stg.createXMLFrom(xml, vol, metadata) clone_vol = stg.storageVolLookupByName(clone) return clone_vol.path() def _defineXML(self, xml): self.wvm.defineXML(xml) def delete_volume(self, path): vol = self.get_volume_by_path(path) vol.delete() def create_instance(self, name, memory, vcpu, vcpu_mode, uuid, arch, machine, firmware, images, networks, nwfilter, graphics, virtio, listen_addr, video="vga", console_pass="random", mac=None, cache_mode=None, io_mode=None, discard_mode=None, detect_zeroes_mode=None, qemu_ga=True): """ Create VM function """ caps = self.get_capabilities(arch) dom_caps = self.get_dom_capabilities(arch, machine) memory = int(memory) * 1024 xml = """ %s None %s %s %s""" % (dom_caps["domain"], name, uuid, memory, vcpu) if dom_caps["os_support"] == 'yes': xml += """ %s""" % (arch, machine, caps["os_type"]) xml += """ """ if firmware: if firmware["secure"] == 'yes': xml += """%s""" % (firmware["readonly"], firmware["type"], firmware["secure"], firmware["loader"]) if firmware["secure"] == 'no': xml += """%s""" % (firmware["readonly"], firmware["type"], firmware["loader"]) xml += """""" if caps["features"]: xml += """""" if 'acpi' in caps["features"]: xml += """""" if 'apic' in caps["features"]: xml += """""" if 'pae' in caps["features"]: xml += """""" if 'yes' == firmware.get("secure", 'no'): xml += """""" xml += """""" if vcpu_mode == "host-model": xml += """""" elif vcpu_mode == "host-passthrough": xml += """""" elif vcpu_mode == "": pass else: xml += """ %s""" % vcpu_mode xml += """""" xml += """ destroy restart restart """ xml += """""" vd_disk_letters = list(string.ascii_lowercase) fd_disk_letters = list(string.ascii_lowercase) hd_disk_letters = list(string.ascii_lowercase) sd_disk_letters = list(string.ascii_lowercase) add_cd = True disk_opts = '' if cache_mode is not None and cache_mode != 'default': disk_opts += "cache='%s' " % cache_mode if io_mode is not None and io_mode != 'default': disk_opts += "io='%s' " % io_mode if discard_mode is not None and discard_mode != 'default': disk_opts += "discard='%s' " % discard_mode if detect_zeroes_mode is not None and detect_zeroes_mode != 'default': disk_opts += "detect_zeroes='%s' " % detect_zeroes_mode for volume in images: stg = self.get_storage_by_vol_path(volume['path']) stg_type = util.get_xml_path(stg.XMLDesc(0), "/pool/@type") if volume['device'] == 'cdrom': add_cd = False if stg_type == 'rbd': ceph_user, secret_uuid, ceph_hosts = get_rbd_storage_data(stg) xml += """ """ % (volume['type'], disk_opts) xml += """ """ % (ceph_user, secret_uuid, volume['path']) if isinstance(ceph_hosts, list): for host in ceph_hosts: if host.get('port'): xml += """ """ % (host.get('name'), host.get('port')) else: xml += """ """ % host.get('name') xml += """""" else: xml += """""" % volume['device'] xml += """ """ % (volume['type'], disk_opts) xml += """ """ % volume['path'] if volume.get('bus') == 'virtio': xml += """""" % (vd_disk_letters.pop(0), volume.get('bus')) elif volume.get('bus') == 'ide': xml += """""" % (hd_disk_letters.pop(0), volume.get('bus')) elif volume.get('bus') == 'fdc': xml += """""" % (fd_disk_letters.pop(0), volume.get('bus')) elif volume.get('bus') == 'sata' or volume.get('bus') == 'scsi': xml += """""" % (sd_disk_letters.pop(0), volume.get('bus')) else: xml += """""" % sd_disk_letters.pop(0) xml += """""" if add_cd: xml += """ """ if 'ide' in dom_caps['disk_bus']: xml += """""" % (hd_disk_letters.pop(0), 'ide') elif 'sata' in dom_caps['disk_bus']: xml += """""" % (sd_disk_letters.pop(0), 'sata') elif 'scsi' in dom_caps['disk_bus']: xml += """""" % (sd_disk_letters.pop(0), 'scsi') else: xml += """""" % (vd_disk_letters.pop(0), 'virtio') xml += """""" if volume.get('bus') == 'scsi': xml += """""" % INSTANCE_VOLUME_DEFAULT_SCSI_CONTROLLER for net in networks.split(','): xml += """""" if mac: xml += """""" % mac xml += """""" % net if nwfilter: xml += """""" % nwfilter if virtio: xml += """""" xml += """""" if console_pass == "random": console_pass = "passwd='" + util.randomPasswd() + "'" else: if not console_pass == "": console_pass = "passwd='" + console_pass + "'" if 'usb' in dom_caps['disk_bus']: xml += """""".format('virtio' if virtio else 'usb') xml += """""".format('virtio' if virtio else 'usb') xml += """""".format('virtio' if virtio else 'usb') else: xml += """""" xml += """""" xml += """""" xml += """ """ % (graphics, console_pass, listen_addr) if qemu_ga and virtio: xml += """ """ xml += """ """ % video self._defineXML(xml)