def clone_from_template(self, clone, template, metadata=False): vol = self.get_volume_by_path(template) stg = vol.storagePoolLookupByVolume() 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 = """ <volume> <name>%s</name> <capacity>0</capacity> <allocation>0</allocation> <target> <format type='%s'/> <permissions> <owner>107</owner> <group>107</group> <mode>0644</mode> <label>virt_image_t</label> </permissions> <compat>1.1</compat> <features> <lazy_refcounts/> </features> </target> </volume>""" % (clone, format) stg.createXMLFrom(xml, vol, metadata) clone_vol = stg.storageVolLookupByName(clone) return clone_vol.path()
def get_console_listen_addr(self): listen_addr = util.get_xml_path(self._XMLDesc(0), "/domain/devices/graphics/@listen") if listen_addr is None: listen_addr = util.get_xml_path(self._XMLDesc(0), "/domain/devices/graphics/listen/@address") if listen_addr is None: return "127.0.0.1" return listen_addr
def get_ipv4_dhcp_range(self): xml = self._XMLDesc(0) dhcpstart = util.get_xml_path(xml, "/network/ip/dhcp/range[1]/@start") dhcpend = util.get_xml_path(xml, "/network/ip/dhcp/range[1]/@end") if not dhcpstart or not dhcpend: return None return [IP(dhcpstart), IP(dhcpend)]
def get_ipv4(self): xml = self._XMLDesc() int_ipv4_ip = util.get_xml_path(xml, "/interface/protocol/ip/@address") int_ipv4_mask = util.get_xml_path(xml, "/interface/protocol/ip/@prefix") if not int_ipv4_ip or not int_ipv4_mask: return None else: return int_ipv4_ip + '/' + int_ipv4_mask
def get_net_device(self): netdevice = [] for dev in self.wvm.listAllDevices(0): xml = dev.XMLDesc(0) dev_type = util.get_xml_path(xml, '/device/capability/@type') if dev_type == 'net': netdevice.append(util.get_xml_path(xml, '/device/capability/interface')) return netdevice
def get_instance_vcpu(self, name): inst = self.get_instance(name) cur_vcpu = util.get_xml_path(inst.XMLDesc(0), "/domain/vcpu/@current") if cur_vcpu: vcpu = cur_vcpu else: vcpu = util.get_xml_path(inst.XMLDesc(0), "/domain/vcpu") return vcpu
def graphics_listen(self, name): inst = self.get_instance(name) listen_addr = util.get_xml_path(inst.XMLDesc(0), "/domain/devices/graphics/@listen") if listen_addr is None: listen_addr = util.get_xml_path(inst.XMLDesc(0), "/domain/devices/graphics/listen/@address") if listen_addr is None: return "None" return listen_addr
def get_host_instances(self): vname = {} memory = self.wvm.getInfo()[1] * 1048576 for name in self.get_instances(): dom = self.get_instance(name) mem = util.get_xml_path(dom.XMLDesc(0), "/domain/memory") mem = int(mem) * 1024 mem_usage = (mem * 100) / memory vcpu = util.get_xml_path(dom.XMLDesc(0), "/domain/vcpu") vname[dom.name()] = (dom.info()[0], vcpu, mem, mem_usage) return vname
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(ctx): hosts = [] for host in ctx.xpathEval("/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
def get_media_device(self): def disks(ctx): result = [] dev = None volume = None storage = None src_fl = None for media in ctx.xpathEval('/domain/devices/disk'): device = media.xpathEval('@device')[0].content if device == 'cdrom': try: dev = media.xpathEval('target/@dev')[0].content try: src_fl = media.xpathEval('source/@file')[0].content vol = self.get_volume_by_path(src_fl) volume = vol.name() stg = vol.storagePoolLookupByVolume() storage = stg.name() except: src_fl = None volume = src_fl except: pass finally: result.append({'dev': dev, 'image': volume, 'storage': storage, 'path': src_fl}) return result return util.get_xml_path(self._XMLDesc(0), func=disks)
def get_media_devices(self): def disks(doc): result = [] dev = volume = storage = None src_file = None for media in doc.xpath('/domain/devices/disk'): device = media.xpath('@device')[0] if device == 'cdrom': try: dev = media.xpath('target/@dev')[0] bus = media.xpath('target/@bus')[0] try: src_file = media.xpath('source/@file')[0] vol = self.get_volume_by_path(src_file) volume = vol.name() stg = vol.storagePoolLookupByVolume() storage = stg.name() except: src_file = None volume = src_file except: pass finally: result.append({'dev': dev, 'image': volume, 'storage': storage, 'path': src_file, 'bus': bus}) return result return util.get_xml_path(self._XMLDesc(0), func=disks)
def get_iface_info(self, name): iface = self.get_iface(name) xml = iface.XMLDesc(0) mac = iface.MACString() itype = util.get_xml_path(xml, "/interface/@type") state = iface.isActive() return {'name': name, 'type': itype, 'state': state, 'mac': mac}
def get_net_device(self): def get_mac_ipaddr(net, mac_host): def fixed(ctx): for net in ctx.xpathEval("/network/ip/dhcp/host"): mac = net.xpathEval("@mac")[0].content host = net.xpathEval("@ip")[0].content if mac == mac_host: return host return None return util.get_xml_path(net.XMLDesc(0), func=fixed) def networks(ctx): result = [] for net in ctx.xpathEval("/domain/devices/interface"): mac_host = net.xpathEval("mac/@address")[0].content nic_host = net.xpathEval("source/@network|source/@bridge|source/@dev")[0].content try: net = self.get_network(nic_host) ip = get_mac_ipaddr(net, mac_host) except: ip = None result.append({"mac": mac_host, "nic": nic_host, "ip": ip}) return result return util.get_xml_path(self._XMLDesc(0), func=networks)
def get_net_device(self): def get_mac_ipaddr(net, mac_host): def fixed(doc): for net in doc.xpath('/network/ip/dhcp/host'): mac = net.xpath('@mac')[0] host = net.xpath('@ip')[0] if mac == mac_host: return host return None return util.get_xml_path(net.XMLDesc(0), func=fixed) def networks(ctx): result = [] for net in ctx.xpath('/domain/devices/interface'): mac_host = net.xpath('mac/@address')[0] network_host = net.xpath('source/@network|source/@bridge|source/@dev')[0] target_host = '' if not net.xpath('target/@dev') else net.xpath('target/@dev')[0] filterref_host = '' if not net.xpath('filterref/@filter') else net.xpath('filterref/@filter')[0] try: net = self.get_network(network_host) ip = get_mac_ipaddr(net, mac_host) except libvirtError as e: ip = None result.append({'mac': mac_host, 'nic': network_host, 'target': target_host,'ip': ip, 'filterref': filterref_host}) return result return util.get_xml_path(self._XMLDesc(0), func=networks)
def get_media_device(self): def disks(ctx): result = [] dev = None volume = None storage = None src_fl = None for media in ctx.xpathEval("/domain/devices/disk"): device = media.xpathEval("@device")[0].content if device == "cdrom": try: dev = media.xpathEval("target/@dev")[0].content try: src_fl = media.xpathEval("source/@file")[0].content vol = self.get_volume_by_path(src_fl) volume = vol.name() stg = vol.storagePoolLookupByVolume() storage = stg.name() except: src_fl = None volume = src_fl except: pass finally: result.append({"dev": dev, "image": volume, "storage": storage, "path": src_fl}) return result return util.get_xml_path(self._XMLDesc(0), func=disks)
def get_disk_device(self): def disks(ctx): result = [] dev = None volume = None storage = None src_fl = None disk_format = None info = None for disk in ctx.xpathEval('/domain/devices/disk[@device="disk"]'): try: dev = disk.xpathEval("target/@dev")[0].content src_fl = disk.xpathEval("source/@file|source/@dev|source/@name")[0].content disk_format = disk.xpathEval("driver/@type")[0].content try: vol = self.get_volume_by_path(src_fl) volume = vol.name() stg = vol.storagePoolLookupByVolume() storage = stg.name() info = vol.info() except libvirtError: volume = src_fl except: pass finally: obj = {"dev": dev, "image": volume, "storage": storage, "path": src_fl, "format": disk_format} if info: obj.update({"type": info[0], "capacity": info[1], "allocation": info[2]}) result.append(obj) return result return util.get_xml_path(self._XMLDesc(0), func=disks)
def get_hd_resources_device(self): def hd_resources(ctx): result = [] bus = None slot = None func = None for hostdev in ctx.xpathEval('/domain/devices/hostdev'): type_info = hostdev.xpathEval('@type')[0].content if type_info == 'pci': try: bus = hostdev.xpathEval('source/address/@bus')[0].content slot = hostdev.xpathEval('source/address/@slot')[0].content func = hostdev.xpathEval('source/address/@function')[0].content if bus is None or slot is None or func is None: continue result.append(bus[2:] + ":" + slot[2:] + "." + func[2:]) bus = None slot = None func = None except: pass return result return util.get_xml_path(self._XMLDesc(0), func=hd_resources)
def get_disk_device(self): def disks(ctx): result = [] dev = None volume = None storage = None file = None for disk in ctx.xpathEval('/domain/devices/disk'): device = disk.xpathEval('@device')[0].content if device == 'disk': try: dev = disk.xpathEval('target/@dev')[0].content file = disk.xpathEval('source/@file|source/@dev|source/@name')[0].content try: vol = self.get_volume_by_path(file) volume = vol.name() stg = vol.storagePoolLookupByVolume() storage = stg.name() except libvirtError: volume = file except: pass finally: result.append({'dev': dev, 'image': volume, 'storage': storage, 'path': file}) return result return util.get_xml_path(self._XMLDesc(0), func=disks)
def create_volume(self, storage, name, size, format='qcow2'): size = int(size) * 1073741824 stg = self.get_storage(storage) storage_type = util.get_xml_path(stg.XMLDesc(0), "/pool/@type") if storage_type == 'dir': name += '.img' alloc = 0 else: alloc = size xml = """ <volume> <name>%s</name> <capacity>%s</capacity> <allocation>%s</allocation> <target> <format type='%s'/> </target> </volume>""" % (name, size, alloc, format) stg.createXML(xml, 0) 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: return vol_type else: return 'raw'
def get_net_device(self): def get_mac_ipaddr(net, mac_host): def fixed(ctx): for net in ctx.xpathEval('/network/ip/dhcp/host'): mac = net.xpathEval('@mac')[0].content host = net.xpathEval('@ip')[0].content if mac == mac_host: return host return None return util.get_xml_path(net.XMLDesc(0), func=fixed) def networks(ctx): result = [] for net in ctx.xpathEval('/domain/devices/interface'): mac_host = net.xpathEval('mac/@address')[0].content nic_host = net.xpathEval('source/@network|source/@bridge|source/@dev|target/@dev')[0].content try: net = self.get_network(nic_host) ip = get_mac_ipaddr(net, mac_host) except: ip = None result.append({'mac': mac_host, 'nic': nic_host, 'ip': ip}) return result return util.get_xml_path(self._XMLDesc(0), func=networks)
def create_volume(self, storage, name, size, image_format=image_format, metadata=False): size = int(size) * 1073741824 stg = self.get_storage(storage) storage_type = util.get_xml_path(stg.XMLDesc(0), "/pool/@type") if storage_type == 'dir': name += '.img' alloc = 0 else: alloc = size metadata = False xml = """ <volume> <name>%s</name> <capacity>%s</capacity> <allocation>%s</allocation> <target> <format type='%s'/> <permissions> <owner>107</owner> <group>107</group> <mode>0644</mode> <label>virt_image_t</label> </permissions> </target> </volume>""" % (name, size, alloc, image_format) stg.createXML(xml, metadata) try: stg.refresh(0) except: pass vol = stg.storageVolLookupByName(name) return vol.path()
def get_disk_device(self): def disks(ctx): result = [] dev = None volume = None storage = None src_fl = None disk_format = None disk_size = None for disk in ctx.xpathEval('/domain/devices/disk'): device = disk.xpathEval('@device')[0].content if device == 'disk': try: dev = disk.xpathEval('target/@dev')[0].content src_fl = disk.xpathEval('source/@file|source/@dev|source/@name|source/@volume')[0].content disk_format = disk.xpathEval('driver/@type')[0].content try: vol = self.get_volume_by_path(src_fl) volume = vol.name() disk_size = vol.info()[1] stg = vol.storagePoolLookupByVolume() storage = stg.name() except libvirtError: volume = src_fl except: pass finally: result.append( {'dev': dev, 'image': volume, 'storage': storage, 'path': src_fl, 'format': disk_format, 'size': disk_size}) return result return util.get_xml_path(self._XMLDesc(0), func=disks)
def get_snapshot(self): snapshots = [] snapshot_list = self.instance.snapshotListNames(0) for snapshot in snapshot_list: snap = self.instance.snapshotLookupByName(snapshot, 0) snap_time_create = util.get_xml_path(snap.getXMLDesc(0), "/domainsnapshot/creationTime") snapshots.append({'date': datetime.fromtimestamp(int(snap_time_create)), 'name': snapshot}) return snapshots
def get_mac_ipaddr(net, mac_host): def fixed(ctx): for net in ctx.xpathEval('/network/ip/dhcp/host'): mac = net.xpathEval('@mac')[0].content host = net.xpathEval('@ip')[0].content if mac == mac_host: return host return None return util.get_xml_path(net.XMLDesc(0), func=fixed)
def get_mac_ipaddr(self): def network(ctx): result = [] for net in ctx.xpathEval('/network/ip/dhcp/host'): host = net.xpathEval('@ip')[0].content mac = net.xpathEval('@mac')[0].content result.append({'host': host, 'mac': mac}) return result return util.get_xml_path(self._XMLDesc(0), func=network)
def clone_from_template(self, clone, template): vol = self.get_volume_by_path(template) stg = vol.storagePoolLookupByVolume() 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' xml = """ <volume> <name>%s</name> <capacity>0</capacity> <allocation>0</allocation> <target> <format type='%s'/> </target> </volume>""" % (clone, format) stg.createXMLFrom(xml, vol, 0) clone_vol = stg.storageVolLookupByName(clone) return clone_vol.path()
def get_mac_ipaddr(net, mac_host): def fixed(doc): for net in doc.xpath('/network/ip/dhcp/host'): mac = net.xpath('@mac')[0] host = net.xpath('@ip')[0] if mac == mac_host: return host return None return util.get_xml_path(net.XMLDesc(0), func=fixed)
def get_mac_ipaddr(self): def network(doc): result = [] for net in doc.xpath('/network/ip/dhcp/host'): host = net.xpath('@ip')[0] mac = net.xpath('@mac')[0] result.append({'host': host, 'mac': mac}) return result return util.get_xml_path(self._XMLDesc(0), func=network)
def get_ipv4_type(self): try: xml = self._XMLDesc(VIR_INTERFACE_XML_INACTIVE) ipaddr = util.get_xml_path(xml, "/interface/protocol/ip/@address") if ipaddr: return 'static' else: return 'dhcp' except: return None
def get_net_device(self): def get_mac_ipaddr(net, mac_host): def fixed(doc): for net in doc.xpath('/network/ip/dhcp/host'): mac = net.xpath('@mac')[0] host = net.xpath('@ip')[0] if mac == mac_host: return host return None return util.get_xml_path(net.XMLDesc(0), func=fixed) def networks(ctx): result = [] inbound = outbound = [] for net in ctx.xpath('/domain/devices/interface'): mac_inst = net.xpath('mac/@address')[0] nic_inst = net.xpath( 'source/@network|source/@bridge|source/@dev')[0] target_inst = '' if not net.xpath( 'target/@dev') else net.xpath('target/@dev')[0] filterref_inst = '' if not net.xpath( 'filterref/@filter') else net.xpath('filterref/@filter')[0] if net.xpath('bandwidth/inbound'): in_attr = net.xpath('bandwidth/inbound')[0] in_av = in_attr.get('average') in_peak = in_attr.get('peak') in_burst = in_attr.get('burst') inbound = { 'average': in_av, 'peak': in_peak, 'burst': in_burst } if net.xpath('bandwidth/outbound'): out_attr = net.xpath('bandwidth/outbound')[0] out_av = out_attr.get('average') out_peak = out_attr.get('peak') out_burst = out_attr.get('burst') outbound = { 'average': out_av, 'peak': out_peak, 'burst': out_burst } try: net = self.get_network(nic_inst) ip = get_mac_ipaddr(net, mac_inst) except libvirtError: ip = None result.append({ 'mac': mac_inst, 'nic': nic_inst, 'target': target_inst, 'ip': ip, 'filterref': filterref_inst, 'inbound': inbound, 'outbound': outbound, }) return result return util.get_xml_path(self._XMLDesc(0), func=networks)
def get_bootmenu(self): menu = util.get_xml_path(self._XMLDesc(0), "/domain/os/bootmenu/@enable") return True if menu == 'yes' else False
def get_cur_vcpu(self): cur_vcpu = util.get_xml_path(self._XMLDesc(0), "/domain/vcpu/@current") if cur_vcpu: return int(cur_vcpu)
def get_available(self): return long(util.get_xml_path(self._XMLDesc(0), "/pool/available"))
def get_description(self): return util.get_xml_path(self._XMLDesc(0), "/domain/description")
def domain_name(self, name): inst = self.get_instance(name) domname = util.get_xml_path(inst.XMLDesc(0), "/domain/name") if domname is None: return "NoName" return domname
def get_host_arch(self): """Get guest capabilities""" return util.get_xml_path(self.get_cap_xml(), "/capabilities/host/cpu/arch")
def get_os_type(self): """Get guest capabilities""" return util.get_xml_path(self.get_cap_xml(), "/capabilities/guest/os_type")
def create_instance(self, name, memory, vcpu, vcpu_mode, uuid, arch, machine, firmware, volumes, networks, nwfilter, graphics, virtio, listen_addr, video="vga", console_pass="******", mac=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 = f""" <domain type='{dom_caps["domain"]}'> <name>{name}</name> <description>None</description> <uuid>{uuid}</uuid> <memory unit='KiB'>{memory}</memory> <vcpu>{vcpu}</vcpu>""" if dom_caps["os_support"] == 'yes': xml += f"""<os> <type arch='{arch}' machine='{machine}'>{caps["os_type"]}</type>""" xml += """ <boot dev='hd'/> <boot dev='cdrom'/> <bootmenu enable='yes'/>""" if firmware: if firmware["secure"] == 'yes': xml += """<loader readonly='%s' type='%s' secure='%s'>%s</loader>""" % ( firmware["readonly"], firmware["type"], firmware["secure"], firmware["loader"]) if firmware["secure"] == 'no': xml += """<loader readonly='%s' type='%s'>%s</loader>""" % ( firmware["readonly"], firmware["type"], firmware["loader"]) xml += """</os>""" if caps["features"]: xml += """<features>""" if 'acpi' in caps["features"]: xml += """<acpi/>""" if 'apic' in caps["features"]: xml += """<apic/>""" if 'pae' in caps["features"]: xml += """<pae/>""" if firmware.get("secure", 'no') == 'yes': xml += """<smm state="on"/>""" xml += """</features>""" if vcpu_mode == "host-model": xml += """<cpu mode='host-model'/>""" elif vcpu_mode == "host-passthrough": xml += """<cpu mode='host-passthrough'/>""" elif vcpu_mode == "": pass else: xml += f"""<cpu mode='custom' match='exact' check='none'> <model fallback='allow'>{vcpu_mode}</model>""" xml += """</cpu>""" xml += """ <clock offset="utc"/> <on_poweroff>destroy</on_poweroff> <on_reboot>restart</on_reboot> <on_crash>restart</on_crash> """ xml += """<devices>""" 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 for volume in volumes: disk_opts = '' if volume['cache_mode'] is not None and volume[ 'cache_mode'] != 'default': disk_opts += f"cache='{volume['cache_mode']}' " if volume['io_mode'] is not None and volume['io_mode'] != 'default': disk_opts += f"io='{volume['io_mode']}' " if volume['discard_mode'] is not None and volume[ 'discard_mode'] != 'default': disk_opts += f"discard='{volume['discard_mode']}' " if volume['detect_zeroes_mode'] is not None and volume[ 'detect_zeroes_mode'] != 'default': disk_opts += f"detect_zeroes='{volume['detect_zeroes_mode']}' " 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 += """<disk type='network' device='disk'> <driver name='qemu' type='%s' %s />""" % ( volume['type'], disk_opts) xml += """ <auth username='******'> <secret type='ceph' uuid='%s'/> </auth> <source protocol='rbd' name='%s'>""" % ( ceph_user, secret_uuid, volume['path']) if isinstance(ceph_hosts, list): for host in ceph_hosts: if host.get('port'): xml += """ <host name='%s' port='%s'/>""" % ( host.get('name'), host.get('port')) else: xml += """ <host name='%s'/>""" % host.get('name') xml += """</source>""" else: xml += """<disk type='file' device='%s'>""" % volume['device'] xml += """ <driver name='qemu' type='%s' %s/>""" % ( volume['type'], disk_opts) xml += f""" <source file='%s'/>""" % volume['path'] if volume.get('bus') == 'virtio': xml += """<target dev='vd%s' bus='%s'/>""" % ( vd_disk_letters.pop(0), volume.get('bus')) elif volume.get('bus') == 'ide': xml += """<target dev='hd%s' bus='%s'/>""" % ( hd_disk_letters.pop(0), volume.get('bus')) elif volume.get('bus') == 'fdc': xml += """<target dev='fd%s' bus='%s'/>""" % ( fd_disk_letters.pop(0), volume.get('bus')) elif volume.get('bus') == 'sata' or volume.get('bus') == 'scsi': xml += """<target dev='sd%s' bus='%s'/>""" % ( sd_disk_letters.pop(0), volume.get('bus')) else: xml += """<target dev='sd%s'/>""" % sd_disk_letters.pop(0) xml += """</disk>""" if volume.get('bus') == 'scsi': xml += f"""<controller type='scsi' model='{volume.get('scsi_model')}'/>""" if add_cd: xml += """<disk type='file' device='cdrom'> <driver name='qemu' type='raw'/> <source file = '' /> <readonly/>""" if 'ide' in dom_caps['disk_bus']: xml += """<target dev='hd%s' bus='%s'/>""" % ( hd_disk_letters.pop(0), 'ide') elif 'sata' in dom_caps['disk_bus']: xml += """<target dev='sd%s' bus='%s'/>""" % ( sd_disk_letters.pop(0), 'sata') elif 'scsi' in dom_caps['disk_bus']: xml += """<target dev='sd%s' bus='%s'/>""" % ( sd_disk_letters.pop(0), 'scsi') else: xml += """<target dev='vd%s' bus='%s'/>""" % ( vd_disk_letters.pop(0), 'virtio') xml += """</disk>""" for net in networks.split(','): xml += """<interface type='network'>""" if mac: xml += f"""<mac address='{mac}'/>""" xml += f"""<source network='{net}'/>""" if nwfilter: xml += f"""<filterref filter='{nwfilter}'/>""" if virtio: xml += """<model type='virtio'/>""" xml += """</interface>""" if console_pass == "random": console_pass = "******" + util.randomPasswd() + "'" else: if not console_pass == "": console_pass = "******" + console_pass + "'" if 'usb' in dom_caps['disk_bus']: xml += """<input type='mouse' bus='{}'/>""".format( 'virtio' if virtio else 'usb') xml += """<input type='keyboard' bus='{}'/>""".format( 'virtio' if virtio else 'usb') xml += """<input type='tablet' bus='{}'/>""".format( 'virtio' if virtio else 'usb') else: xml += """<input type='mouse'/>""" xml += """<input type='keyboard'/>""" xml += """<input type='tablet'/>""" xml += f""" <graphics type='{graphics}' port='-1' autoport='yes' {console_pass} listen='{listen_addr}'/> <console type='pty'/> """ if qemu_ga and virtio: xml += """ <channel type='unix'> <target type='virtio' name='org.qemu.guest_agent.0'/> </channel>""" xml += f""" <video> <model type='{video}'/> </video> </devices> </domain>""" self._defineXML(xml)
def get_console_socket(self): socket = util.get_xml_path(self._XMLDesc(0), "/domain/devices/graphics/@socket") return socket
def get_vnc_passwd(self): return util.get_xml_path(self._XMLDesc(VIR_DOMAIN_XML_SECURE), "/domain/devices/graphics/@passwd")
def get_vnc(self): vnc = util.get_xml_path(self._XMLDesc(0), "/domain/devices/graphics[@type='vnc']/@port") return vnc
def get_description(self): description = util.get_xml_path(self._XMLDesc(0), "/domain/description") return description if description else ''
def clone_instance(self, clone_data): clone_dev_path = [] xml = self._XMLDesc(VIR_DOMAIN_XML_SECURE) tree = ElementTree.fromstring(xml) name = tree.find('name') name.text = clone_data['name'] uuid = tree.find('uuid') tree.remove(uuid) for num, net in enumerate(tree.findall('devices/interface')): elm = net.find('mac') mac_address = self.fix_mac(clone_data['clone-net-mac-' + str(num)]) elm.set('address', mac_address) for disk in tree.findall('devices/disk'): if disk.get('device') == 'disk': elm = disk.find('target') device_name = elm.get('dev') if device_name: target_file = clone_data['disk-' + device_name] try: meta_prealloc = clone_data['meta-' + device_name] except: meta_prealloc = False elm.set('dev', device_name) elm = disk.find('source') source_file = elm.get('file') if source_file: clone_dev_path.append(source_file) clone_path = os.path.join(os.path.dirname(source_file), target_file) elm.set('file', clone_path) vol = self.get_volume_by_path(source_file) vol_format = util.get_xml_path( vol.XMLDesc(0), "/volume/target/format/@type") if vol_format == 'qcow2' and meta_prealloc: meta_prealloc = True vol_clone_xml = """ <volume> <name>%s</name> <capacity>0</capacity> <allocation>0</allocation> <target> <format type='%s'/> <permissions> <owner>%s</owner> <group>%s</group> <mode>0644</mode> <label>virt_image_t</label> </permissions> <compat>1.1</compat> <features> <lazy_refcounts/> </features> </target> </volume>""" % ( target_file, vol_format, owner['uid'], owner['guid']) stg = vol.storagePoolLookupByVolume() stg.createXMLFrom(vol_clone_xml, vol, meta_prealloc) source_protocol = elm.get('protocol') if source_protocol == 'rbd': source_name = elm.get('name') clone_name = "%s/%s" % (os.path.dirname(source_name), target_file) elm.set('name', clone_name) vol = self.get_volume_by_path(source_name) vol_format = util.get_xml_path( vol.XMLDesc(0), "/volume/target/format/@type") vol_clone_xml = """ <volume type='network'> <name>%s</name> <capacity>0</capacity> <allocation>0</allocation> <target> <format type='%s'/> </target> </volume>""" % (target_file, vol_format) stg = vol.storagePoolLookupByVolume() stg.createXMLFrom(vol_clone_xml, vol, meta_prealloc) source_dev = elm.get('dev') if source_dev: clone_path = os.path.join(os.path.dirname(source_dev), target_file) elm.set('dev', clone_path) vol = self.get_volume_by_path(source_dev) stg = vol.storagePoolLookupByVolume() vol_name = util.get_xml_path(vol.XMLDesc(0), "/volume/name") pool_name = util.get_xml_path(stg.XMLDesc(0), "/pool/name") storage = self.get_wvmStorage(pool_name) storage.clone_volume(vol_name, target_file) options = { 'title': clone_data.get('clone-title', ''), 'description': clone_data.get('clone-description', ''), } self._set_options(tree, options) self._defineXML(ElementTree.tostring(tree)) return self.get_instance(clone_data['name']).UUIDString()
def get_title(self): title = util.get_xml_path(self._XMLDesc(0), "/domain/title") return title if title else ''
def get_volume_type(self, name): vol_xml = self._vol_XMLDesc(name) return util.get_xml_path(vol_xml, "/volume/target/format/@type")
def get_type(self): return util.get_xml_path(self._XMLDesc(0), "/pool/@type")
def get_cur_memory(self): mem = util.get_xml_path(self._XMLDesc(0), "/domain/currentMemory") return int(mem) / 1024
def graphics_type(self, name): inst = self.get_instance(name) console_type = util.get_xml_path(inst.XMLDesc(0), "/domain/devices/graphics/@type") if console_type is None: return "None" return console_type
def get_target_path(self): return util.get_xml_path(self._XMLDesc(0), "/pool/target/path")
def get_capacity(self): return long(util.get_xml_path(self._XMLDesc(0), "/pool/capacity"))
def get_allocation(self): return long(util.get_xml_path(self._XMLDesc(0), "/pool/allocation"))
def get_console_websocket_port(self): console_type = self.get_console_type() websocket_port = util.get_xml_path( self._XMLDesc(0), "/domain/devices/graphics[@type='%s']/@websocket" % console_type) return websocket_port
def get_vcpu(self): vcpu = util.get_xml_path(self._XMLDesc(0), "/domain/vcpu") return int(vcpu)
def get_console_port(self, console_type=None): if console_type is None: console_type = self.get_console_type() port = util.get_xml_path(self._XMLDesc(0), "/domain/devices/graphics[@type='%s']/@port" % console_type) return port
def get_console_type(self): console_type = util.get_xml_path(self._XMLDesc(0), "/domain/devices/graphics/@type") return console_type
def get_vnc_keymap(self): return util.get_xml_path(self._XMLDesc(VIR_DOMAIN_XML_SECURE), "/domain/devices/graphics/@keymap") or ''
def create(request, host_id): """ Create new instance. """ if not request.user.is_authenticated(): return HttpResponseRedirect('/login') conn = None errors = [] storages = [] networks = [] compute = Compute.objects.get(id=host_id) flavors = Flavor.objects.filter().order_by('id') try: conn = wvmCreate(compute.hostname, compute.login, compute.password, compute.type) storages = sorted(conn.get_storages()) networks = sorted(conn.get_networks()) instances = conn.get_instances() get_images = sorted(conn.get_storages_images()) mac_auto = util.randomMAC() except libvirtError as err: errors.append(err.message) if conn: if not storages: msg = _("You haven't defined have any storage pools") errors.append(msg) if not networks: msg = _("You haven't defined have any network pools") errors.append(msg) if request.method == 'POST': if 'create_flavor' in request.POST: form = FlavorAddForm(request.POST) if form.is_valid(): data = form.cleaned_data create_flavor = Flavor(label=data['label'], vcpu=data['vcpu'], memory=data['memory'], disk=data['disk']) create_flavor.save() return HttpResponseRedirect(request.get_full_path()) if 'delete_flavor' in request.POST: flavor_id = request.POST.get('flavor', '') delete_flavor = Flavor.objects.get(id=flavor_id) delete_flavor.delete() return HttpResponseRedirect(request.get_full_path()) if 'create_xml' in request.POST: xml = request.POST.get('from_xml', '') try: name = util.get_xml_path(xml, '/domain/name') except util.libxml2.parserError: name = None if name in instances: msg = _("A virtual machine with this name already exists") errors.append(msg) else: try: conn._defineXML(xml) return HttpResponseRedirect('/instance/%s/%s' % (host_id, name)) except libvirtError as err: errors.append(err.message) if 'create' in request.POST: volumes = {} form = NewVMForm(request.POST) if form.is_valid(): data = form.cleaned_data if instances: if data['name'] in instances: msg = _( "A virtual machine with this name already exists" ) errors.append(msg) if not errors: if data['hdd_size']: if not data['mac']: msg = _( "No Virtual Machine MAC has been entered") errors.append(msg) else: try: path = conn.create_volume( data['storage'], data['name'], data['hdd_size']) volumes[path] = conn.get_volume_type(path) except libvirtError as msg_error: errors.append(msg_error.message) elif data['template']: templ_path = conn.get_volume_path(data['template']) clone_path = conn.clone_from_template( data['name'], templ_path) volumes[clone_path] = conn.get_volume_type( clone_path) else: if not data['images']: msg = _( "First you need to create or select an image" ) errors.append(msg) else: for vol in data['images'].split(','): try: path = conn.get_volume_path(vol) volumes[path] = conn.get_volume_type( path) except libvirtError as msg_error: errors.append(msg_error.message) if not errors: uuid = util.randomUUID() try: conn.create_instance( data['name'], data['memory'], data['vcpu'], data['host_model'], uuid, volumes, data['networks'], data['virtio'], data['mac']) create_instance = Instance(compute_id=host_id, name=data['name'], uuid=uuid) create_instance.save() return HttpResponseRedirect( '/instance/%s/%s/' % (host_id, data['name'])) except libvirtError as msg_error: if data['hdd_size']: conn.delete_volume(volumes.keys()[0]) errors.append(msg_error.message) conn.close() return render_to_response('create.html', locals(), context_instance=RequestContext(request))
def get_instance_memory(self, name): inst = self.get_instance(name) mem = util.get_xml_path(inst.XMLDesc(0), "/domain/currentMemory") return int(mem) / 1024
def create_instance(self, name, memory, vcpu, host_model, uuid, images, cache_mode, networks, virtio, listen_addr, nwfilter=None, video="cirrus", console_pass="******", mac=None): """ Create VM function """ memory = int(memory) * 1024 if self.is_kvm_supported(): hypervisor_type = 'kvm' else: hypervisor_type = 'qemu' xml = """ <domain type='%s'> <name>%s</name> <description>None</description> <uuid>%s</uuid> <memory unit='KiB'>%s</memory> <vcpu>%s</vcpu>""" % (hypervisor_type, name, uuid, memory, vcpu) if host_model: xml += """<cpu mode='host-model'/>""" xml += """<os> <type arch='%s'>%s</type> <boot dev='hd'/> <boot dev='cdrom'/> <bootmenu enable='yes'/> </os>""" % (self.get_host_arch(), self.get_os_type()) xml += """<features> <acpi/><apic/><pae/> </features> <clock offset="utc"/> <on_poweroff>destroy</on_poweroff> <on_reboot>restart</on_reboot> <on_crash>restart</on_crash> <devices>""" disk_letters = list(string.lowercase) for image, img_type in images.items(): stg = self.get_storage_by_vol_path(image) stg_type = util.get_xml_path(stg.XMLDesc(0), "/pool/@type") if stg_type == 'rbd': ceph_user, secret_uuid, ceph_hosts = get_rbd_storage_data(stg) xml += """<disk type='network' device='disk'> <driver name='qemu' type='%s' cache='%s'/> <auth username='******'> <secret type='ceph' uuid='%s'/> </auth> <source protocol='rbd' name='%s'>""" % ( img_type, cache_mode, ceph_user, secret_uuid, image) if isinstance(ceph_hosts, list): for host in ceph_hosts: if host.get('port'): xml += """ <host name='%s' port='%s'/>""" % ( host.get('name'), host.get('port')) else: xml += """ <host name='%s'/>""" % host.get('name') xml += """ </source>""" else: xml += """<disk type='file' device='disk'> <driver name='qemu' type='%s' cache='%s'/> <source file='%s'/>""" % (img_type, cache_mode, image) if virtio: xml += """<target dev='vd%s' bus='virtio'/>""" % ( disk_letters.pop(0), ) else: xml += """<target dev='sd%s' bus='ide'/>""" % ( disk_letters.pop(0), ) xml += """</disk>""" xml += """ <disk type='file' device='cdrom'> <driver name='qemu' type='raw'/> <source file=''/> <target dev='hda' bus='ide'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='1'/> </disk>""" for net in networks.split(','): xml += """<interface type='network'>""" if mac: xml += """<mac address='%s'/>""" % mac xml += """<source network='%s'/>""" % net if nwfilter: xml += """<filterref filter='%s'/>""" % nwfilter if virtio: xml += """<model type='virtio'/>""" xml += """</interface>""" if console_pass == "random": console_pass = "******" + util.randomPasswd() + "'" else: if not console_pass == "": console_pass = "******" + console_pass + "'" xml += """ <input type='mouse' bus='ps2'/> <input type='tablet' bus='usb'/> <graphics type='%s' port='-1' autoport='yes' %s listen='%s'/> <console type='pty'/> <video> <model type='%s'/> </video> <memballoon model='virtio'/> </devices> </domain>""" % (QEMU_CONSOLE_DEFAULT_TYPE, console_pass, listen_addr, video) self._defineXML(xml)