mirror of
https://github.com/retspen/webvirtcloud
synced 2024-12-25 15:45:23 +00:00
Add nvram clone, rewrite instance migration, add some helper functions
This commit is contained in:
parent
1b0324e3e3
commit
6634207ef5
1 changed files with 67 additions and 20 deletions
|
@ -1,8 +1,16 @@
|
||||||
import time
|
import time
|
||||||
import os.path
|
import os.path
|
||||||
try:
|
try:
|
||||||
from libvirt import libvirtError, VIR_DOMAIN_XML_SECURE, VIR_MIGRATE_LIVE, VIR_MIGRATE_UNSAFE, VIR_DOMAIN_RUNNING, \
|
from libvirt import libvirtError, VIR_DOMAIN_XML_SECURE, VIR_DOMAIN_RUNNING, VIR_DOMAIN_AFFECT_LIVE, \
|
||||||
VIR_DOMAIN_AFFECT_LIVE, VIR_DOMAIN_AFFECT_CONFIG, VIR_DOMAIN_UNDEFINE_NVRAM, VIR_DOMAIN_UNDEFINE_KEEP_NVRAM
|
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:
|
except:
|
||||||
from libvirt import libvirtError, VIR_DOMAIN_XML_SECURE, VIR_MIGRATE_LIVE
|
from libvirt import libvirtError, VIR_DOMAIN_XML_SECURE, VIR_MIGRATE_LIVE
|
||||||
|
|
||||||
|
@ -12,9 +20,9 @@ from lxml import etree
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from vrtManager.connection import wvmConnect
|
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 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):
|
class wvmInstances(wvmConnect):
|
||||||
|
@ -72,19 +80,30 @@ class wvmInstances(wvmConnect):
|
||||||
dom = self.get_instance(name)
|
dom = self.get_instance(name)
|
||||||
dom.resume()
|
dom.resume()
|
||||||
|
|
||||||
def moveto(self, conn, name, live, unsafe, undefine, offline):
|
def moveto(self, conn, name, live, unsafe, undefine, offline, autoconverge=False, compress=False):
|
||||||
flags = 0
|
flags = VIR_MIGRATE_PERSIST_DEST
|
||||||
if live and conn.get_status() == 1:
|
if live and conn.get_status() == 1:
|
||||||
flags |= VIR_MIGRATE_LIVE
|
flags |= VIR_MIGRATE_LIVE
|
||||||
if unsafe and conn.get_status() == 1:
|
if unsafe and conn.get_status() == 1:
|
||||||
flags |= VIR_MIGRATE_UNSAFE
|
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:
|
if undefine:
|
||||||
dom.undefine()
|
flags |= VIR_MIGRATE_UNDEFINE_SOURCE
|
||||||
self.wvm.defineXML(xml)
|
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):
|
def graphics_type(self, name):
|
||||||
inst = self.get_instance(name)
|
inst = self.get_instance(name)
|
||||||
|
@ -192,9 +211,19 @@ class wvmInstance(wvmConnect):
|
||||||
def get_machine_type(self):
|
def get_machine_type(self):
|
||||||
return util.get_xml_path(self._XMLDesc(0), "/domain/os/type/@machine")
|
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):
|
def get_nvram(self):
|
||||||
return util.get_xml_path(self._XMLDesc(0), "/domain/os/nvram")
|
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):
|
def get_vcpus(self):
|
||||||
vcpus = OrderedDict()
|
vcpus = OrderedDict()
|
||||||
tree = etree.fromstring(self._XMLDesc(0))
|
tree = etree.fromstring(self._XMLDesc(0))
|
||||||
|
@ -951,12 +980,10 @@ class wvmInstance(wvmConnect):
|
||||||
return self.instance.hasManagedSaveImage(0)
|
return self.instance.hasManagedSaveImage(0)
|
||||||
|
|
||||||
def get_wvmStorage(self, pool):
|
def get_wvmStorage(self, pool):
|
||||||
storage = wvmStorage(self.host,
|
return wvmStorage(self.host, self.login, self.passwd, self.conn, pool)
|
||||||
self.login,
|
|
||||||
self.passwd,
|
def get_wvmStorages(self):
|
||||||
self.conn,
|
return wvmStorages(self.host, self.login, self.passwd, self.conn)
|
||||||
pool)
|
|
||||||
return storage
|
|
||||||
|
|
||||||
def fix_mac(self, mac):
|
def fix_mac(self, mac):
|
||||||
if ":" in mac:
|
if ":" in mac:
|
||||||
|
@ -970,12 +997,32 @@ class wvmInstance(wvmConnect):
|
||||||
clone_dev_path = []
|
clone_dev_path = []
|
||||||
|
|
||||||
xml = self._XMLDesc(VIR_DOMAIN_XML_SECURE)
|
xml = self._XMLDesc(VIR_DOMAIN_XML_SECURE)
|
||||||
tree = ElementTree.fromstring(xml)
|
tree = etree.fromstring(xml)
|
||||||
name = tree.find('name')
|
name = tree.find('name')
|
||||||
name.text = clone_data['name']
|
name.text = clone_data['name']
|
||||||
uuid = tree.find('uuid')
|
uuid = tree.find('uuid')
|
||||||
tree.remove(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')):
|
for num, net in enumerate(tree.findall('devices/interface')):
|
||||||
elm = net.find('mac')
|
elm = net.find('mac')
|
||||||
mac_address = self.fix_mac(clone_data['clone-net-mac-' + str(num)])
|
mac_address = self.fix_mac(clone_data['clone-net-mac-' + str(num)])
|
||||||
|
@ -1024,7 +1071,7 @@ class wvmInstance(wvmConnect):
|
||||||
<lazy_refcounts/>
|
<lazy_refcounts/>
|
||||||
</features>
|
</features>
|
||||||
</target>
|
</target>
|
||||||
</volume>""" % (target_file, vol_format, owner['uid'], owner['guid'])
|
</volume>""" % (target_file, vol_format, OWNER['uid'], OWNER['guid'])
|
||||||
|
|
||||||
stg = vol.storagePoolLookupByVolume()
|
stg = vol.storagePoolLookupByVolume()
|
||||||
stg.createXMLFrom(vol_clone_xml, vol, meta_prealloc)
|
stg.createXMLFrom(vol_clone_xml, vol, meta_prealloc)
|
||||||
|
|
Loading…
Reference in a new issue