Browse Source

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
tags/19.0.0.0rc1
Sergii Golovatiuk 1 year ago
parent
commit
8b019d6f1e

+ 58
- 15
nova/tests/unit/virt/libvirt/test_driver.py View File

@@ -9910,6 +9910,10 @@ class LibvirtConnTestCase(test.NoDBTestCase,
9910 9910
                              etree.tostring(config, encoding='unicode'))
9911 9911
 
9912 9912
     def test_live_migration_uri(self):
9913
+        addresses = ('127.0.0.1', '127.0.0.1:4444', '[::1]:4444',
9914
+                    '[0:0:0:0:0:0:0:1]:4444', u'127.0.0.1', u'destination',
9915
+        )
9916
+
9913 9917
         hypervisor_uri_map = (
9914 9918
             ('xen', 'xenmigr://%s/system'),
9915 9919
             ('kvm', 'qemu+tcp://%s/system'),
@@ -9918,17 +9922,42 @@ class LibvirtConnTestCase(test.NoDBTestCase,
9918 9922
             # anything else will return None
9919 9923
             ('lxc', None),
9920 9924
         )
9921
-        dest = 'destination'
9922
-        for hyperv, uri in hypervisor_uri_map:
9923
-            self.flags(virt_type=hyperv, group='libvirt')
9924
-            drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
9925
-            if uri is not None:
9926
-                uri = uri % dest
9927
-                self.assertEqual(uri, drvr._live_migration_uri(dest))
9928
-            else:
9929
-                self.assertRaises(exception.LiveMigrationURINotAvailable,
9930
-                                  drvr._live_migration_uri,
9931
-                                  dest)
9925
+
9926
+        drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
9927
+        for dest in addresses:
9928
+            for hyperv, uri in hypervisor_uri_map:
9929
+                self.flags(virt_type=hyperv, group='libvirt')
9930
+                if uri is not None:
9931
+                    uri = uri % dest
9932
+                    self.assertEqual(uri, drvr._live_migration_uri(dest))
9933
+                else:
9934
+                    self.assertRaises(exception.LiveMigrationURINotAvailable,
9935
+                                      drvr._live_migration_uri,
9936
+                                      dest)
9937
+
9938
+    def test_live_migration_uri_ipv6(self):
9939
+        addresses = ('::1', '0:0:0:0:0:0:0:1', u'::1')
9940
+
9941
+        hypervisor_uri_map = (
9942
+            ('xen', 'xenmigr://[%s]/system'),
9943
+            ('kvm', 'qemu+tcp://[%s]/system'),
9944
+            ('qemu', 'qemu+tcp://[%s]/system'),
9945
+            ('parallels', 'parallels+tcp://[%s]/system'),
9946
+            # anything else will return None
9947
+            ('lxc', None),
9948
+        )
9949
+
9950
+        for dest in addresses:
9951
+            for hyperv, uri in hypervisor_uri_map:
9952
+                self.flags(virt_type=hyperv, group='libvirt')
9953
+                drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
9954
+                if uri is not None:
9955
+                    uri = uri % dest
9956
+                    self.assertEqual(uri, drvr._live_migration_uri(dest))
9957
+                else:
9958
+                    self.assertRaises(exception.LiveMigrationURINotAvailable,
9959
+                                      drvr._live_migration_uri,
9960
+                                      dest)
9932 9961
 
9933 9962
     def test_live_migration_uri_forced(self):
9934 9963
         dest = 'destination'
@@ -9984,12 +10013,26 @@ class LibvirtConnTestCase(test.NoDBTestCase,
9984 10013
         self.flags(virt_type='kvm', group='libvirt')
9985 10014
 
9986 10015
         drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
9987
-        addresses = ('127.0.0.1', '127.0.0.1:4444',
9988
-                     '0:0:0:0:0:0:0:1', '[0:0:0:0:0:0:0:1]:4444',
9989
-                     u'127.0.0.1', u'destination')
10016
+        addresses = ('127.0.0.1', '127.0.0.1:4444', '[::1]:4444',
10017
+                    '[0:0:0:0:0:0:0:1]:4444', u'127.0.0.1', u'destination',
10018
+        )
10019
+
10020
+        for dest in addresses:
10021
+            uri = 'tcp://%s'
10022
+            result = drvr._migrate_uri(dest)
10023
+            self.assertEqual(uri % dest, result)
10024
+            self.assertIsInstance(result, str)
10025
+
10026
+    def test_migrate_uri_forced_live_migration_inboud_addr_ipv6(self):
10027
+        self.flags(virt_type='kvm', group='libvirt')
10028
+
10029
+        drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
10030
+        addresses = ('::1', '0:0:0:0:0:0:0:1', u'::1')
10031
+
9990 10032
         for dest in addresses:
10033
+            uri = 'tcp://[%s]'
9991 10034
             result = drvr._migrate_uri(dest)
9992
-            self.assertEqual('tcp://%s' % dest, result)
10035
+            self.assertEqual(uri % dest, result)
9993 10036
             self.assertIsInstance(result, str)
9994 10037
 
9995 10038
     def test_update_volume_xml_no_serial(self):

+ 5
- 0
nova/virt/libvirt/driver.py View File

@@ -61,6 +61,7 @@ from oslo_utils import encodeutils
61 61
 from oslo_utils import excutils
62 62
 from oslo_utils import fileutils
63 63
 from oslo_utils import importutils
64
+from oslo_utils import netutils as oslo_netutils
64 65
 from oslo_utils import strutils
65 66
 from oslo_utils import timeutils
66 67
 from oslo_utils import units
@@ -734,6 +735,8 @@ class LibvirtDriver(driver.ComputeDriver):
734 735
             'xen': 'xenmigr://%s/system',
735 736
             'parallels': 'parallels+tcp://%s/system',
736 737
         }
738
+        dest = oslo_netutils.escape_ipv6(dest)
739
+
737 740
         virt_type = CONF.libvirt.virt_type
738 741
         # TODO(pkoniszewski): Remove fetching live_migration_uri in Pike
739 742
         uri = CONF.libvirt.live_migration_uri
@@ -753,6 +756,8 @@ class LibvirtDriver(driver.ComputeDriver):
753 756
     @staticmethod
754 757
     def _migrate_uri(dest):
755 758
         uri = None
759
+        dest = oslo_netutils.escape_ipv6(dest)
760
+
756 761
         # Only QEMU live migrations supports migrate-uri parameter
757 762
         virt_type = CONF.libvirt.virt_type
758 763
         if virt_type in ('qemu', 'kvm'):

+ 4
- 0
releasenotes/notes/libvirt_fix_ipv6_live_migration-bbcde8f3b7d17921.yaml View File

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

Loading…
Cancel
Save