guest: Move all_devices to guest.devices.X

The way we enumerate devices doesn't conform with the way all
other XMLBuilder instances expose child objects. Move more towards
that direction.

This requires some virt-xml and cli.py hacks but we will remove those
in future patches
This commit is contained in:
Cole Robinson 2018-03-20 17:23:34 -04:00
parent fe9ed2340c
commit 7b61c45d3b
13 changed files with 190 additions and 175 deletions

View File

@ -209,7 +209,7 @@ class XMLParseTest(unittest.TestCase):
check = self._make_checker(guest.resource)
check("partition", None, "/virtualmachines/production")
check = self._make_checker(guest.get_devices("memballoon")[0])
check = self._make_checker(guest.devices.memballoon[0])
check("model", "virtio", "none")
check = self._make_checker(guest.memoryBacking)
@ -334,7 +334,7 @@ class XMLParseTest(unittest.TestCase):
guest, outfile = self._get_test_content("change-disk")
def _get_disk(target):
for disk in guest.get_devices("disk"):
for disk in guest.devices.disk:
if disk.target == target:
return disk
@ -348,7 +348,7 @@ class XMLParseTest(unittest.TestCase):
check("bus", "ide", "usb")
check("removable", None, False, True)
disk = guest.get_devices("disk")[1]
disk = guest.devices.disk[1]
check = self._make_checker(disk.seclabels[1])
check("model", "dac")
check("relabel", None, True)
@ -427,15 +427,15 @@ class XMLParseTest(unittest.TestCase):
def testAlterChars(self):
guest, outfile = self._get_test_content("change-chars")
serial1 = guest.get_devices("serial")[0]
serial2 = guest.get_devices("serial")[1]
parallel1 = guest.get_devices("parallel")[0]
parallel2 = guest.get_devices("parallel")[1]
console1 = guest.get_devices("console")[0]
console2 = guest.get_devices("console")[1]
channel1 = guest.get_devices("channel")[0]
channel2 = guest.get_devices("channel")[1]
channel3 = guest.get_devices("channel")[2]
serial1 = guest.devices.serial[0]
serial2 = guest.devices.serial[1]
parallel1 = guest.devices.parallel[0]
parallel2 = guest.devices.parallel[1]
console1 = guest.devices.console[0]
console2 = guest.devices.console[1]
channel1 = guest.devices.channel[0]
channel2 = guest.devices.channel[1]
channel3 = guest.devices.channel[2]
check = self._make_checker(serial1)
check("type", "null", "udp")
@ -493,10 +493,10 @@ class XMLParseTest(unittest.TestCase):
def testAlterControllers(self):
guest, outfile = self._get_test_content("change-controllers")
dev1 = guest.get_devices("controller")[0]
dev2 = guest.get_devices("controller")[1]
dev3 = guest.get_devices("controller")[2]
dev4 = guest.get_devices("controller")[3]
dev1 = guest.devices.controller[0]
dev2 = guest.devices.controller[1]
dev3 = guest.devices.controller[2]
dev4 = guest.devices.controller[3]
check = self._make_checker(dev1)
check("type", "ide")
@ -523,11 +523,11 @@ class XMLParseTest(unittest.TestCase):
def testAlterNics(self):
guest, outfile = self._get_test_content("change-nics")
dev1 = guest.get_devices("interface")[0]
dev2 = guest.get_devices("interface")[1]
dev3 = guest.get_devices("interface")[2]
dev4 = guest.get_devices("interface")[3]
dev5 = guest.get_devices("interface")[4]
dev1 = guest.devices.interface[0]
dev2 = guest.devices.interface[1]
dev3 = guest.devices.interface[2]
dev4 = guest.devices.interface[3]
dev5 = guest.devices.interface[4]
check = self._make_checker(dev1)
check("type", "user")
@ -575,8 +575,8 @@ class XMLParseTest(unittest.TestCase):
def testAlterInputs(self):
guest, outfile = self._get_test_content("change-inputs")
dev1 = guest.get_devices("input")[0]
dev2 = guest.get_devices("input")[1]
dev1 = guest.devices.input[0]
dev2 = guest.devices.input[1]
check = self._make_checker(dev1)
check("type", "mouse", "tablet")
@ -592,12 +592,12 @@ class XMLParseTest(unittest.TestCase):
def testAlterGraphics(self):
guest, outfile = self._get_test_content("change-graphics")
dev1 = guest.get_devices("graphics")[0]
dev2 = guest.get_devices("graphics")[1]
dev3 = guest.get_devices("graphics")[2]
dev4 = guest.get_devices("graphics")[3]
dev5 = guest.get_devices("graphics")[4]
dev6 = guest.get_devices("graphics")[5]
dev1 = guest.devices.graphics[0]
dev2 = guest.devices.graphics[1]
dev3 = guest.devices.graphics[2]
dev4 = guest.devices.graphics[3]
dev5 = guest.devices.graphics[4]
dev6 = guest.devices.graphics[5]
check = self._make_checker(dev1)
check("type", "vnc")
@ -657,9 +657,9 @@ class XMLParseTest(unittest.TestCase):
def testAlterVideos(self):
guest, outfile = self._get_test_content("change-videos")
dev1 = guest.get_devices("video")[0]
dev2 = guest.get_devices("video")[1]
dev3 = guest.get_devices("video")[2]
dev1 = guest.devices.video[0]
dev2 = guest.devices.video[1]
dev3 = guest.devices.video[2]
check = self._make_checker(dev1)
check("model", "vmvga", "vga")
@ -685,10 +685,10 @@ class XMLParseTest(unittest.TestCase):
guest = virtinst.Guest(self.conn,
parsexml=open(infile).read())
dev1 = guest.get_devices("hostdev")[0]
dev2 = guest.get_devices("hostdev")[1]
dev3 = guest.get_devices("hostdev")[2]
dev4 = guest.get_devices("hostdev")[3]
dev1 = guest.devices.hostdev[0]
dev2 = guest.devices.hostdev[1]
dev3 = guest.devices.hostdev[2]
dev4 = guest.devices.hostdev[3]
check = self._make_checker(dev1)
check("type", "usb", "foo", "usb")
@ -728,7 +728,7 @@ class XMLParseTest(unittest.TestCase):
def testAlterWatchdogs(self):
guest, outfile = self._get_test_content("change-watchdogs")
dev1 = guest.get_devices("watchdog")[0]
dev1 = guest.devices.watchdog[0]
check = self._make_checker(dev1)
check("model", "ib700", "i6300esb")
check("action", "none", "poweroff")
@ -738,13 +738,13 @@ class XMLParseTest(unittest.TestCase):
def testAlterFilesystems(self):
guest, outfile = self._get_test_content("change-filesystems")
dev1 = guest.get_devices("filesystem")[0]
dev2 = guest.get_devices("filesystem")[1]
dev3 = guest.get_devices("filesystem")[2]
dev4 = guest.get_devices("filesystem")[3]
dev5 = guest.get_devices("filesystem")[4]
dev6 = guest.get_devices("filesystem")[5]
dev7 = guest.get_devices("filesystem")[6]
dev1 = guest.devices.filesystem[0]
dev2 = guest.devices.filesystem[1]
dev3 = guest.devices.filesystem[2]
dev4 = guest.devices.filesystem[3]
dev5 = guest.devices.filesystem[4]
dev6 = guest.devices.filesystem[5]
dev7 = guest.devices.filesystem[6]
check = self._make_checker(dev1)
check("type", None, "mount")
@ -800,9 +800,9 @@ class XMLParseTest(unittest.TestCase):
guest = virtinst.Guest(self.conn,
parsexml=open(infile).read())
dev1 = guest.get_devices("sound")[0]
dev2 = guest.get_devices("sound")[1]
dev3 = guest.get_devices("sound")[2]
dev1 = guest.devices.sound[0]
dev2 = guest.devices.sound[1]
dev3 = guest.devices.sound[2]
check = self._make_checker(dev1)
check("model", "sb16", "ac97")
@ -818,11 +818,11 @@ class XMLParseTest(unittest.TestCase):
def testAlterAddr(self):
guest, outfile = self._get_test_content("change-addr")
dev1 = guest.get_devices("disk")[0]
dev2 = guest.get_devices("controller")[0]
dev3 = guest.get_devices("channel")[0]
dev4 = guest.get_devices("disk")[1]
dev5 = guest.get_devices("memory")[0]
dev1 = guest.devices.disk[0]
dev2 = guest.devices.controller[0]
dev3 = guest.devices.channel[0]
dev4 = guest.devices.disk[1]
dev5 = guest.devices.memory[0]
check = self._make_checker(dev1.address)
check("type", "drive", "pci")
@ -868,8 +868,8 @@ class XMLParseTest(unittest.TestCase):
def testAlterSmartCard(self):
guest, outfile = self._get_test_content("change-smartcard")
dev1 = guest.get_devices("smartcard")[0]
dev2 = guest.get_devices("smartcard")[1]
dev1 = guest.devices.smartcard[0]
dev2 = guest.devices.smartcard[1]
check = self._make_checker(dev1)
check("type", None, "tcp")
@ -883,8 +883,8 @@ class XMLParseTest(unittest.TestCase):
def testAlterRedirdev(self):
guest, outfile = self._get_test_content("change-redirdev")
dev1 = guest.get_devices("redirdev")[0]
dev2 = guest.get_devices("redirdev")[1]
dev1 = guest.devices.redirdev[0]
dev2 = guest.devices.redirdev[1]
check = self._make_checker(dev1)
check("bus", "usb", "baz", "usb")
@ -899,7 +899,7 @@ class XMLParseTest(unittest.TestCase):
def testAlterTPM(self):
guest, outfile = self._get_test_content("change-tpm")
dev1 = guest.get_devices("tpm")[0]
dev1 = guest.devices.tpm[0]
check = self._make_checker(dev1)
check("type", "passthrough", "foo", "passthrough")
@ -911,7 +911,7 @@ class XMLParseTest(unittest.TestCase):
def testAlterRNG_EGD(self):
guest, outfile = self._get_test_content("change-rng-egd")
dev1 = guest.get_devices("rng")[0]
dev1 = guest.devices.rng[0]
check = self._make_checker(dev1)
check("type", "egd")
@ -930,7 +930,7 @@ class XMLParseTest(unittest.TestCase):
def testAlterRNG_Random(self):
guest, outfile = self._get_test_content("change-rng-random")
dev1 = guest.get_devices("rng")[0]
dev1 = guest.devices.rng[0]
check = self._make_checker(dev1)
check("type", "random", "random")
@ -942,7 +942,7 @@ class XMLParseTest(unittest.TestCase):
def testConsoleCompat(self):
guest, outfile = self._get_test_content("console-compat")
dev1 = guest.get_devices("console")[0]
dev1 = guest.devices.console[0]
check = self._make_checker(dev1)
check("source_path", "/dev/pts/4")
check("_tty", "/dev/pts/4", "foo", "/dev/pts/4")
@ -952,7 +952,7 @@ class XMLParseTest(unittest.TestCase):
def testPanicDevice(self):
guest, outfile = self._get_test_content("change-panic-device")
dev1 = guest.get_devices("panic")[0]
dev1 = guest.devices.panic[0]
check = self._make_checker(dev1)
check("type", "isa", None, "isa")
@ -988,7 +988,7 @@ class XMLParseTest(unittest.TestCase):
guest, outfile = self._get_test_content("add-devices")
# Basic removal of existing device
rmdev = guest.get_devices("disk")[2]
rmdev = guest.devices.disk[2]
guest.remove_device(rmdev)
# Basic device add
@ -1015,28 +1015,28 @@ class XMLParseTest(unittest.TestCase):
def testChangeKVMMedia(self):
guest, outfile = self._get_test_content("change-media", kvm=True)
disk = guest.get_devices("disk")[0]
disk = guest.devices.disk[0]
check = self._make_checker(disk)
check("path", None, "/dev/default-pool/default-vol")
disk.sync_path_props()
disk = guest.get_devices("disk")[1]
disk = guest.devices.disk[1]
check = self._make_checker(disk)
check("path", None, "/dev/default-pool/default-vol")
check("path", "/dev/default-pool/default-vol", "/dev/disk-pool/diskvol1")
disk.sync_path_props()
disk = guest.get_devices("disk")[2]
disk = guest.devices.disk[2]
check = self._make_checker(disk)
check("path", None, "/dev/disk-pool/diskvol1")
disk.sync_path_props()
disk = guest.get_devices("disk")[3]
disk = guest.devices.disk[3]
check = self._make_checker(disk)
check("path", None, "/dev/default-pool/default-vol")
disk.sync_path_props()
disk = guest.get_devices("disk")[4]
disk = guest.devices.disk[4]
check = self._make_checker(disk)
check("path", None, "/dev/disk-pool/diskvol1")
disk.sync_path_props()

