Add classes for defining SMBios information in a guest. This includes adding an smbios sub-element to the guest os element and a sysinfo sub-element to the guest. The sysinfo sub-element contains the SMBios specific data. --- virtinst/guest.py | 4 +- virtinst/osxml.py | 3 +- virtinst/sysinfo.py | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 163 insertions(+), 2 deletions(-) create mode 100644 virtinst/sysinfo.py diff --git a/virtinst/guest.py b/virtinst/guest.py index 6a42536..173aa04 100644 --- a/virtinst/guest.py +++ b/virtinst/guest.py @@ -52,6 +52,7 @@ from .idmap import IdMap from .osxml import OSXML from .pm import PM from .seclabel import Seclabel +from .sysinfo import SYSInfo from .xmlbuilder import XMLBuilder, XMLProperty, XMLChildProperty @@ -106,7 +107,7 @@ class Guest(XMLBuilder): "vcpus", "curvcpus", "vcpu_placement", "cpuset", "numatune", "bootloader", "os", "idmap", "features", "cpu", "clock", "on_poweroff", "on_reboot", "on_crash", - "resource", "pm", "emulator", "_devices", "seclabels"] + "resource", "pm", "emulator", "_devices", "seclabels", "sysinfo"] def __init__(self, *args, **kwargs): XMLBuilder.__init__(self, *args, **kwargs) @@ -212,6 +213,7 @@ class Guest(XMLBuilder): memoryBacking = XMLChildProperty(DomainMemorybacking, is_single=True) idmap = XMLChildProperty(IdMap, is_single=True) resource = XMLChildProperty(DomainResource, is_single=True) + sysinfo = XMLChildProperty(SYSInfo, is_single=True) ############################### diff --git a/virtinst/osxml.py b/virtinst/osxml.py index 2bbd466..54e118b 100644 --- a/virtinst/osxml.py +++ b/virtinst/osxml.py @@ -77,7 +77,7 @@ class OSXML(XMLBuilder): _XML_ROOT_NAME = "os" _XML_PROP_ORDER = ["arch", "os_type", "loader", "loader_ro", "loader_type", "nvram", "nvram_template", "kernel", "initrd", - "kernel_args", "dtb", "_bootdevs"] + "kernel_args", "dtb", "_bootdevs", "smbios_mode"] def _get_bootorder(self): return [dev.dev for dev in self._bootdevs] @@ -116,6 +116,7 @@ class OSXML(XMLBuilder): loader = XMLProperty("./loader") loader_ro = XMLProperty("./loader/@readonly", is_yesno=True) loader_type = XMLProperty("./loader/@type") + smbios_mode = XMLProperty("./smbios/@mode") nvram = XMLProperty("./nvram") nvram_template = XMLProperty("./nvram/@template") arch = XMLProperty("./type/@arch", diff --git a/virtinst/sysinfo.py b/virtinst/sysinfo.py new file mode 100644 index 0000000..eca7921 --- /dev/null +++ b/virtinst/sysinfo.py @@ -0,0 +1,158 @@ +# +# Copyright (C) 2016 Red Hat, Inc. +# Copyright (C) 2016 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Charles Arnold <carnold@xxxxxxxx> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301 USA. +""" +Classes for building and installing with libvirt <sysinfo> XML +""" + +import datetime + +from . import util +from .xmlbuilder import XMLBuilder, XMLChildProperty, XMLProperty + + +class _Entry(XMLBuilder): + """ + Entry Information for SMBios Types + """ + _XML_ROOT_NAME = "entry" + + value = XMLProperty(".") + name = XMLProperty("./@name") + + +class _SMBiosBios(XMLBuilder): + """ + Type 0: BIOS Information + """ + _XML_ROOT_NAME = "bios" + + entry = XMLChildProperty(_Entry) + + def add_entry(self, key, value): + keys = ["vendor", "version", "date", "release"] + if key not in keys: + return + # Libvirt: If supplied, date is in either mm/dd/yy or mm/dd/yyyy format + if key == "date": + try: + datetime.datetime.strptime(value, '%m/%d/%Y') + except ValueError: + try: + datetime.datetime.strptime(value, '%m/%d/%y') + except ValueError: + raise RuntimeError(_("SMBios date string '%s' is invalid.") + % value) + entry = _Entry(self) + self.add_child(entry) + entry.name = key + entry.value = value + + +class _SMBiosSystem(XMLBuilder): + """ + Type 1: System Information + """ + _XML_ROOT_NAME = "system" + + entry = XMLChildProperty(_Entry) + + def add_entry(self, key, value, guest): + keys = ["manufacturer", "product", "version", "serial", "uuid", + "sku", "family"] + if key not in keys: + return + # If a uuid is supplied it must match the guest UUID. This would be + # impossible to guess if the guest uuid is autogenerated so just + # overwrite the guest uuid with what is passed in assuming it passes + # sanity checking. + if key == "uuid": + try: + util.validate_uuid(value) + except ValueError: + raise ValueError(_("Invalid uuid for SMBios: %s") % value) + + if util.vm_uuid_collision(self.conn, value): + raise ValueError(_("UUID '%s' is in use by another guest.") % + value) + + # Override guest uuid with passed in SMBios value (they must match) + guest.uuid = value + + entry = _Entry(self) + self.add_child(entry) + entry.name = key + entry.value = value + + +class _SMBiosBaseboard(XMLBuilder): + """ + Type 2: Baseboard (or Module) Information + """ + _XML_ROOT_NAME = "baseBoard" + + entry = XMLChildProperty(_Entry) + + def add_entry(self, key, value): + keys = ["manufacturer", "product", "version", "asset", "location"] + if key not in keys: + return + entry = _Entry(self) + self.add_child(entry) + entry.name = key + entry.value = value + + +class SYSInfo(XMLBuilder): + """ + Top level class for <sysinfo type='smbios'> object XML + """ + + SMBIOS_TYPE_BIOS = "0" + SMBIOS_TYPE_SYSTEM = "1" + SMBIOS_TYPE_BASEBOARD = "2" + + _XML_ROOT_NAME = "sysinfo" + _XML_PROP_ORDER = ["bios", "system", "baseBoard"] + + def parse(self, guest, value): + val = value.split(',') + optdict = dict(s.split('=') for s in val) + self.type = "smbios" + + if optdict['type'] == self.SMBIOS_TYPE_BIOS: + bios = _SMBiosBios(self.conn) + self.add_child(bios) + for key in optdict: + bios.add_entry(key, optdict[key]) + elif optdict['type'] == self.SMBIOS_TYPE_SYSTEM: + system = _SMBiosSystem(self.conn) + self.add_child(system) + for key in optdict: + system.add_entry(key, optdict[key], guest) + elif optdict['type'] == self.SMBIOS_TYPE_BASEBOARD: + baseBoard = _SMBiosBaseboard(self.conn) + self.add_child(baseBoard) + for key in optdict: + baseBoard.add_entry(key, optdict[key]) + + type = XMLProperty("./@type") + bios = XMLChildProperty(_SMBiosBios) + system = XMLChildProperty(_SMBiosSystem) + baseBoard = XMLChildProperty(_SMBiosBaseboard) -- 2.6.6 _______________________________________________ virt-tools-list mailing list virt-tools-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/virt-tools-list