diff options
| author | Josh Durgin <josh.durgin@inktank.com> | 2013-05-24 17:31:17 -0700 |
|---|---|---|
| committer | Josh Durgin <josh.durgin@inktank.com> | 2013-05-28 13:35:02 -0700 |
| commit | 4d99a3486911badc39be4e089bd4106c03a8a671 (patch) | |
| tree | f0edbc240907b6989a260665d5fa0a180b8fb40f | |
| parent | 09526751a85535b3c4ebf7e062b0da10d1d1a99f (diff) | |
| download | nova-4d99a3486911badc39be4e089bd4106c03a8a671.tar.gz nova-4d99a3486911badc39be4e089bd4106c03a8a671.tar.xz nova-4d99a3486911badc39be4e089bd4106c03a8a671.zip | |
libvirt: improve the specification of network disks
Allow zero or more hosts, and make the name optional, since only a
host is needed to use nbd. This allows cinder to fully specify the
location of a sheepdog or rbd volume without depending on extra
configuration files, and lays the groundwork for supporting nbd.
Rename the internal attribute source_host to source_name to reflect
its usage in the libvirt xml, and add source_hosts and source_ports
attributes to store the new information.
Fixes: bug 1077817
blueprint better-libvirt-network-volume-support
Signed-off-by: Josh Durgin <josh.durgin@inktank.com>
Change-Id: I8ac431751692e52ba0786768cea996388962922d
| -rw-r--r-- | nova/tests/virt/libvirt/test_libvirt_config.py | 49 | ||||
| -rw-r--r-- | nova/tests/virt/libvirt/test_libvirt_volume.py | 26 | ||||
| -rw-r--r-- | nova/virt/libvirt/config.py | 16 | ||||
| -rw-r--r-- | nova/virt/libvirt/volume.py | 8 |
4 files changed, 91 insertions, 8 deletions
diff --git a/nova/tests/virt/libvirt/test_libvirt_config.py b/nova/tests/virt/libvirt/test_libvirt_config.py index 8eed7136e..2d9e52f3c 100644 --- a/nova/tests/virt/libvirt/test_libvirt_config.py +++ b/nova/tests/virt/libvirt/test_libvirt_config.py @@ -434,7 +434,7 @@ class LibvirtConfigGuestDiskTest(LibvirtConfigBaseTest): obj = config.LibvirtConfigGuestDisk() obj.source_type = "network" obj.source_protocol = "iscsi" - obj.source_host = "foo.bar.com" + obj.source_name = "foo.bar.com" obj.driver_name = "qemu" obj.driver_format = "qcow2" obj.target_dev = "/dev/hda" @@ -448,11 +448,56 @@ class LibvirtConfigGuestDiskTest(LibvirtConfigBaseTest): <target bus="ide" dev="/dev/hda"/> </disk>""") + def test_config_network_no_name(self): + obj = config.LibvirtConfigGuestDisk() + obj.source_type = 'network' + obj.source_protocol = 'nbd' + obj.source_hosts = ['foo.bar.com'] + obj.source_ports = [None] + obj.driver_name = 'qemu' + obj.driver_format = 'raw' + obj.target_dev = '/dev/vda' + obj.target_bus = 'virtio' + + xml = obj.to_xml() + self.assertXmlEqual(xml, """ + <disk type="network" device="disk"> + <driver name="qemu" type="raw"/> + <source protocol="nbd"> + <host name="foo.bar.com"/> + </source> + <target bus="virtio" dev="/dev/vda"/> + </disk>""") + + def test_config_network_multihost(self): + obj = config.LibvirtConfigGuestDisk() + obj.source_type = 'network' + obj.source_protocol = 'rbd' + obj.source_name = 'pool/image' + obj.source_hosts = ['foo.bar.com', '::1', '1.2.3.4'] + obj.source_ports = [None, '123', '456'] + obj.driver_name = 'qemu' + obj.driver_format = 'raw' + obj.target_dev = '/dev/vda' + obj.target_bus = 'virtio' + + xml = obj.to_xml() + self.assertXmlEqual(xml, """ + <disk type="network" device="disk"> + <driver name="qemu" type="raw"/> + <source name="pool/image" protocol="rbd"> + <host name="foo.bar.com"/> + <host name="::1" port="123"/> + <host name="1.2.3.4" port="456"/> + </source> + <target bus="virtio" dev="/dev/vda"/> + </disk>""") + def test_config_network_auth(self): obj = config.LibvirtConfigGuestDisk() obj.source_type = "network" obj.source_protocol = "rbd" - obj.source_host = "pool/image" + obj.source_name = "pool/image" obj.driver_name = "qemu" obj.driver_format = "raw" obj.target_dev = "/dev/vda" diff --git a/nova/tests/virt/libvirt/test_libvirt_volume.py b/nova/tests/virt/libvirt/test_libvirt_volume.py index 86773dd10..567749a98 100644 --- a/nova/tests/virt/libvirt/test_libvirt_volume.py +++ b/nova/tests/virt/libvirt/test_libvirt_volume.py @@ -218,6 +218,32 @@ class LibvirtVolumeTestCase(test.TestCase): self.assertEqual(tree.find('./source/auth'), None) libvirt_driver.disconnect_volume(connection_info, "vde") + def test_libvirt_rbd_driver_hosts(self): + libvirt_driver = volume.LibvirtNetVolumeDriver(self.fake_conn) + name = 'volume-00000001' + vol = {'id': 1, 'name': name} + connection_info = self.rbd_connection(vol) + disk_info = { + "bus": "virtio", + "dev": "vde", + "type": "disk", + } + hosts = ['example.com', '1.2.3.4', '::1'] + ports = [None, '6790', '6791'] + connection_info['data']['hosts'] = hosts + connection_info['data']['ports'] = ports + conf = libvirt_driver.connect_volume(connection_info, disk_info) + tree = conf.format_dom() + self.assertEqual(tree.get('type'), 'network') + self.assertEqual(tree.find('./source').get('protocol'), 'rbd') + rbd_name = '%s/%s' % ('rbd', name) + self.assertEqual(tree.find('./source').get('name'), rbd_name) + self.assertEqual(tree.find('./source/auth'), None) + found_hosts = tree.findall('./source/host') + self.assertEqual([host.get('name') for host in found_hosts], hosts) + self.assertEqual([host.get('port') for host in found_hosts], ports) + libvirt_driver.disconnect_volume(connection_info, "vde") + def test_libvirt_rbd_driver_auth_enabled(self): libvirt_driver = volume.LibvirtNetVolumeDriver(self.fake_conn) name = 'volume-00000001' diff --git a/nova/virt/libvirt/config.py b/nova/virt/libvirt/config.py index 08a0566dd..e5319c514 100644 --- a/nova/virt/libvirt/config.py +++ b/nova/virt/libvirt/config.py @@ -460,7 +460,9 @@ class LibvirtConfigGuestDisk(LibvirtConfigGuestDevice): self.driver_cache = None self.source_path = None self.source_protocol = None - self.source_host = None + self.source_name = None + self.source_hosts = [] + self.source_ports = [] self.target_dev = None self.target_path = None self.target_bus = None @@ -499,8 +501,16 @@ class LibvirtConfigGuestDisk(LibvirtConfigGuestDevice): elif self.source_type == "mount": dev.append(etree.Element("source", dir=self.source_path)) elif self.source_type == "network": - dev.append(etree.Element("source", protocol=self.source_protocol, - name=self.source_host)) + source = etree.Element("source", protocol=self.source_protocol) + if self.source_name is not None: + source.set('name', self.source_name) + hosts_info = zip(self.source_hosts, self.source_ports) + for name, port in hosts_info: + host = etree.Element('host', name=name) + if port is not None: + host.set('port', port) + source.append(host) + dev.append(source) if self.auth_secret_type is not None: auth = etree.Element("auth") diff --git a/nova/virt/libvirt/volume.py b/nova/virt/libvirt/volume.py index 317d398d6..fa2f96743 100644 --- a/nova/virt/libvirt/volume.py +++ b/nova/virt/libvirt/volume.py @@ -131,7 +131,7 @@ class LibvirtFakeVolumeDriver(LibvirtBaseVolumeDriver): disk_info) conf.source_type = "network" conf.source_protocol = "fake" - conf.source_host = "fake" + conf.source_name = "fake" return conf @@ -145,10 +145,12 @@ class LibvirtNetVolumeDriver(LibvirtBaseVolumeDriver): conf = super(LibvirtNetVolumeDriver, self).connect_volume(connection_info, disk_info) + netdisk_properties = connection_info['data'] conf.source_type = "network" conf.source_protocol = connection_info['driver_volume_type'] - conf.source_host = connection_info['data']['name'] - netdisk_properties = connection_info['data'] + conf.source_name = netdisk_properties.get('name') + conf.source_hosts = netdisk_properties.get('hosts', []) + conf.source_ports = netdisk_properties.get('ports', []) auth_enabled = netdisk_properties.get('auth_enabled') if (conf.source_protocol == 'rbd' and CONF.rbd_secret_uuid): |