View File

@ -31,7 +31,7 @@ def install_specified(location, cdpath, pxe, import_install):
def cdrom_specified(guest, disk=None):
disks = guest.get_devices("disk")
disks = guest.devices.disk
for d in disks:
if d.device == virtinst.DeviceDisk.DEVICE_CDROM:
@ -50,7 +50,7 @@ def supports_pxe(guest):
"""
Return False if we are pretty sure the config doesn't support PXE
"""
for nic in guest.get_devices("interface"):
for nic in guest.devices.interface:
if nic.type == nic.TYPE_USER:
continue
if nic.type != nic.TYPE_VIRTUAL:
@ -477,7 +477,7 @@ def check_option_collisions(options, guest):
def _show_nographics_warnings(options, guest):
if guest.get_devices("graphics"):
if guest.devices.graphics:
return
if not options.autoconsole:
return
@ -495,7 +495,7 @@ def _show_nographics_warnings(options, guest):
# Trying --location --nographics with console connect. Warn if
# they likely won't see any output.
if not guest.get_devices("console"):
if not guest.devices.console:
logging.warning(_("No --console device added, you likely will not "
"see text install output from the guest."))
return
@ -507,7 +507,7 @@ def _show_nographics_warnings(options, guest):
console_type = serial_arg
if guest.os.is_arm():
console_type = serial_arm_arg
if guest.get_devices("console")[0].target_type in ["virtio", "xen"]:
if guest.devices.console[0].target_type in ["virtio", "xen"]:
console_type = hvc_arg
if guest.os.is_ppc64() or guest.os.is_arm_machvirt():
# Later arm/ppc kernels figure out console= automatically, so don't
@ -600,7 +600,7 @@ def build_guest_instance(conn, options):
cli.parse_option_strings(options, guest, None)
# Extra disk validation
for disk in guest.get_devices("disk"):
for disk in guest.devices.disk:
cli.validate_disk(disk)
set_install_media(guest, options.location, options.cdrom,

View File

@ -92,7 +92,10 @@ def get_domain_and_guest(conn, domstr):
################
def _find_objects_to_edit(guest, action_name, editval, parserclass):
objlist = guest.list_children_for_class(parserclass.objclass)
if issubclass(parserclass.objclass, virtinst.Device):
objlist = guest.devices.list_children_for_class(parserclass.objclass)
else:
objlist = guest.list_children_for_class(parserclass.objclass)
idx = None
if editval is None:
@ -179,16 +182,22 @@ def action_edit(guest, options, parserclass):
return cli.parse_option_strings(options, guest, inst, update=True)
def _is_singleton(guest, objclass):
if not objclass:
return True
if issubclass(objclass, virtinst.devices.Device):
return False
return guest.child_class_is_singleton(objclass)
def action_add_device(guest, options, parserclass):
if (not parserclass.objclass or
guest.child_class_is_singleton(parserclass.objclass)):
if _is_singleton(guest, parserclass.objclass):
fail(_("Cannot use --add-device with --%s") % parserclass.cli_arg_name)
return cli.parse_option_strings(options, guest, None)
def action_remove_device(guest, options, parserclass):
if (not parserclass.objclass or
guest.child_class_is_singleton(parserclass.objclass)):
if _is_singleton(guest, parserclass.objclass):
fail(_("Cannot use --remove-device with --%s") %
parserclass.cli_arg_name)

View File

@ -83,7 +83,7 @@ def _mark_vmm_device(dev):
def _get_vmm_device(guest, devkey):
for dev in guest.get_devices(devkey):
for dev in getattr(guest.devices, devkey):
if hasattr(dev, "vmm_create_wizard_device"):
return dev
@ -1187,8 +1187,8 @@ class vmmCreate(vmmGObjectUI):
if not path:
path = disk.path
storagepath = (storagetmpl % path)
elif len(self._guest.get_devices("filesystem")):
fs = self._guest.get_devices("filesystem")[0]
elif len(self._guest.devices.filesystem):
fs = self._guest.devices.filesystem[0]
storagepath = storagetmpl % fs.source
elif self._guest.os.is_container():
storagepath = _("Host filesystem")
@ -2543,7 +2543,7 @@ class vmmCreate(vmmGObjectUI):
# Build a list of pools we should refresh, if we are creating storage
refresh_pools = []
for disk in guest.get_devices("disk"):
for disk in guest.devices.disk:
if not disk.wants_storage_creation():
continue

View File

@ -71,7 +71,7 @@ def compare_device(origdev, newdev, idx):
def _find_device(guest, origdev):
devlist = guest.get_devices(origdev.virtual_device_type)
devlist = getattr(guest.devices, origdev.virtual_device_type)
for idx, dev in enumerate(devlist):
if compare_device(origdev, dev, idx):
return dev
@ -914,7 +914,7 @@ class vmmDomain(vmmLibvirtObject):
def _change_model():
if editdev.type == "usb":
ctrls = xmlobj.get_devices("controller")
ctrls = xmlobj.devices.controller
ctrls = [x for x in ctrls if (x.type ==
DeviceController.TYPE_USB)]
for dev in ctrls:
@ -1277,7 +1277,7 @@ class vmmDomain(vmmLibvirtObject):
refresh_if_nec=True, inactive=False):
guest = self.get_xmlobj(refresh_if_nec=refresh_if_nec,
inactive=inactive)
devs = guest.get_devices(device_type)
devs = getattr(guest.devices, device_type)
for idx, dev in enumerate(devs):
dev.vmmindex = idx
@ -1857,7 +1857,7 @@ class vmmDomain(vmmLibvirtObject):
return
# Only works for virtio balloon
if not any([b for b in self.get_xmlobj().get_devices("memballoon") if
if not any([b for b in self.get_xmlobj().devices.memballoon if
b.model == "virtio"]):
return

View File

@ -254,7 +254,7 @@ class vmmGraphicsDetails(vmmGObjectUI):
if opengl_warning:
pass
elif not [v for v in self.vm.xmlobj.get_devices("video") if
elif not [v for v in self.vm.xmlobj.devices.video if
(v.model == "virtio" and v.accel3d)]:
opengl_warning = _("Spice GL requires "
"virtio graphics configured with accel3d.")

View File

@ -292,7 +292,7 @@ class VirtConverter(object):
destdir = StoragePool.get_default_dir(self.conn, build=not dry)
guest = self.get_guest()
for disk in guest.get_devices("disk"):
for disk in guest.devices.disk:
if disk.device != "disk":
continue

View File

@ -28,8 +28,6 @@ from .domain import * # pylint: disable=wildcard-import
from .nodedev import NodeDevice
from .storage import StoragePool, StorageVolume
_ignore = Device
##########################
# Global option handling #
@ -409,7 +407,7 @@ def _gfx_console(guest):
args.append("--attach")
logging.debug("Launching virt-viewer for graphics type '%s'",
guest.get_devices("graphics")[0].type)
guest.devices.graphics[0].type)
return _run_console(guest, args)
@ -442,7 +440,7 @@ def connect_console(guest, consolecb, wait):
def get_console_cb(guest):
gdevs = guest.get_devices("graphics")
gdevs = guest.devices.graphics
if not gdevs:
return _txt_console
@ -1183,7 +1181,8 @@ class VirtCLIParser(object):
new_object = False
if self.objclass and not inst:
if self.guest.child_class_is_singleton(self.objclass):
if (not issubclass(self.objclass, Device) and
self.guest.child_class_is_singleton(self.objclass)):
inst = self.guest.list_children_for_class(self.objclass)[0]
else:
new_object = True
@ -1198,7 +1197,10 @@ class VirtCLIParser(object):
break
if validate:
obj.validate()
self.guest.add_child(obj)
if isinstance(obj, Device):
self.guest.add_device(obj)
else:
self.guest.add_child(obj)
ret += util.listify(objs)
except Exception as e:
@ -1218,7 +1220,10 @@ class VirtCLIParser(object):
Used only by virt-xml --edit lookups
"""
ret = []
objlist = self.guest.list_children_for_class(self.objclass)
if issubclass(self.objclass, Device):
objlist = self.guest.devices.list_children_for_class(self.objclass)
else:
objlist = self.guest.list_children_for_class(self.objclass)
try:
for inst in objlist:
@ -1958,7 +1963,7 @@ def _get_default_image_format(conn, poolobj):
def _generate_new_volume_name(guest, poolobj, fmt):
collidelist = []
for disk in guest.get_devices("disk"):
for disk in guest.devices.disk:
if (disk.get_vol_install() and
disk.get_vol_install().pool.name() == poolobj.name()):
collidelist.append(os.path.basename(disk.path))
@ -2069,7 +2074,7 @@ class ParserDisk(VirtCLIParser):
inst.set_vol_install(vol_install)
if not inst.target:
skip_targets = [d.target for d in self.guest.get_devices("disk")]
skip_targets = [d.target for d in self.guest.devices.disk]
inst.generate_target(skip_targets)
inst.cli_generated_target = True

View File

@ -391,14 +391,14 @@ class Cloner(object):
self._guest.name = self._clone_name
self._guest.uuid = self._clone_uuid
self._clone_macs.reverse()
for dev in self._guest.get_devices("graphics"):
for dev in self._guest.devices.graphics:
if dev.port and dev.port != -1:
logging.warning(_("Setting the graphics device port to autoport, "
"in order to avoid conflicting."))
dev.port = -1
clone_macs = self._clone_macs[:]
for iface in self._guest.get_devices("interface"):
for iface in self._guest.devices.interface:
iface.target_dev = None
if clone_macs:
@ -411,7 +411,7 @@ class Cloner(object):
for i, orig_disk in enumerate(self._original_disks):
clone_disk = self._clone_disks[i]
for disk in self._guest.get_devices("disk"):
for disk in self._guest.devices.disk:
if disk.target == orig_disk.target:
xmldisk = disk
@ -426,7 +426,7 @@ class Cloner(object):
# For guest agent channel, remove a path to generate a new one with
# new guest name
for channel in self._guest.get_devices("channel"):
for channel in self._guest.devices.channel:
if channel.type == DeviceChannel.TYPE_UNIX:
channel.source_path = None
@ -528,7 +528,7 @@ class Cloner(object):
clonelist = []
retdisks = []
for disk in self._guest.get_devices("disk"):
for disk in self._guest.devices.disk:
if self._do_we_clone_device(disk):
clonelist.append(disk)
continue

View File

@ -351,7 +351,7 @@ class DeviceDisk(Device):
ret.append(vm.name)
continue
for disk in vm.get_devices("disk"):
for disk in vm.devices.disk:
if disk.path in vols and vm.name not in ret:
# VM uses the path indirectly via backing store
ret.append(vm.name)

View File

@ -174,7 +174,7 @@ class DeviceInterface(Device):
vms = conn.fetch_all_guests()
for vm in vms:
for nic in vm.get_devices("interface"):
for nic in vm.devices.interface:
nicmac = nic.macaddr or ""
if nicmac.lower() == searchmac.lower():
return (True, _("The MAC address '%s' is in use "

View File

@ -16,9 +16,7 @@ from virtcli import CLIConfig
from . import util
from . import support
from .devices import (Device, DeviceChannel, DeviceConsole, DeviceController,
DeviceDisk, DeviceInput, DeviceGraphics, DevicePanic, DeviceRedirdev,
DeviceRng, DeviceSound, DeviceVideo)
from .devices import * # pylint: disable=wildcard-import
from .distroinstaller import DistroInstaller
from .domain import * # pylint: disable=wildcard-import
from .domcapabilities import DomainCapabilities
@ -26,6 +24,34 @@ from .osdict import OSDB
from .xmlbuilder import XMLBuilder, XMLProperty, XMLChildProperty
class _DomainDevices(XMLBuilder):
_XML_ROOT_NAME = "devices"
_XML_PROP_ORDER = Device.virtual_device_types[:]
disk = XMLChildProperty(DeviceDisk)
controller = XMLChildProperty(DeviceController)
filesystem = XMLChildProperty(DeviceFilesystem)
interface = XMLChildProperty(DeviceInterface)
smartcard = XMLChildProperty(DeviceSmartcard)
serial = XMLChildProperty(DeviceSerial)
parallel = XMLChildProperty(DeviceParallel)
console = XMLChildProperty(DeviceConsole)
channel = XMLChildProperty(DeviceChannel)
input = XMLChildProperty(DeviceInput)
tpm = XMLChildProperty(DeviceTpm)
graphics = XMLChildProperty(DeviceGraphics)
sound = XMLChildProperty(DeviceSound)
video = XMLChildProperty(DeviceVideo)
hostdev = XMLChildProperty(DeviceHostdev)
redirdev = XMLChildProperty(DeviceRedirdev)
watchdog = XMLChildProperty(DeviceWatchdog)
memballoon = XMLChildProperty(DeviceMemballoon)
rng = XMLChildProperty(DeviceRng)
panic = XMLChildProperty(DevicePanic)
memory = XMLChildProperty(DeviceMemory)
class Guest(XMLBuilder):
@staticmethod
def check_vm_collision(conn, name, do_remove):
@ -73,11 +99,13 @@ class Guest(XMLBuilder):
_XML_ROOT_NAME = "domain"
_XML_PROP_ORDER = ["type", "name", "uuid", "title", "description",
"hotplugmemorymax", "hotplugmemoryslots", "maxmemory", "memory", "blkiotune",
"memtune", "memoryBacking", "vcpus", "curvcpus", "vcpu_placement",
"cpuset", "numatune", "resource", "sysinfo", "bootloader", "os", "idmap",
"features", "cpu", "clock", "on_poweroff", "on_reboot", "on_crash",
"pm", "emulator", "_devices", "seclabels"]
"hotplugmemorymax", "hotplugmemoryslots", "maxmemory", "memory",
"blkiotune", "memtune", "memoryBacking",
"vcpus", "curvcpus", "vcpu_placement",
"cpuset", "numatune", "resource", "sysinfo",
"bootloader", "os", "idmap", "features", "cpu", "clock",
"on_poweroff", "on_reboot", "on_crash",
"pm", "emulator", "devices", "seclabels"]
def __init__(self, *args, **kwargs):
XMLBuilder.__init__(self, *args, **kwargs)
@ -224,39 +252,10 @@ class Guest(XMLBuilder):
########################################
def add_device(self, dev):
"""
Add the passed device to the guest's device list.
:param dev: Device instance to attach to guest
"""
self.add_child(dev)
self.devices.add_child(dev)
def remove_device(self, dev):
"""
Remove the passed device from the guest's device list
:param dev: Device instance
"""
self.remove_child(dev)
def get_devices(self, devtype):
"""
Return a list of devices of type 'devtype' that will installed on
the guest.
:param devtype: Device type to search for (one of
Device.virtual_device_types)
"""
newlist = []
for i in self._devices:
if devtype == "all" or i.virtual_device_type == devtype:
newlist.append(i)
return newlist
_devices = XMLChildProperty(
[Device.virtual_device_classes[_n]
for _n in Device.virtual_device_types],
relative_xpath="./devices")
self.devices.remove_child(dev)
def get_all_devices(self):
"""
@ -264,9 +263,11 @@ class Guest(XMLBuilder):
"""
retlist = []
for devtype in Device.virtual_device_types:
retlist.extend(self.get_devices(devtype))
retlist.extend(getattr(self.devices, devtype))
return retlist
devices = XMLChildProperty(_DomainDevices, is_single=True)
############################
# Install Helper functions #
@ -464,7 +465,7 @@ class Guest(XMLBuilder):
self.installer.cleanup()
def get_created_disks(self):
return [d for d in self.get_devices("disk") if d.storage_was_created]
return [d for d in self.devices.disk if d.storage_was_created]
def cleanup_created_disks(self, meter):
"""
@ -574,7 +575,7 @@ class Guest(XMLBuilder):
return self.conn.stable_defaults(self.emulator, *args, **kwargs)
def _usb_disabled(self):
controllers = [c for c in self.get_devices("controller") if
controllers = [c for c in self.devices.controller if
c.type == "usb"]
if not controllers:
return False
@ -583,9 +584,9 @@ class Guest(XMLBuilder):
def add_default_input_device(self):
if self.os.is_container():
return
if self.get_devices("input"):
if self.devices.input:
return
if not self.get_devices("graphics"):
if not self.devices.graphics:
return
if self._usb_disabled():
return
@ -612,7 +613,7 @@ class Guest(XMLBuilder):
def add_default_console_device(self):
if self.skip_default_console:
return
if self.get_devices("console") or self.get_devices("serial"):
if self.devices.console or self.devices.serial:
return
dev = DeviceConsole(self.conn)
@ -624,16 +625,16 @@ class Guest(XMLBuilder):
def add_default_video_device(self):
if self.os.is_container():
return
if self.get_devices("video"):
if self.devices.video:
return
if not self.get_devices("graphics"):
if not self.devices.graphics:
return
self.add_device(DeviceVideo(self.conn))
def add_default_usb_controller(self):
if self.os.is_container():
return
if any([d.type == "usb" for d in self.get_devices("controller")]):
if any([d.type == "usb" for d in self.devices.controller]):
return
usb2 = False
@ -663,7 +664,7 @@ class Guest(XMLBuilder):
def add_default_channels(self):
if self.skip_default_channel:
return
if self.get_devices("channel"):
if self.devices.channel:
return
if self.os.is_s390x():
# Not wanted for s390 apparently
@ -681,7 +682,7 @@ class Guest(XMLBuilder):
def add_default_graphics(self):
if self.skip_default_graphics:
return
if self.get_devices("graphics"):
if self.devices.graphics:
return
if self.os.is_container() and not self.conn.is_vz():
return
@ -692,7 +693,7 @@ class Guest(XMLBuilder):
def add_default_rng(self):
if self.skip_default_rng:
return
if self.get_devices("rng"):
if self.devices.rng:
return
if not (self.os.is_x86() or
self.os.is_arm_machvirt() or
@ -729,7 +730,7 @@ class Guest(XMLBuilder):
self.add_device(dev)
def _remove_cdrom_install_media(self):
for dev in self.get_devices("disk"):
for dev in self.devices.disk:
# Keep the install cdrom device around, but with no media attached.
# But only if we are installing windows which has a multi stage
# install.
@ -763,7 +764,7 @@ class Guest(XMLBuilder):
def _is_full_os_container(self):
if not self.os.is_container():
return False
for fs in self.get_devices("filesystem"):
for fs in self.devices.filesystem:
if fs.target == "/":
return True
return False
@ -956,7 +957,7 @@ class Guest(XMLBuilder):
has_spapr_scsi = False
has_virtio_scsi = False
has_any_scsi = False
for dev in self.get_devices("controller"):
for dev in self.devices.controller:
if dev.type == "scsi":
has_any_scsi = True
if dev.address.type == "spapr-vio":
@ -966,7 +967,7 @@ class Guest(XMLBuilder):
# Add spapr-vio controller if needed
if not has_spapr_scsi:
for dev in self.get_devices("disk"):
for dev in self.devices.disk:
if dev.address.type == "spapr-vio":
ctrl = DeviceController(self.conn)
ctrl.type = "scsi"
@ -978,7 +979,7 @@ class Guest(XMLBuilder):
if ((self.os.is_arm_machvirt() or self.os.is_pseries()) and
not has_any_scsi and
not has_virtio_scsi):
for dev in self.get_devices("disk"):
for dev in self.devices.disk:
if dev.bus == "scsi":
ctrl = DeviceController(self.conn)
ctrl.type = "scsi"
@ -1036,7 +1037,7 @@ class Guest(XMLBuilder):
return False
def _set_disk_defaults(self):
disks = self.get_devices("disk")
disks = self.devices.disk
def set_disk_bus(d):
if d.is_floppy():
@ -1090,7 +1091,7 @@ class Guest(XMLBuilder):
net_model = self._os_object.default_netmodel()
if net_model:
for net in self.get_devices("interface"):
for net in self.devices.interface:
if not net.model:
net.model = net_model
@ -1104,7 +1105,7 @@ class Guest(XMLBuilder):
else:
default = "es1370"
for sound in self.get_devices("sound"):
for sound in self.devices.sound:
if sound.model == sound.MODEL_DEFAULT:
sound.model = default
@ -1122,7 +1123,7 @@ class Guest(XMLBuilder):
gfx.type = gtype
for dev in self.get_devices("graphics"):
for dev in self.devices.graphics:
if dev.type == "default":
_set_type(dev)
@ -1155,7 +1156,7 @@ class Guest(XMLBuilder):
if self.skip_default_channel:
return
for chn in self.get_devices("channel"):
for chn in self.devices.channel:
if chn.type == chn.TYPE_SPICEVMC:
return
@ -1167,7 +1168,7 @@ class Guest(XMLBuilder):
def _add_spice_sound(self):
if self.skip_default_sound:
return
if self.get_devices("sound"):
if self.devices.sound:
return
if not self.os.is_hvm():
return
@ -1180,7 +1181,7 @@ class Guest(XMLBuilder):
def _add_spice_usbredir(self):
if self.skip_default_usbredir:
return
if self.get_devices("redirdev"):
if self.devices.redirdev:
return
if not self.os.is_x86():
return
@ -1197,17 +1198,17 @@ class Guest(XMLBuilder):
self.add_device(dev)
def has_spice(self):
for gfx in self.get_devices("graphics"):
for gfx in self.devices.graphics:
if gfx.type == gfx.TYPE_SPICE:
return True
def has_gl(self):
for gfx in self.get_devices("graphics"):
for gfx in self.devices.graphics:
if gfx.gl:
return True
def has_listen_none(self):
for gfx in self.get_devices("graphics"):
for gfx in self.devices.graphics:
listen = gfx.get_first_listen_type()
if listen and listen == "none":
return True
@ -1223,13 +1224,13 @@ class Guest(XMLBuilder):
if self.os.is_arm_machvirt():
video_model = "virtio"
for video in self.get_devices("video"):
for video in self.devices.video:
if video.model == video.MODEL_DEFAULT:
video.model = video_model
if video.model == 'virtio' and self.has_gl():
video.accel3d = True
def _set_panic_defaults(self):
for panic in self.get_devices("panic"):
for panic in self.devices.panic:
if panic.model == DevicePanic.MODEL_DEFAULT:
panic.model = DevicePanic.get_default_model(self.os)

View File

@ -79,7 +79,7 @@ class Installer(object):
# If guest has an attached disk, always have 'hd' in the boot
# list, so disks are marked as bootable/installable (needed for
# windows virtio installs, and booting local disk from PXE)
for disk in guest.get_devices("disk"):
for disk in guest.devices.disk:
if disk.device == disk.DEVICE_DISK:
bootdev = "hd"
if bootdev not in bootorder:
@ -222,7 +222,7 @@ class PXEInstaller(Installer):
bootdev = DomainOs.BOOT_DEVICE_NETWORK
if (not isinstall and
[d for d in guest.get_devices("disk") if
[d for d in guest.devices.disk if
d.device == d.DEVICE_DISK]):
# If doing post-install boot and guest has an HD attached
bootdev = DomainOs.BOOT_DEVICE_HARDDISK
@ -235,7 +235,7 @@ class ImportInstaller(Installer):
# Private methods
def _get_bootdev(self, isinstall, guest):
disks = guest.get_devices("disk")
disks = guest.devices.disk
if not disks:
return DomainOs.BOOT_DEVICE_HARDDISK
return self._disk_to_bootdev(disks[0])