libvirt: Always escape IPv6 addresses when used in migration URI

If IPv6 is passed to URI it should be wrapped within square brackets.
This patch detects IPv6 to form migration URI properly. Domain name, IPv4 or
already bracketed IPv6 address will pass as is

Extend tests to include collapsed IPv6 addresses and IPv6 addresses with
port

Change-Id: I1201db996ea6ceaebd49479b298d74585a78b006
Closes-Bug: #1786058
This commit is contained in:
Sergii Golovatiuk 2018-08-07 19:49:37 +03:00 committed by Matt Riedemann
parent 17b69575bc
commit 8b019d6f1e
3 changed files with 67 additions and 15 deletions

View File

@ -9910,6 +9910,10 @@ class LibvirtConnTestCase(test.NoDBTestCase,
etree.tostring(config, encoding='unicode'))
def test_live_migration_uri(self):
addresses = ('127.0.0.1', '127.0.0.1:4444', '[::1]:4444',
'[0:0:0:0:0:0:0:1]:4444', u'127.0.0.1', u'destination',
)
hypervisor_uri_map = (
('xen', 'xenmigr://%s/system'),
('kvm', 'qemu+tcp://%s/system'),
@ -9918,17 +9922,42 @@ class LibvirtConnTestCase(test.NoDBTestCase,
# anything else will return None
('lxc', None),
)
dest = 'destination'
for hyperv, uri in hypervisor_uri_map:
self.flags(virt_type=hyperv, group='libvirt')
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
if uri is not None:
uri = uri % dest
self.assertEqual(uri, drvr._live_migration_uri(dest))
else:
self.assertRaises(exception.LiveMigrationURINotAvailable,
drvr._live_migration_uri,
dest)
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
for dest in addresses:
for hyperv, uri in hypervisor_uri_map:
self.flags(virt_type=hyperv, group='libvirt')
if uri is not None:
uri = uri % dest
self.assertEqual(uri, drvr._live_migration_uri(dest))
else:
self.assertRaises(exception.LiveMigrationURINotAvailable,
drvr._live_migration_uri,
dest)
def test_live_migration_uri_ipv6(self):
addresses = ('::1', '0:0:0:0:0:0:0:1', u'::1')
hypervisor_uri_map = (
('xen', 'xenmigr://[%s]/system'),
('kvm', 'qemu+tcp://[%s]/system'),
('qemu', 'qemu+tcp://[%s]/system'),
('parallels', 'parallels+tcp://[%s]/system'),
# anything else will return None
('lxc', None),
)
for dest in addresses:
for hyperv, uri in hypervisor_uri_map:
self.flags(virt_type=hyperv, group='libvirt')
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
if uri is not None:
uri = uri % dest
self.assertEqual(uri, drvr._live_migration_uri(dest))
else:
self.assertRaises(exception.LiveMigrationURINotAvailable,
drvr._live_migration_uri,
dest)
def test_live_migration_uri_forced(self):
dest = 'destination'
@ -9984,12 +10013,26 @@ class LibvirtConnTestCase(test.NoDBTestCase,
self.flags(virt_type='kvm', group='libvirt')
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
addresses = ('127.0.0.1', '127.0.0.1:4444',
'0:0:0:0:0:0:0:1', '[0:0:0:0:0:0:0:1]:4444',
u'127.0.0.1', u'destination')
addresses = ('127.0.0.1', '127.0.0.1:4444', '[::1]:4444',
'[0:0:0:0:0:0:0:1]:4444', u'127.0.0.1', u'destination',
)
for dest in addresses:
uri = 'tcp://%s'
result = drvr._migrate_uri(dest)
self.assertEqual('tcp://%s' % dest, result)
self.assertEqual(uri % dest, result)
self.assertIsInstance(result, str)
def test_migrate_uri_forced_live_migration_inboud_addr_ipv6(self):
self.flags(virt_type='kvm', group='libvirt')
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
addresses = ('::1', '0:0:0:0:0:0:0:1', u'::1')
for dest in addresses:
uri = 'tcp://[%s]'
result = drvr._migrate_uri(dest)
self.assertEqual(uri % dest, result)
self.assertIsInstance(result, str)
def test_update_volume_xml_no_serial(self):

View File

@ -61,6 +61,7 @@ from oslo_utils import encodeutils
from oslo_utils import excutils
from oslo_utils import fileutils
from oslo_utils import importutils
from oslo_utils import netutils as oslo_netutils
from oslo_utils import strutils
from oslo_utils import timeutils
from oslo_utils import units
@ -734,6 +735,8 @@ class LibvirtDriver(driver.ComputeDriver):
'xen': 'xenmigr://%s/system',
'parallels': 'parallels+tcp://%s/system',
}
dest = oslo_netutils.escape_ipv6(dest)
virt_type = CONF.libvirt.virt_type
# TODO(pkoniszewski): Remove fetching live_migration_uri in Pike
uri = CONF.libvirt.live_migration_uri
@ -753,6 +756,8 @@ class LibvirtDriver(driver.ComputeDriver):
@staticmethod
def _migrate_uri(dest):
uri = None
dest = oslo_netutils.escape_ipv6(dest)
# Only QEMU live migrations supports migrate-uri parameter
virt_type = CONF.libvirt.virt_type
if virt_type in ('qemu', 'kvm'):

View File

@ -0,0 +1,4 @@
---
fixes:
- A change has been introduced in the libvirt driver to correctly handle
IPv6 addresses for live migration.