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.lowercase)
fd_disk_letters = list(string.lowercase)
hd_disk_letters = list(string.lowercase)
sd_disk_letters = list(string.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 += """
"""
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)