From 095759640dd48e2ea470dc160726a3a8501800a1 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Tue, 11 Dec 2012 17:38:08 +0000 Subject: Export custom SMBIOS info to QEMU/KVM guests Provide custom SMBIOS data to QEMU/KVM guests, so that they can reliably detect the fact that they're running on an OpenStack platform. Guest OS vendors often need info about the host virtualization platform to apply the correct billing process for virtual machines. Looking at 'dmidecode' in the guest will show something akin to ...snip... Handle 0x0100, DMI type 1, 27 bytes System Information Manufacturer: OpenStack Foundation Product Name: OpenStack Nova Version: 2013.1-dev Serial Number: 35363738-393a-3b3c-3d3e-3f4041424344 UUID: 2BAFB510-B7DB-4117-A609-452B6E2BD718 Wake-up Type: Power Switch SKU Number: Not Specified Family: Not Specified ...snip... Change-Id: I5cdd75cd06ee872e5665f06926951b340ff2f57f Signed-off-by: Daniel P. Berrange --- nova/tests/test_libvirt.py | 39 +++++++++++++++++++++++++++++++++++++++ nova/virt/libvirt/driver.py | 24 ++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/nova/tests/test_libvirt.py b/nova/tests/test_libvirt.py index fbafe27f3..a35eacd83 100644 --- a/nova/tests/test_libvirt.py +++ b/nova/tests/test_libvirt.py @@ -48,6 +48,7 @@ from nova.tests import fake_network import nova.tests.image.fake from nova.tests import matchers from nova import utils +from nova import version from nova.virt.disk import api as disk from nova.virt import driver from nova.virt import fake @@ -596,6 +597,7 @@ class LibvirtConnTestCase(test.TestCase): nova.tests.image.fake.stub_out_image_service(self.stubs) self.test_instance = { + 'uuid': '32dfcb37-5af1-552b-357c-be8c3aa38310', 'memory_kb': '1024000', 'basepath': '/some/path', 'bridge_name': 'br100', @@ -1813,6 +1815,43 @@ class LibvirtConnTestCase(test.TestCase): check = (lambda t: t.find('./os/initrd'), None) check_list.append(check) + if hypervisor_type in ['qemu', 'kvm']: + xpath = "./sysinfo/system/entry" + check = (lambda t: t.findall(xpath)[0].get("name"), + "manufacturer") + check_list.append(check) + check = (lambda t: t.findall(xpath)[0].text, + version.vendor_string()) + check_list.append(check) + + check = (lambda t: t.findall(xpath)[1].get("name"), + "product") + check_list.append(check) + check = (lambda t: t.findall(xpath)[1].text, + version.product_string()) + check_list.append(check) + + check = (lambda t: t.findall(xpath)[2].get("name"), + "version") + check_list.append(check) + check = (lambda t: t.findall(xpath)[2].text, + version.version_string_with_package()) + check_list.append(check) + + check = (lambda t: t.findall(xpath)[3].get("name"), + "serial") + check_list.append(check) + check = (lambda t: t.findall(xpath)[3].text, + "cef19ce0-0ca2-11df-855d-b19fbce37686") + check_list.append(check) + + check = (lambda t: t.findall(xpath)[4].get("name"), + "uuid") + check_list.append(check) + check = (lambda t: t.findall(xpath)[4].text, + instance['uuid']) + check_list.append(check) + if hypervisor_type in ['qemu', 'kvm']: check = (lambda t: t.findall('./devices/serial')[0].get( 'type'), 'file') diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index 263fd5ca4..643caa2ea 100644 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -69,6 +69,7 @@ from nova.openstack.common import jsonutils from nova.openstack.common import log as logging from nova.openstack.common.notifier import api as notifier from nova import utils +from nova import version from nova.virt import configdrive from nova.virt.disk import api as disk from nova.virt import driver @@ -1512,6 +1513,11 @@ class LibvirtDriver(driver.ComputeDriver): caps.parse_str(xmlstr) return caps + def get_host_uuid(self): + """Returns a UUID representing the host""" + caps = self.get_host_capabilities() + return caps.host.uuid + def get_host_cpu_for_guest(self): """Returns an instance of config.LibvirtConfigGuestCPU representing the host's CPU model & topology with @@ -1712,6 +1718,18 @@ class LibvirtDriver(driver.ComputeDriver): return devices + def get_guest_config_sysinfo(self, instance): + sysinfo = vconfig.LibvirtConfigGuestSysinfo() + + sysinfo.system_manufacturer = version.vendor_string() + sysinfo.system_product = version.product_string() + sysinfo.system_version = version.version_string_with_package() + + sysinfo.system_serial = self.get_host_uuid() + sysinfo.system_uuid = instance['uuid'] + + return sysinfo + def get_guest_config(self, instance, network_info, image_meta, rescue=None, block_device_info=None): """Get config data for parameters. @@ -1757,6 +1775,12 @@ class LibvirtDriver(driver.ComputeDriver): if CONF.libvirt_type == "xen" and guest.os_type == vm_mode.HVM: guest.os_loader = CONF.xen_hvmloader_path + if CONF.libvirt_type in ("kvm", "qemu"): + caps = self.get_host_capabilities() + if caps.host.cpu.arch in ("i686", "x86_64"): + guest.sysinfo = self.get_guest_config_sysinfo(instance) + guest.os_smbios = vconfig.LibvirtConfigGuestSMBIOS() + if CONF.libvirt_type == "lxc": guest.os_type = vm_mode.EXE guest.os_init_path = "/sbin/init" -- cgit