1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2024-10-31 19:44:16 +00:00

Add nvram clone, rewrite instance migration, add some helper functions

This commit is contained in:
catborise 2019-12-19 13:47:07 +03:00
parent 1b0324e3e3
commit 6634207ef5

View file

@ -1,8 +1,16 @@
import time
import os.path
try:
from libvirt import libvirtError, VIR_DOMAIN_XML_SECURE, VIR_MIGRATE_LIVE, VIR_MIGRATE_UNSAFE, VIR_DOMAIN_RUNNING, \
VIR_DOMAIN_AFFECT_LIVE, VIR_DOMAIN_AFFECT_CONFIG, VIR_DOMAIN_UNDEFINE_NVRAM, VIR_DOMAIN_UNDEFINE_KEEP_NVRAM
from libvirt import libvirtError, VIR_DOMAIN_XML_SECURE, VIR_DOMAIN_RUNNING, VIR_DOMAIN_AFFECT_LIVE, \
VIR_DOMAIN_AFFECT_CONFIG, VIR_DOMAIN_UNDEFINE_NVRAM, VIR_DOMAIN_UNDEFINE_KEEP_NVRAM,\
VIR_DOMAIN_START_PAUSED
from libvirt import VIR_MIGRATE_LIVE, \
VIR_MIGRATE_UNSAFE, \
VIR_MIGRATE_PERSIST_DEST, \
VIR_MIGRATE_UNDEFINE_SOURCE, \
VIR_MIGRATE_OFFLINE,\
VIR_MIGRATE_COMPRESSED, \
VIR_MIGRATE_AUTO_CONVERGE
except:
from libvirt import libvirtError, VIR_DOMAIN_XML_SECURE, VIR_MIGRATE_LIVE
@ -12,9 +20,9 @@ from lxml import etree
from datetime import datetime
from collections import OrderedDict
from vrtManager.connection import wvmConnect
from vrtManager.storage import wvmStorage
from vrtManager.storage import wvmStorage, wvmStorages
from webvirtcloud.settings import QEMU_CONSOLE_TYPES
from webvirtcloud.settings import INSTANCE_VOLUME_DEFAULT_OWNER as owner
from webvirtcloud.settings import INSTANCE_VOLUME_DEFAULT_OWNER as OWNER
class wvmInstances(wvmConnect):
@ -72,19 +80,30 @@ class wvmInstances(wvmConnect):
dom = self.get_instance(name)
dom.resume()
def moveto(self, conn, name, live, unsafe, undefine, offline):
flags = 0
def moveto(self, conn, name, live, unsafe, undefine, offline, autoconverge=False, compress=False):
flags = VIR_MIGRATE_PERSIST_DEST
if live and conn.get_status() == 1:
flags |= VIR_MIGRATE_LIVE
if unsafe and conn.get_status() == 1:
flags |= VIR_MIGRATE_UNSAFE
dom = conn.get_instance(name)
xml = dom.XMLDesc(VIR_DOMAIN_XML_SECURE)
if not offline:
dom.migrate(self.wvm, flags, None, None, 0)
if undefine:
dom.undefine()
self.wvm.defineXML(xml)
flags |= VIR_MIGRATE_UNDEFINE_SOURCE
if offline:
flags |= VIR_MIGRATE_OFFLINE
if not offline and autoconverge:
flags |= VIR_MIGRATE_AUTO_CONVERGE
if compress:
flags |= VIR_MIGRATE_COMPRESSED
dom = conn.get_instance(name)
dom_arch = conn.get_arch()
dom_emulator = conn.get_dom_emulator()
if dom_emulator != self.get_emulator(dom_arch):
raise libvirtError('Destination host emulator is different. Cannot be migrated')
dom.migrate(self.wvm, flags, None, None, 0)
def graphics_type(self, name):
inst = self.get_instance(name)
@ -192,9 +211,19 @@ class wvmInstance(wvmConnect):
def get_machine_type(self):
return util.get_xml_path(self._XMLDesc(0), "/domain/os/type/@machine")
def get_dom_emulator(self):
return util.get_xml_path(self._XMLDesc(0), "/domain/devices/emulator")
def get_nvram(self):
return util.get_xml_path(self._XMLDesc(0), "/domain/os/nvram")
def get_loader(self):
xml = self._XMLDesc(0)
loader = util.get_xml_path(xml, "/domain/os/loader")
type = util.get_xml_path(xml, "/domain/os/loader/@type")
readonly = util.get_xml_path(xml, "/domain/os/loader/@readonly")
return {"loader": loader, "type": type, "readonly": readonly}
def get_vcpus(self):
vcpus = OrderedDict()
tree = etree.fromstring(self._XMLDesc(0))
@ -951,12 +980,10 @@ class wvmInstance(wvmConnect):
return self.instance.hasManagedSaveImage(0)
def get_wvmStorage(self, pool):
storage = wvmStorage(self.host,
self.login,
self.passwd,
self.conn,
pool)
return storage
return wvmStorage(self.host, self.login, self.passwd, self.conn, pool)
def get_wvmStorages(self):
return wvmStorages(self.host, self.login, self.passwd, self.conn)
def fix_mac(self, mac):
if ":" in mac:
@ -970,12 +997,32 @@ class wvmInstance(wvmConnect):
clone_dev_path = []
xml = self._XMLDesc(VIR_DOMAIN_XML_SECURE)
tree = ElementTree.fromstring(xml)
tree = etree.fromstring(xml)
name = tree.find('name')
name.text = clone_data['name']
uuid = tree.find('uuid')
tree.remove(uuid)
src_nvram_path = self.get_nvram()
if src_nvram_path:
# Change XML for nvram
nvram = tree.find('os/nvram')
nvram.getparent().remove(nvram)
# NVRAM CLONE: create pool if nvram is not in a pool. then clone it
src_nvram_name = os.path.basename(src_nvram_path)
nvram_dir = os.path.dirname(src_nvram_path)
nvram_pool_name = os.path.basename(nvram_dir)
try:
self.get_volume_by_path(src_nvram_path)
except libvirtError:
stg_conn = self.get_wvmStorages()
stg_conn.create_storage('dir', nvram_pool_name, None, nvram_dir)
new_nvram_name = "%s_VARS" % clone_data['name']
nvram_stg = self.get_wvmStorage(nvram_pool_name)
nvram_stg.clone_volume(src_nvram_name, new_nvram_name, file_suffix='fd')
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)])
@ -1024,7 +1071,7 @@ class wvmInstance(wvmConnect):
<lazy_refcounts/>
</features>
</target>
</volume>""" % (target_file, vol_format, owner['uid'], owner['guid'])
</volume>""" % (target_file, vol_format, OWNER['uid'], OWNER['guid'])
stg = vol.storagePoolLookupByVolume()
stg.createXMLFrom(vol_clone_xml, vol, meta_prealloc)