libvirt: Add a default VirtIO-RNG device to guests
tl;dr: We're adding the default VirtIO-RNG device to ensure guests are not starved of entropy (and thus not hang) during boot time. Background ---------- From Nova Git history, commitb94550f419
("libvirt: configuration element for a random number generator device") _did_ add a default RNG device (but with its entropy source to the undesirable '/dev/random'). However, the default RNG device was immediately removed in another commit (605677c
-- "libvirt: remove explicit /dev/random rng default"), with this rationale: libvirt (or rather qemu) will default to /dev/random if no rng device path is specified [...] It's preferable for us to not duplicate this default to allow for a future where libvirt or the hypervisor needs to make more intelligent decisions about the default device to use. The above reasoning doesn't hold up, because: (a) libvirt does not make "policy" decisions, such as choosing an entropy source (or any other such). Therefore Nova, as a management application, should make the decision here. (b) More importantly, when QEMU exposes a VirtIO-RNG device to the guest, that device needs a source of entropy; and QEMU by default uses the legacy and problematic `/dev/random` as the source — instead of the preferred `/dev/urandom`. So QEMU's default for VirtIO-RNG devices is not sufficient, and Nova should not rely on it. (Discussion[+] on 'qemu-devel' list to consider changing QEMU's default.) * * * In this patch: - Make Nova configure a VirtIO-RNG device by default for guests. (Which will be using `/dev/urandom` as the default entropy source.) This will also work for Windows guests, when using VirtIO-Win drivers[*] on the Linux host. - The 'hw_rng_model' image metadata property is now rendered (temporarily) useless -- as it's not used anywhere outside the _add_rng_device() method. But we don't want to deprecate it yet, as we may extend it (see code comment for details); docucment that. [*] https://docs.pagure.org/docs-fedora/create-windows-vms-using-virtio.html [+] https://lists.nongnu.org/archive/html/qemu-devel/2018-09/msg02724.html -- "[RFC] Virtio RNG: Consider changing the default entropy source to /dev/urandom?" Closes-Bug: #1789868 Change-Id: I28e66c9640c38d23b8c0dbd0b05f5260bfcf6d30 Signed-off-by: Kashyap Chamarthy <kchamart@redhat.com>
This commit is contained in:
parent
093e65c2ca
commit
de512f2c02
@ -480,6 +480,20 @@ class OSType(BaseNovaEnum):
|
|||||||
|
|
||||||
class RNGModel(BaseNovaEnum):
|
class RNGModel(BaseNovaEnum):
|
||||||
|
|
||||||
|
# NOTE(kchamart): Along with "virtio", we may need to extend this (if a
|
||||||
|
# good reason shows up) to allow two more values for VirtIO
|
||||||
|
# transitional and non-transitional devices (available since libvirt
|
||||||
|
# 5.2.0):
|
||||||
|
#
|
||||||
|
# - virtio-transitional
|
||||||
|
# - virtio-nontransitional
|
||||||
|
#
|
||||||
|
# This allows one to choose whether you want to have compatibility
|
||||||
|
# with older guest operating systems. The value you select will in
|
||||||
|
# turn decide the kind of PCI topology the guest will get.
|
||||||
|
#
|
||||||
|
# Details:
|
||||||
|
# https://libvirt.org/formatdomain.html#elementsVirtioTransitional
|
||||||
VIRTIO = "virtio"
|
VIRTIO = "virtio"
|
||||||
|
|
||||||
ALL = (VIRTIO,)
|
ALL = (VIRTIO,)
|
||||||
|
@ -359,6 +359,12 @@ class ImageMetaProps(base.NovaObject):
|
|||||||
'hw_rescue_device': fields.BlockDeviceTypeField(),
|
'hw_rescue_device': fields.BlockDeviceTypeField(),
|
||||||
|
|
||||||
# name of the RNG device type eg virtio
|
# name of the RNG device type eg virtio
|
||||||
|
# NOTE(kchamart): Although this is currently not used anymore,
|
||||||
|
# we should not remove / deprecate it yet, as we are likely to
|
||||||
|
# extend this field to allow two more values to support "VirtIO
|
||||||
|
# transitional/non-transitional devices" (refer to the note in
|
||||||
|
# RNGModel() class in nova/objects/fields.py), and thus expose
|
||||||
|
# to the user again.
|
||||||
'hw_rng_model': fields.RNGModelField(),
|
'hw_rng_model': fields.RNGModelField(),
|
||||||
|
|
||||||
# boolean 'true' or 'false' to enable HPET
|
# boolean 'true' or 'false' to enable HPET
|
||||||
|
@ -2486,7 +2486,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
self.assertEqual(cfg.os_type, fields.VMMode.HVM)
|
self.assertEqual(cfg.os_type, fields.VMMode.HVM)
|
||||||
self.assertEqual(cfg.os_boot_dev, ["hd"])
|
self.assertEqual(cfg.os_boot_dev, ["hd"])
|
||||||
self.assertIsNone(cfg.os_root)
|
self.assertIsNone(cfg.os_root)
|
||||||
self.assertEqual(len(cfg.devices), 9)
|
self.assertEqual(len(cfg.devices), 10)
|
||||||
self.assertIsInstance(cfg.devices[0],
|
self.assertIsInstance(cfg.devices[0],
|
||||||
vconfig.LibvirtConfigGuestDisk)
|
vconfig.LibvirtConfigGuestDisk)
|
||||||
self.assertIsInstance(cfg.devices[1],
|
self.assertIsInstance(cfg.devices[1],
|
||||||
@ -2504,6 +2504,8 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
self.assertIsInstance(cfg.devices[7],
|
self.assertIsInstance(cfg.devices[7],
|
||||||
vconfig.LibvirtConfigGuestVideo)
|
vconfig.LibvirtConfigGuestVideo)
|
||||||
self.assertIsInstance(cfg.devices[8],
|
self.assertIsInstance(cfg.devices[8],
|
||||||
|
vconfig.LibvirtConfigGuestRng)
|
||||||
|
self.assertIsInstance(cfg.devices[9],
|
||||||
vconfig.LibvirtConfigMemoryBalloon)
|
vconfig.LibvirtConfigMemoryBalloon)
|
||||||
self.assertEqual(len(cfg.metadata), 1)
|
self.assertEqual(len(cfg.metadata), 1)
|
||||||
self.assertIsInstance(cfg.metadata[0],
|
self.assertIsInstance(cfg.metadata[0],
|
||||||
@ -4533,7 +4535,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
self.assertEqual(cfg.os_type, fields.VMMode.HVM)
|
self.assertEqual(cfg.os_type, fields.VMMode.HVM)
|
||||||
self.assertEqual(cfg.os_boot_dev, ["hd"])
|
self.assertEqual(cfg.os_boot_dev, ["hd"])
|
||||||
self.assertIsNone(cfg.os_root)
|
self.assertIsNone(cfg.os_root)
|
||||||
self.assertEqual(len(cfg.devices), 9)
|
self.assertEqual(len(cfg.devices), 10)
|
||||||
self.assertIsInstance(cfg.devices[0],
|
self.assertIsInstance(cfg.devices[0],
|
||||||
vconfig.LibvirtConfigGuestDisk)
|
vconfig.LibvirtConfigGuestDisk)
|
||||||
self.assertIsInstance(cfg.devices[1],
|
self.assertIsInstance(cfg.devices[1],
|
||||||
@ -4551,6 +4553,8 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
self.assertIsInstance(cfg.devices[7],
|
self.assertIsInstance(cfg.devices[7],
|
||||||
vconfig.LibvirtConfigGuestVideo)
|
vconfig.LibvirtConfigGuestVideo)
|
||||||
self.assertIsInstance(cfg.devices[8],
|
self.assertIsInstance(cfg.devices[8],
|
||||||
|
vconfig.LibvirtConfigGuestRng)
|
||||||
|
self.assertIsInstance(cfg.devices[9],
|
||||||
vconfig.LibvirtConfigMemoryBalloon)
|
vconfig.LibvirtConfigMemoryBalloon)
|
||||||
|
|
||||||
def test_get_guest_config_with_root_device_name(self):
|
def test_get_guest_config_with_root_device_name(self):
|
||||||
@ -5001,7 +5005,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
|
|
||||||
cfg = self._get_guest_config_with_graphics()
|
cfg = self._get_guest_config_with_graphics()
|
||||||
|
|
||||||
self.assertEqual(len(cfg.devices), 6)
|
self.assertEqual(len(cfg.devices), 7)
|
||||||
self.assertIsInstance(cfg.devices[0],
|
self.assertIsInstance(cfg.devices[0],
|
||||||
vconfig.LibvirtConfigGuestDisk)
|
vconfig.LibvirtConfigGuestDisk)
|
||||||
self.assertIsInstance(cfg.devices[1],
|
self.assertIsInstance(cfg.devices[1],
|
||||||
@ -5013,6 +5017,8 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
self.assertIsInstance(cfg.devices[4],
|
self.assertIsInstance(cfg.devices[4],
|
||||||
vconfig.LibvirtConfigGuestVideo)
|
vconfig.LibvirtConfigGuestVideo)
|
||||||
self.assertIsInstance(cfg.devices[5],
|
self.assertIsInstance(cfg.devices[5],
|
||||||
|
vconfig.LibvirtConfigGuestRng)
|
||||||
|
self.assertIsInstance(cfg.devices[6],
|
||||||
vconfig.LibvirtConfigMemoryBalloon)
|
vconfig.LibvirtConfigMemoryBalloon)
|
||||||
|
|
||||||
self.assertEqual(cfg.devices[3].type, 'vnc')
|
self.assertEqual(cfg.devices[3].type, 'vnc')
|
||||||
@ -5028,7 +5034,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
|
|
||||||
cfg = self._get_guest_config_with_graphics()
|
cfg = self._get_guest_config_with_graphics()
|
||||||
|
|
||||||
self.assertEqual(len(cfg.devices), 7)
|
self.assertEqual(len(cfg.devices), 8)
|
||||||
self.assertIsInstance(cfg.devices[0],
|
self.assertIsInstance(cfg.devices[0],
|
||||||
vconfig.LibvirtConfigGuestDisk)
|
vconfig.LibvirtConfigGuestDisk)
|
||||||
self.assertIsInstance(cfg.devices[1],
|
self.assertIsInstance(cfg.devices[1],
|
||||||
@ -5042,6 +5048,8 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
self.assertIsInstance(cfg.devices[5],
|
self.assertIsInstance(cfg.devices[5],
|
||||||
vconfig.LibvirtConfigGuestVideo)
|
vconfig.LibvirtConfigGuestVideo)
|
||||||
self.assertIsInstance(cfg.devices[6],
|
self.assertIsInstance(cfg.devices[6],
|
||||||
|
vconfig.LibvirtConfigGuestRng)
|
||||||
|
self.assertIsInstance(cfg.devices[7],
|
||||||
vconfig.LibvirtConfigMemoryBalloon)
|
vconfig.LibvirtConfigMemoryBalloon)
|
||||||
|
|
||||||
self.assertEqual(cfg.devices[3].type, "tablet")
|
self.assertEqual(cfg.devices[3].type, "tablet")
|
||||||
@ -5060,7 +5068,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
|
|
||||||
cfg = self._get_guest_config_with_graphics()
|
cfg = self._get_guest_config_with_graphics()
|
||||||
|
|
||||||
self.assertEqual(len(cfg.devices), 7)
|
self.assertEqual(len(cfg.devices), 8)
|
||||||
self.assertIsInstance(cfg.devices[0],
|
self.assertIsInstance(cfg.devices[0],
|
||||||
vconfig.LibvirtConfigGuestDisk)
|
vconfig.LibvirtConfigGuestDisk)
|
||||||
self.assertIsInstance(cfg.devices[1],
|
self.assertIsInstance(cfg.devices[1],
|
||||||
@ -5074,6 +5082,8 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
self.assertIsInstance(cfg.devices[5],
|
self.assertIsInstance(cfg.devices[5],
|
||||||
vconfig.LibvirtConfigGuestVideo)
|
vconfig.LibvirtConfigGuestVideo)
|
||||||
self.assertIsInstance(cfg.devices[6],
|
self.assertIsInstance(cfg.devices[6],
|
||||||
|
vconfig.LibvirtConfigGuestRng)
|
||||||
|
self.assertIsInstance(cfg.devices[7],
|
||||||
vconfig.LibvirtConfigMemoryBalloon)
|
vconfig.LibvirtConfigMemoryBalloon)
|
||||||
|
|
||||||
self.assertEqual(cfg.devices[3].type, 'tablet')
|
self.assertEqual(cfg.devices[3].type, 'tablet')
|
||||||
@ -5095,7 +5105,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
expect = {"ppc": "vga", "ppc64": "vga",
|
expect = {"ppc": "vga", "ppc64": "vga",
|
||||||
"ppc64le": "vga", "aarch64": "virtio"}
|
"ppc64le": "vga", "aarch64": "virtio"}
|
||||||
video_type = expect.get(blockinfo.libvirt_utils.get_arch({}), "qxl")
|
video_type = expect.get(blockinfo.libvirt_utils.get_arch({}), "qxl")
|
||||||
self.assertEqual(len(cfg.devices), 7)
|
self.assertEqual(len(cfg.devices), 8)
|
||||||
self.assertIsInstance(cfg.devices[0],
|
self.assertIsInstance(cfg.devices[0],
|
||||||
vconfig.LibvirtConfigGuestDisk)
|
vconfig.LibvirtConfigGuestDisk)
|
||||||
self.assertIsInstance(cfg.devices[1],
|
self.assertIsInstance(cfg.devices[1],
|
||||||
@ -5109,6 +5119,8 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
self.assertIsInstance(cfg.devices[5],
|
self.assertIsInstance(cfg.devices[5],
|
||||||
vconfig.LibvirtConfigGuestVideo)
|
vconfig.LibvirtConfigGuestVideo)
|
||||||
self.assertIsInstance(cfg.devices[6],
|
self.assertIsInstance(cfg.devices[6],
|
||||||
|
vconfig.LibvirtConfigGuestRng)
|
||||||
|
self.assertIsInstance(cfg.devices[7],
|
||||||
vconfig.LibvirtConfigMemoryBalloon)
|
vconfig.LibvirtConfigMemoryBalloon)
|
||||||
|
|
||||||
self.assertEqual(cfg.devices[3].target_name, "com.redhat.spice.0")
|
self.assertEqual(cfg.devices[3].target_name, "com.redhat.spice.0")
|
||||||
@ -5228,7 +5240,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
|
|
||||||
cfg = drvr._get_guest_config(instance_ref, [],
|
cfg = drvr._get_guest_config(instance_ref, [],
|
||||||
image_meta, disk_info)
|
image_meta, disk_info)
|
||||||
self.assertEqual(7, len(cfg.devices))
|
self.assertEqual(8, len(cfg.devices))
|
||||||
self.assertIsInstance(cfg.devices[0],
|
self.assertIsInstance(cfg.devices[0],
|
||||||
vconfig.LibvirtConfigGuestDisk)
|
vconfig.LibvirtConfigGuestDisk)
|
||||||
self.assertIsInstance(cfg.devices[1],
|
self.assertIsInstance(cfg.devices[1],
|
||||||
@ -5242,6 +5254,8 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
self.assertIsInstance(cfg.devices[5],
|
self.assertIsInstance(cfg.devices[5],
|
||||||
vconfig.LibvirtConfigGuestVideo)
|
vconfig.LibvirtConfigGuestVideo)
|
||||||
self.assertIsInstance(cfg.devices[6],
|
self.assertIsInstance(cfg.devices[6],
|
||||||
|
vconfig.LibvirtConfigGuestRng)
|
||||||
|
self.assertIsInstance(cfg.devices[7],
|
||||||
vconfig.LibvirtConfigMemoryBalloon)
|
vconfig.LibvirtConfigMemoryBalloon)
|
||||||
|
|
||||||
self.assertEqual("tcp", cfg.devices[2].type)
|
self.assertEqual("tcp", cfg.devices[2].type)
|
||||||
@ -5262,7 +5276,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
|
|
||||||
cfg = drvr._get_guest_config(instance_ref, [],
|
cfg = drvr._get_guest_config(instance_ref, [],
|
||||||
image_meta, disk_info)
|
image_meta, disk_info)
|
||||||
self.assertEqual(9, len(cfg.devices))
|
self.assertEqual(10, len(cfg.devices))
|
||||||
self.assertIsInstance(cfg.devices[0],
|
self.assertIsInstance(cfg.devices[0],
|
||||||
vconfig.LibvirtConfigGuestDisk)
|
vconfig.LibvirtConfigGuestDisk)
|
||||||
self.assertIsInstance(cfg.devices[1],
|
self.assertIsInstance(cfg.devices[1],
|
||||||
@ -5280,6 +5294,8 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
self.assertIsInstance(cfg.devices[7],
|
self.assertIsInstance(cfg.devices[7],
|
||||||
vconfig.LibvirtConfigGuestVideo)
|
vconfig.LibvirtConfigGuestVideo)
|
||||||
self.assertIsInstance(cfg.devices[8],
|
self.assertIsInstance(cfg.devices[8],
|
||||||
|
vconfig.LibvirtConfigGuestRng)
|
||||||
|
self.assertIsInstance(cfg.devices[9],
|
||||||
vconfig.LibvirtConfigMemoryBalloon)
|
vconfig.LibvirtConfigMemoryBalloon)
|
||||||
|
|
||||||
self.assertEqual("tcp", cfg.devices[2].type)
|
self.assertEqual("tcp", cfg.devices[2].type)
|
||||||
@ -5320,7 +5336,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
image_meta)
|
image_meta)
|
||||||
cfg = drvr._get_guest_config(instance_ref, [], image_meta,
|
cfg = drvr._get_guest_config(instance_ref, [], image_meta,
|
||||||
disk_info)
|
disk_info)
|
||||||
self.assertEqual(9, len(cfg.devices), cfg.devices)
|
self.assertEqual(10, len(cfg.devices), cfg.devices)
|
||||||
self.assertIsInstance(cfg.devices[0],
|
self.assertIsInstance(cfg.devices[0],
|
||||||
vconfig.LibvirtConfigGuestDisk)
|
vconfig.LibvirtConfigGuestDisk)
|
||||||
self.assertIsInstance(cfg.devices[1],
|
self.assertIsInstance(cfg.devices[1],
|
||||||
@ -5338,6 +5354,8 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
self.assertIsInstance(cfg.devices[7],
|
self.assertIsInstance(cfg.devices[7],
|
||||||
vconfig.LibvirtConfigGuestVideo)
|
vconfig.LibvirtConfigGuestVideo)
|
||||||
self.assertIsInstance(cfg.devices[8],
|
self.assertIsInstance(cfg.devices[8],
|
||||||
|
vconfig.LibvirtConfigGuestRng)
|
||||||
|
self.assertIsInstance(cfg.devices[9],
|
||||||
vconfig.LibvirtConfigMemoryBalloon)
|
vconfig.LibvirtConfigMemoryBalloon)
|
||||||
|
|
||||||
self.assertEqual("tcp", cfg.devices[2].type)
|
self.assertEqual("tcp", cfg.devices[2].type)
|
||||||
@ -5693,7 +5711,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
image_meta)
|
image_meta)
|
||||||
cfg = drvr._get_guest_config(instance_ref, [],
|
cfg = drvr._get_guest_config(instance_ref, [],
|
||||||
image_meta, disk_info)
|
image_meta, disk_info)
|
||||||
self.assertEqual(len(cfg.devices), 9)
|
self.assertEqual(len(cfg.devices), 10)
|
||||||
self.assertIsInstance(cfg.devices[0],
|
self.assertIsInstance(cfg.devices[0],
|
||||||
vconfig.LibvirtConfigGuestDisk)
|
vconfig.LibvirtConfigGuestDisk)
|
||||||
self.assertIsInstance(cfg.devices[1],
|
self.assertIsInstance(cfg.devices[1],
|
||||||
@ -5711,6 +5729,8 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
self.assertIsInstance(cfg.devices[7],
|
self.assertIsInstance(cfg.devices[7],
|
||||||
vconfig.LibvirtConfigGuestVideo)
|
vconfig.LibvirtConfigGuestVideo)
|
||||||
self.assertIsInstance(cfg.devices[8],
|
self.assertIsInstance(cfg.devices[8],
|
||||||
|
vconfig.LibvirtConfigGuestRng)
|
||||||
|
self.assertIsInstance(cfg.devices[9],
|
||||||
vconfig.LibvirtConfigMemoryBalloon)
|
vconfig.LibvirtConfigMemoryBalloon)
|
||||||
|
|
||||||
self.assertEqual(cfg.devices[3].type, "tablet")
|
self.assertEqual(cfg.devices[3].type, "tablet")
|
||||||
@ -5733,7 +5753,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
image_meta)
|
image_meta)
|
||||||
|
|
||||||
cfg = drvr._get_guest_config(instance_ref, [], image_meta, disk_info)
|
cfg = drvr._get_guest_config(instance_ref, [], image_meta, disk_info)
|
||||||
self.assertEqual(len(cfg.devices), 8)
|
self.assertEqual(len(cfg.devices), 9)
|
||||||
self.assertIsInstance(cfg.devices[0],
|
self.assertIsInstance(cfg.devices[0],
|
||||||
vconfig.LibvirtConfigGuestDisk)
|
vconfig.LibvirtConfigGuestDisk)
|
||||||
self.assertIsInstance(cfg.devices[1],
|
self.assertIsInstance(cfg.devices[1],
|
||||||
@ -5747,11 +5767,13 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
self.assertIsInstance(cfg.devices[5],
|
self.assertIsInstance(cfg.devices[5],
|
||||||
vconfig.LibvirtConfigGuestVideo)
|
vconfig.LibvirtConfigGuestVideo)
|
||||||
self.assertIsInstance(cfg.devices[6],
|
self.assertIsInstance(cfg.devices[6],
|
||||||
vconfig.LibvirtConfigGuestWatchdog)
|
vconfig.LibvirtConfigGuestRng)
|
||||||
self.assertIsInstance(cfg.devices[7],
|
self.assertIsInstance(cfg.devices[7],
|
||||||
|
vconfig.LibvirtConfigGuestWatchdog)
|
||||||
|
self.assertIsInstance(cfg.devices[8],
|
||||||
vconfig.LibvirtConfigMemoryBalloon)
|
vconfig.LibvirtConfigMemoryBalloon)
|
||||||
|
|
||||||
self.assertEqual("none", cfg.devices[6].action)
|
self.assertEqual("none", cfg.devices[7].action)
|
||||||
|
|
||||||
def _test_get_guest_usb_tablet(self, vnc_enabled, spice_enabled, os_type,
|
def _test_get_guest_usb_tablet(self, vnc_enabled, spice_enabled, os_type,
|
||||||
agent_enabled=False, image_meta=None):
|
agent_enabled=False, image_meta=None):
|
||||||
@ -5885,7 +5907,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
cfg = drvr._get_guest_config(instance_ref, [],
|
cfg = drvr._get_guest_config(instance_ref, [],
|
||||||
image_meta, disk_info)
|
image_meta, disk_info)
|
||||||
|
|
||||||
self.assertEqual(8, len(cfg.devices))
|
self.assertEqual(9, len(cfg.devices))
|
||||||
self.assertIsInstance(cfg.devices[0],
|
self.assertIsInstance(cfg.devices[0],
|
||||||
vconfig.LibvirtConfigGuestDisk)
|
vconfig.LibvirtConfigGuestDisk)
|
||||||
self.assertIsInstance(cfg.devices[1],
|
self.assertIsInstance(cfg.devices[1],
|
||||||
@ -5899,11 +5921,13 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
self.assertIsInstance(cfg.devices[5],
|
self.assertIsInstance(cfg.devices[5],
|
||||||
vconfig.LibvirtConfigGuestVideo)
|
vconfig.LibvirtConfigGuestVideo)
|
||||||
self.assertIsInstance(cfg.devices[6],
|
self.assertIsInstance(cfg.devices[6],
|
||||||
vconfig.LibvirtConfigGuestWatchdog)
|
vconfig.LibvirtConfigGuestRng)
|
||||||
self.assertIsInstance(cfg.devices[7],
|
self.assertIsInstance(cfg.devices[7],
|
||||||
|
vconfig.LibvirtConfigGuestWatchdog)
|
||||||
|
self.assertIsInstance(cfg.devices[8],
|
||||||
vconfig.LibvirtConfigMemoryBalloon)
|
vconfig.LibvirtConfigMemoryBalloon)
|
||||||
|
|
||||||
self.assertEqual("none", cfg.devices[6].action)
|
self.assertEqual("none", cfg.devices[7].action)
|
||||||
|
|
||||||
def test_get_guest_config_with_watchdog_overrides_flavor(self):
|
def test_get_guest_config_with_watchdog_overrides_flavor(self):
|
||||||
self.flags(virt_type='kvm', group='libvirt')
|
self.flags(virt_type='kvm', group='libvirt')
|
||||||
@ -5923,7 +5947,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
cfg = drvr._get_guest_config(instance_ref, [],
|
cfg = drvr._get_guest_config(instance_ref, [],
|
||||||
image_meta, disk_info)
|
image_meta, disk_info)
|
||||||
|
|
||||||
self.assertEqual(8, len(cfg.devices))
|
self.assertEqual(9, len(cfg.devices))
|
||||||
self.assertIsInstance(cfg.devices[0],
|
self.assertIsInstance(cfg.devices[0],
|
||||||
vconfig.LibvirtConfigGuestDisk)
|
vconfig.LibvirtConfigGuestDisk)
|
||||||
self.assertIsInstance(cfg.devices[1],
|
self.assertIsInstance(cfg.devices[1],
|
||||||
@ -5937,11 +5961,12 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
self.assertIsInstance(cfg.devices[5],
|
self.assertIsInstance(cfg.devices[5],
|
||||||
vconfig.LibvirtConfigGuestVideo)
|
vconfig.LibvirtConfigGuestVideo)
|
||||||
self.assertIsInstance(cfg.devices[6],
|
self.assertIsInstance(cfg.devices[6],
|
||||||
vconfig.LibvirtConfigGuestWatchdog)
|
vconfig.LibvirtConfigGuestRng)
|
||||||
self.assertIsInstance(cfg.devices[7],
|
self.assertIsInstance(cfg.devices[7],
|
||||||
|
vconfig.LibvirtConfigGuestWatchdog)
|
||||||
|
self.assertIsInstance(cfg.devices[8],
|
||||||
vconfig.LibvirtConfigMemoryBalloon)
|
vconfig.LibvirtConfigMemoryBalloon)
|
||||||
|
self.assertEqual("pause", cfg.devices[7].action)
|
||||||
self.assertEqual("pause", cfg.devices[6].action)
|
|
||||||
|
|
||||||
def test_get_guest_config_with_video_driver_image_meta(self):
|
def test_get_guest_config_with_video_driver_image_meta(self):
|
||||||
self.flags(virt_type='kvm', group='libvirt')
|
self.flags(virt_type='kvm', group='libvirt')
|
||||||
@ -5952,43 +5977,45 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
"disk_format": "raw",
|
"disk_format": "raw",
|
||||||
"properties": {"hw_video_model": "vmvga"}})
|
"properties": {"hw_video_model": "vmvga"}})
|
||||||
|
|
||||||
disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
|
|
||||||
instance_ref,
|
|
||||||
image_meta)
|
|
||||||
cfg = drvr._get_guest_config(instance_ref, [], image_meta, disk_info)
|
|
||||||
self.assertEqual(len(cfg.devices), 7)
|
|
||||||
self.assertIsInstance(cfg.devices[0],
|
|
||||||
vconfig.LibvirtConfigGuestDisk)
|
|
||||||
self.assertIsInstance(cfg.devices[1],
|
|
||||||
vconfig.LibvirtConfigGuestDisk)
|
|
||||||
self.assertIsInstance(cfg.devices[2],
|
|
||||||
vconfig.LibvirtConfigGuestSerial)
|
|
||||||
self.assertIsInstance(cfg.devices[3],
|
|
||||||
vconfig.LibvirtConfigGuestInput)
|
|
||||||
self.assertIsInstance(cfg.devices[4],
|
|
||||||
vconfig.LibvirtConfigGuestGraphics)
|
|
||||||
self.assertIsInstance(cfg.devices[5],
|
|
||||||
vconfig.LibvirtConfigGuestVideo)
|
|
||||||
self.assertIsInstance(cfg.devices[6],
|
|
||||||
vconfig.LibvirtConfigMemoryBalloon)
|
|
||||||
|
|
||||||
self.assertEqual(cfg.devices[4].type, "vnc")
|
|
||||||
self.assertEqual(cfg.devices[5].type, "vmvga")
|
|
||||||
|
|
||||||
def test_get_guest_config_with_qga_through_image_meta(self):
|
|
||||||
self.flags(virt_type='kvm', group='libvirt')
|
|
||||||
|
|
||||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
|
||||||
instance_ref = objects.Instance(**self.test_instance)
|
|
||||||
image_meta = objects.ImageMeta.from_dict({
|
|
||||||
"disk_format": "raw",
|
|
||||||
"properties": {"hw_qemu_guest_agent": "yes"}})
|
|
||||||
|
|
||||||
disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
|
disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
|
||||||
instance_ref,
|
instance_ref,
|
||||||
image_meta)
|
image_meta)
|
||||||
cfg = drvr._get_guest_config(instance_ref, [], image_meta, disk_info)
|
cfg = drvr._get_guest_config(instance_ref, [], image_meta, disk_info)
|
||||||
self.assertEqual(len(cfg.devices), 8)
|
self.assertEqual(len(cfg.devices), 8)
|
||||||
|
self.assertIsInstance(cfg.devices[0],
|
||||||
|
vconfig.LibvirtConfigGuestDisk)
|
||||||
|
self.assertIsInstance(cfg.devices[1],
|
||||||
|
vconfig.LibvirtConfigGuestDisk)
|
||||||
|
self.assertIsInstance(cfg.devices[2],
|
||||||
|
vconfig.LibvirtConfigGuestSerial)
|
||||||
|
self.assertIsInstance(cfg.devices[3],
|
||||||
|
vconfig.LibvirtConfigGuestInput)
|
||||||
|
self.assertIsInstance(cfg.devices[4],
|
||||||
|
vconfig.LibvirtConfigGuestGraphics)
|
||||||
|
self.assertIsInstance(cfg.devices[5],
|
||||||
|
vconfig.LibvirtConfigGuestVideo)
|
||||||
|
self.assertIsInstance(cfg.devices[6],
|
||||||
|
vconfig.LibvirtConfigGuestRng)
|
||||||
|
self.assertIsInstance(cfg.devices[7],
|
||||||
|
vconfig.LibvirtConfigMemoryBalloon)
|
||||||
|
|
||||||
|
self.assertEqual(cfg.devices[4].type, "vnc")
|
||||||
|
self.assertEqual(cfg.devices[5].type, "vmvga")
|
||||||
|
|
||||||
|
def test_get_guest_config_with_qga_through_image_meta(self):
|
||||||
|
self.flags(virt_type='kvm', group='libvirt')
|
||||||
|
|
||||||
|
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||||
|
instance_ref = objects.Instance(**self.test_instance)
|
||||||
|
image_meta = objects.ImageMeta.from_dict({
|
||||||
|
"disk_format": "raw",
|
||||||
|
"properties": {"hw_qemu_guest_agent": "yes"}})
|
||||||
|
|
||||||
|
disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
|
||||||
|
instance_ref,
|
||||||
|
image_meta)
|
||||||
|
cfg = drvr._get_guest_config(instance_ref, [], image_meta, disk_info)
|
||||||
|
self.assertEqual(len(cfg.devices), 9)
|
||||||
self.assertIsInstance(cfg.devices[0],
|
self.assertIsInstance(cfg.devices[0],
|
||||||
vconfig.LibvirtConfigGuestDisk)
|
vconfig.LibvirtConfigGuestDisk)
|
||||||
self.assertIsInstance(cfg.devices[1],
|
self.assertIsInstance(cfg.devices[1],
|
||||||
@ -6004,6 +6031,8 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
self.assertIsInstance(cfg.devices[6],
|
self.assertIsInstance(cfg.devices[6],
|
||||||
vconfig.LibvirtConfigGuestChannel)
|
vconfig.LibvirtConfigGuestChannel)
|
||||||
self.assertIsInstance(cfg.devices[7],
|
self.assertIsInstance(cfg.devices[7],
|
||||||
|
vconfig.LibvirtConfigGuestRng)
|
||||||
|
self.assertIsInstance(cfg.devices[8],
|
||||||
vconfig.LibvirtConfigMemoryBalloon)
|
vconfig.LibvirtConfigMemoryBalloon)
|
||||||
|
|
||||||
self.assertEqual(cfg.devices[3].type, "tablet")
|
self.assertEqual(cfg.devices[3].type, "tablet")
|
||||||
@ -6050,7 +6079,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
|
|
||||||
cfg = drvr._get_guest_config(instance_ref, [],
|
cfg = drvr._get_guest_config(instance_ref, [],
|
||||||
image_meta, disk_info)
|
image_meta, disk_info)
|
||||||
self.assertEqual(len(cfg.devices), 7)
|
self.assertEqual(len(cfg.devices), 8)
|
||||||
self.assertIsInstance(cfg.devices[0],
|
self.assertIsInstance(cfg.devices[0],
|
||||||
vconfig.LibvirtConfigGuestDisk)
|
vconfig.LibvirtConfigGuestDisk)
|
||||||
self.assertIsInstance(cfg.devices[1],
|
self.assertIsInstance(cfg.devices[1],
|
||||||
@ -6064,6 +6093,8 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
self.assertIsInstance(cfg.devices[5],
|
self.assertIsInstance(cfg.devices[5],
|
||||||
vconfig.LibvirtConfigGuestVideo)
|
vconfig.LibvirtConfigGuestVideo)
|
||||||
self.assertIsInstance(cfg.devices[6],
|
self.assertIsInstance(cfg.devices[6],
|
||||||
|
vconfig.LibvirtConfigGuestRng)
|
||||||
|
self.assertIsInstance(cfg.devices[7],
|
||||||
vconfig.LibvirtConfigMemoryBalloon)
|
vconfig.LibvirtConfigMemoryBalloon)
|
||||||
|
|
||||||
self.assertEqual(cfg.devices[4].type, "spice")
|
self.assertEqual(cfg.devices[4].type, "spice")
|
||||||
@ -6233,7 +6264,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
instance_ref,
|
instance_ref,
|
||||||
image_meta)
|
image_meta)
|
||||||
cfg = drvr._get_guest_config(instance_ref, [], image_meta, disk_info)
|
cfg = drvr._get_guest_config(instance_ref, [], image_meta, disk_info)
|
||||||
self.assertEqual(len(cfg.devices), 7)
|
self.assertEqual(len(cfg.devices), 8)
|
||||||
self.assertIsInstance(cfg.devices[0],
|
self.assertIsInstance(cfg.devices[0],
|
||||||
vconfig.LibvirtConfigGuestDisk)
|
vconfig.LibvirtConfigGuestDisk)
|
||||||
self.assertIsInstance(cfg.devices[1],
|
self.assertIsInstance(cfg.devices[1],
|
||||||
@ -6247,6 +6278,8 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
self.assertIsInstance(cfg.devices[5],
|
self.assertIsInstance(cfg.devices[5],
|
||||||
vconfig.LibvirtConfigGuestVideo)
|
vconfig.LibvirtConfigGuestVideo)
|
||||||
self.assertIsInstance(cfg.devices[6],
|
self.assertIsInstance(cfg.devices[6],
|
||||||
|
vconfig.LibvirtConfigGuestRng)
|
||||||
|
self.assertIsInstance(cfg.devices[7],
|
||||||
vconfig.LibvirtConfigMemoryBalloon)
|
vconfig.LibvirtConfigMemoryBalloon)
|
||||||
|
|
||||||
self.assertEqual(cfg.devices[3].type, "tablet")
|
self.assertEqual(cfg.devices[3].type, "tablet")
|
||||||
@ -6258,10 +6291,8 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
|
|
||||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||||
instance_ref = objects.Instance(**self.test_instance)
|
instance_ref = objects.Instance(**self.test_instance)
|
||||||
instance_ref.flavor.extra_specs = {'hw_rng:allowed': 'True'}
|
|
||||||
image_meta = objects.ImageMeta.from_dict({
|
image_meta = objects.ImageMeta.from_dict({
|
||||||
"disk_format": "raw",
|
"disk_format": "raw"})
|
||||||
"properties": {"hw_rng_model": "virtio"}})
|
|
||||||
|
|
||||||
disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
|
disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
|
||||||
instance_ref,
|
instance_ref,
|
||||||
@ -6296,9 +6327,9 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
|
|
||||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||||
instance_ref = objects.Instance(**self.test_instance)
|
instance_ref = objects.Instance(**self.test_instance)
|
||||||
|
instance_ref.flavor.extra_specs = {'hw_rng:allowed': 'False'}
|
||||||
image_meta = objects.ImageMeta.from_dict({
|
image_meta = objects.ImageMeta.from_dict({
|
||||||
"disk_format": "raw",
|
"disk_format": "raw"})
|
||||||
"properties": {"hw_rng_model": "virtio"}})
|
|
||||||
|
|
||||||
disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
|
disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
|
||||||
instance_ref,
|
instance_ref,
|
||||||
@ -6326,12 +6357,10 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
|
|
||||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||||
instance_ref = objects.Instance(**self.test_instance)
|
instance_ref = objects.Instance(**self.test_instance)
|
||||||
instance_ref.flavor.extra_specs = {'hw_rng:allowed': 'True',
|
instance_ref.flavor.extra_specs = {'hw_rng:rate_bytes': '1024',
|
||||||
'hw_rng:rate_bytes': '1024',
|
|
||||||
'hw_rng:rate_period': '2'}
|
'hw_rng:rate_period': '2'}
|
||||||
image_meta = objects.ImageMeta.from_dict({
|
image_meta = objects.ImageMeta.from_dict({
|
||||||
"disk_format": "raw",
|
"disk_format": "raw"})
|
||||||
"properties": {"hw_rng_model": "virtio"}})
|
|
||||||
|
|
||||||
disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
|
disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
|
||||||
instance_ref,
|
instance_ref,
|
||||||
@ -6371,10 +6400,8 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
|
|
||||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||||
instance_ref = objects.Instance(**self.test_instance)
|
instance_ref = objects.Instance(**self.test_instance)
|
||||||
instance_ref.flavor.extra_specs = {'hw_rng:allowed': 'True'}
|
|
||||||
image_meta = objects.ImageMeta.from_dict({
|
image_meta = objects.ImageMeta.from_dict({
|
||||||
"disk_format": "raw",
|
"disk_format": "raw"})
|
||||||
"properties": {"hw_rng_model": "virtio"}})
|
|
||||||
|
|
||||||
disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
|
disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
|
||||||
instance_ref,
|
instance_ref,
|
||||||
@ -6413,10 +6440,8 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
|
|
||||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||||
instance_ref = objects.Instance(**self.test_instance)
|
instance_ref = objects.Instance(**self.test_instance)
|
||||||
instance_ref.flavor.extra_specs = {'hw_rng:allowed': 'True'}
|
|
||||||
image_meta = objects.ImageMeta.from_dict({
|
image_meta = objects.ImageMeta.from_dict({
|
||||||
"disk_format": "raw",
|
"disk_format": "raw"})
|
||||||
"properties": {"hw_rng_model": "virtio"}})
|
|
||||||
|
|
||||||
disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
|
disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
|
||||||
instance_ref,
|
instance_ref,
|
||||||
@ -7074,8 +7099,9 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
_fake_network_info(self),
|
_fake_network_info(self),
|
||||||
image_meta, disk_info)
|
image_meta, disk_info)
|
||||||
self.assertTrue(mock_path_exists.called)
|
self.assertTrue(mock_path_exists.called)
|
||||||
mock_path_exists.assert_any_call(
|
expected = mock.call(libvirt_driver.
|
||||||
libvirt_driver.DEFAULT_UEFI_LOADER_PATH['aarch64'][0])
|
DEFAULT_UEFI_LOADER_PATH['aarch64'][0])
|
||||||
|
self.assertIn(expected, mock_path_exists.mock_calls)
|
||||||
self.assertEqual(cfg.os_mach_type, "virt")
|
self.assertEqual(cfg.os_mach_type, "virt")
|
||||||
|
|
||||||
num_ports = 0
|
num_ports = 0
|
||||||
@ -7120,8 +7146,9 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
cfg = self._get_guest_config_with_graphics()
|
cfg = self._get_guest_config_with_graphics()
|
||||||
|
|
||||||
self.assertTrue(mock_path_exists.called)
|
self.assertTrue(mock_path_exists.called)
|
||||||
mock_path_exists.assert_any_call(
|
expected = mock.call(libvirt_driver.
|
||||||
libvirt_driver.DEFAULT_UEFI_LOADER_PATH['aarch64'][0])
|
DEFAULT_UEFI_LOADER_PATH['aarch64'][0])
|
||||||
|
self.assertIn(expected, mock_path_exists.mock_calls)
|
||||||
self.assertEqual(cfg.os_mach_type, "virt")
|
self.assertEqual(cfg.os_mach_type, "virt")
|
||||||
|
|
||||||
usbhost_exists = False
|
usbhost_exists = False
|
||||||
|
@ -5109,10 +5109,12 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||||||
guest.add_device(qga)
|
guest.add_device(qga)
|
||||||
|
|
||||||
def _add_rng_device(self, guest, flavor, image_meta):
|
def _add_rng_device(self, guest, flavor, image_meta):
|
||||||
rng_is_virtio = image_meta.properties.get('hw_rng_model') == 'virtio'
|
rng_allowed_str = flavor.extra_specs.get('hw_rng:allowed', 'True')
|
||||||
rng_allowed_str = flavor.extra_specs.get('hw_rng:allowed', '')
|
|
||||||
rng_allowed = strutils.bool_from_string(rng_allowed_str)
|
rng_allowed = strutils.bool_from_string(rng_allowed_str)
|
||||||
if rng_is_virtio and rng_allowed:
|
|
||||||
|
if not rng_allowed:
|
||||||
|
return
|
||||||
|
|
||||||
rng_device = vconfig.LibvirtConfigGuestRng()
|
rng_device = vconfig.LibvirtConfigGuestRng()
|
||||||
rate_bytes = flavor.extra_specs.get('hw_rng:rate_bytes', 0)
|
rate_bytes = flavor.extra_specs.get('hw_rng:rate_bytes', 0)
|
||||||
period = flavor.extra_specs.get('hw_rng:rate_period', 0)
|
period = flavor.extra_specs.get('hw_rng:rate_period', 0)
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
When using the libvirt driver, Nova instances will now get a
|
||||||
|
VirtIO-RNG (Random Number Generator) device by default. This is to
|
||||||
|
ensure guests are not starved of entropy during boot time. In case
|
||||||
|
you want to *disallow* setting an RNG device for some reason, it can
|
||||||
|
be done by setting the flavor Extra Spec property ``hw_rng:allowed``
|
||||||
|
to ``False``.
|
Loading…
Reference in New Issue
Block a user