mirror of
https://github.com/virt-manager/virt-manager.git
synced 2025-01-11 05:17:59 +03:00
domain: Add vmmDomainVirtinst class.
A domain class backed by a virtinst Guest, this allows for customizing a VM before installing.
This commit is contained in:
parent
d99c04b02a
commit
e788fdad23
@ -25,9 +25,11 @@ import logging
|
||||
import time
|
||||
import difflib
|
||||
|
||||
import virtinst
|
||||
from virtManager import util
|
||||
import virtinst.util as vutil
|
||||
import virtinst.support as support
|
||||
from virtinst import VirtualDevice
|
||||
|
||||
def safeint(val, fmt="%.3d"):
|
||||
try:
|
||||
@ -1873,5 +1875,290 @@ class vmmDomain(vmmDomainBase):
|
||||
self._update_status(info[0])
|
||||
gobject.idle_add(util.idle_emit, self, "resources-sampled")
|
||||
|
||||
|
||||
class vmmDomainVirtinst(vmmDomainBase):
|
||||
"""
|
||||
Domain object backed by a virtinst Guest object.
|
||||
|
||||
Used for launching a details window for customizing a VM before install.
|
||||
"""
|
||||
def __init__(self, config, connection, backend, uuid):
|
||||
vmmDomainBase.__init__(self, config, connection, backend, uuid)
|
||||
|
||||
def get_name(self):
|
||||
return self._backend.name
|
||||
def get_id(self):
|
||||
return -1
|
||||
def status(self):
|
||||
return libvirt.VIR_DOMAIN_SHUTOFF
|
||||
|
||||
def get_xml(self):
|
||||
return self._backend.get_config_xml()
|
||||
def refresh_xml(self):
|
||||
# No caching, so no refresh needed
|
||||
return
|
||||
def _get_inactive_xml(self):
|
||||
return self.get_xml()
|
||||
|
||||
def get_autostart(self):
|
||||
return self._backend.autostart
|
||||
|
||||
def get_memory(self):
|
||||
return int(self._backend.memory * 1024.0)
|
||||
def get_memory_percentage(self):
|
||||
return 0
|
||||
def maximum_memory(self):
|
||||
return int(self._backend.maxmemory * 1024.0)
|
||||
def maximum_memory_percentage(self):
|
||||
return 0
|
||||
def cpu_time(self):
|
||||
return 0
|
||||
def cpu_time_percentage(self):
|
||||
return 0
|
||||
def vcpu_count(self):
|
||||
return self._backend.vcpus
|
||||
def network_rx_rate(self):
|
||||
return 0
|
||||
def network_tx_rate(self):
|
||||
return 0
|
||||
def disk_read_rate(self):
|
||||
return 0
|
||||
def disk_write_rate(self):
|
||||
return 0
|
||||
|
||||
|
||||
# Device/XML altering implementations
|
||||
def set_autostart(self, val):
|
||||
self._backend.autostart = bool(val)
|
||||
self.emit("config-changed")
|
||||
|
||||
def attach_device(self, devobj):
|
||||
return
|
||||
def detach_device(self, devtype, dev_id_info):
|
||||
return
|
||||
|
||||
def add_device(self, devobj):
|
||||
def add_dev():
|
||||
self._backend.add_device(devobj)
|
||||
self._redefine(add_dev)
|
||||
def remove_device(self, dev_type, dev_id_info):
|
||||
dev = self._get_device_xml_object(dev_type, dev_id_info)
|
||||
|
||||
def rm_dev():
|
||||
self._backend.remove_device(dev)
|
||||
self._redefine(rm_dev)
|
||||
|
||||
def define_storage_media(self, dev_id_info, newpath, _type=None):
|
||||
dev = self._get_device_xml_object(VirtualDevice.VIRTUAL_DEV_DISK,
|
||||
dev_id_info)
|
||||
|
||||
def change_path():
|
||||
dev.path = newpath
|
||||
self._redefine(change_path)
|
||||
def hotplug_storage_media(self, dev_id_info, newpath, _type=None):
|
||||
return
|
||||
|
||||
def define_vcpus(self, vcpus):
|
||||
def change_vcpu():
|
||||
self._backend.vcpus = int(vcpus)
|
||||
self._redefine(change_vcpu)
|
||||
def hotplug_vcpus(self, vcpus):
|
||||
return
|
||||
def define_cpuset(self, cpuset):
|
||||
def change_cpuset():
|
||||
self._backend.cpuset = cpuset
|
||||
self._redefine(change_cpuset)
|
||||
|
||||
def define_both_mem(self, memory, maxmem):
|
||||
def change_mem():
|
||||
self._backend.memory = int(int(memory) / 1024)
|
||||
self._backend.maxmemory = int(int(maxmem) / 1024)
|
||||
self._redefine(change_mem)
|
||||
def hotplug_both_mem(self, memory, maxmem):
|
||||
return
|
||||
|
||||
def define_seclabel(self, model, t, label):
|
||||
def change_seclabel():
|
||||
if not model:
|
||||
self._backend.seclabel = None
|
||||
return
|
||||
|
||||
seclabel = virtinst.Seclabel(self.get_connection().vmm)
|
||||
seclabel.type = t
|
||||
seclabel.model = model
|
||||
if label:
|
||||
seclabel.label = label
|
||||
|
||||
self._backend.seclabel = seclabel
|
||||
|
||||
self._redefine(change_seclabel)
|
||||
|
||||
def set_boot_device(self, boot_type):
|
||||
if not boot_type or boot_type == self.get_boot_device():
|
||||
return
|
||||
|
||||
raise RuntimeError("Boot device is determined by the install media.")
|
||||
|
||||
def define_acpi(self, newvalue):
|
||||
def change_acpi():
|
||||
self._backend.features["acpi"] = bool(newvalue)
|
||||
self._redefine(change_acpi)
|
||||
def define_apic(self, newvalue):
|
||||
def change_apic():
|
||||
self._backend.features["apic"] = bool(newvalue)
|
||||
self._redefine(change_apic)
|
||||
|
||||
def define_clock(self, newvalue):
|
||||
def change_clock():
|
||||
self._backend.clock.offset = newvalue
|
||||
self._redefine(change_clock)
|
||||
|
||||
def define_disk_readonly(self, dev_id_info, do_readonly):
|
||||
dev = self._get_device_xml_object(VirtualDevice.VIRTUAL_DEV_DISK,
|
||||
dev_id_info)
|
||||
|
||||
def change_readonly():
|
||||
dev.read_only = do_readonly
|
||||
self._redefine(change_readonly)
|
||||
def define_disk_shareable(self, dev_id_info, do_shareable):
|
||||
dev = self._get_device_xml_object(VirtualDevice.VIRTUAL_DEV_DISK,
|
||||
dev_id_info)
|
||||
|
||||
def change_shareable():
|
||||
dev.shareable = do_shareable
|
||||
self._redefine(change_shareable)
|
||||
|
||||
def define_video_model(self, dev_id_info, newmodel):
|
||||
dev = self._get_device_xml_object(VirtualDevice.VIRTUAL_DEV_VIDEO,
|
||||
dev_id_info)
|
||||
|
||||
def change_video_model():
|
||||
dev.model_type = newmodel
|
||||
self._redefine(change_video_model)
|
||||
|
||||
# Helper functions
|
||||
def _redefine(self, alter_func):
|
||||
origxml = self.get_xml()
|
||||
|
||||
# Make change
|
||||
alter_func()
|
||||
|
||||
newxml = self.get_xml()
|
||||
|
||||
if origxml == newxml:
|
||||
logging.debug("Redefinition request XML was no different,"
|
||||
" redefining anyways")
|
||||
else:
|
||||
diff = "".join(difflib.unified_diff(origxml.splitlines(1),
|
||||
newxml.splitlines(1),
|
||||
fromfile="Original XML",
|
||||
tofile="New XML"))
|
||||
logging.debug("Redefining '%s' with XML diff:\n%s",
|
||||
self.get_name(), diff)
|
||||
|
||||
self.emit("config-changed")
|
||||
|
||||
def _get_device_xml_object(self, dev_type, dev_id_info):
|
||||
"""
|
||||
Find the virtinst device for the passed id info
|
||||
"""
|
||||
def device_iter(try_func):
|
||||
devs = self._backend.get_devices(dev_type)
|
||||
for dev in devs:
|
||||
if try_func(dev):
|
||||
return dev
|
||||
|
||||
def count_func(count):
|
||||
devs = self._backend.get_devices(dev_type)
|
||||
tmpcount = -1
|
||||
for dev in devs:
|
||||
tmpcount += 1
|
||||
if count == tmpcount:
|
||||
return dev
|
||||
return None
|
||||
|
||||
found_func = None
|
||||
count = None
|
||||
|
||||
if dev_type == VirtualDevice.VIRTUAL_DEV_NET:
|
||||
found_func = (lambda x: x.macaddr == dev_id_info)
|
||||
|
||||
elif dev_type == VirtualDevice.VIRTUAL_DEV_DISK:
|
||||
found_func = (lambda x: x.target == dev_id_info)
|
||||
|
||||
elif dev_type == VirtualDevice.VIRTUAL_DEV_INPUT:
|
||||
found_func = (lambda x: (x.type == dev_id_info[0] and
|
||||
x.bus == dev_id_info[1]))
|
||||
|
||||
elif dev_type == VirtualDevice.VIRTUAL_DEV_GRAPHICS:
|
||||
found_func = (lambda x: x.type == dev_id_info)
|
||||
|
||||
elif dev_type == VirtualDevice.VIRTUAL_DEV_AUDIO:
|
||||
found_func = (lambda x: x.model == dev_id_info)
|
||||
|
||||
elif (dev_type == VirtualDevice.VIRTUAL_DEV_PARALLEL or
|
||||
dev_type == VirtualDevice.VIRTUAL_DEV_SERIAL or
|
||||
dev_type == VirtualDevice.VIRTUAL_DEV_CONSOLE):
|
||||
count = int(dev_id_info)
|
||||
|
||||
elif dev_type == VirtualDevice.VIRTUAL_DEV_HOSTDEV:
|
||||
# This whole process is a little funky, since we need a decent
|
||||
# amount of info to determine which specific hostdev to remove
|
||||
|
||||
def found_func(rmdev):
|
||||
host_type = dev_id_info["type"]
|
||||
addr = dev_id_info.get("address")
|
||||
vend = dev_id_info.get("vendor")
|
||||
prod = dev_id_info.get("product")
|
||||
|
||||
if rmdev.type != host_type:
|
||||
return False
|
||||
|
||||
if addr:
|
||||
bus = addr.get("bus")
|
||||
dev = addr.get("device")
|
||||
slot = addr.get("slot")
|
||||
funct = addr.get("function")
|
||||
dom = addr.get("domain")
|
||||
|
||||
if bus and dev:
|
||||
return (rmdev.bus == bus and rmdev.device == dev)
|
||||
|
||||
elif bus and slot and funct and dom:
|
||||
return (rmdev.bus == bus and
|
||||
rmdev.slot == slot and
|
||||
rmdev.function == funct and
|
||||
rmdev.domain == dom)
|
||||
|
||||
elif vend.get("id") and prod.get("id"):
|
||||
return (rmdev.vendor == vend.get("id") and
|
||||
rmdev.product == prod.get("id"))
|
||||
|
||||
return False
|
||||
|
||||
|
||||
elif dev_type == VirtualDevice.VIRTUAL_DEV_VIDEO:
|
||||
model, ram, heads = dev_id_info
|
||||
|
||||
def found_func(rmdev):
|
||||
return (rmdev.model_type == model and
|
||||
rmdev.vram == ram and
|
||||
rmdev.heads == heads)
|
||||
|
||||
else:
|
||||
raise RuntimeError(_("Unknown device type '%s'") % dev_type)
|
||||
|
||||
if count != None:
|
||||
# We are looking up devices by a simple index
|
||||
found_dev = count_func(count)
|
||||
else:
|
||||
found_dev = device_iter(found_func)
|
||||
|
||||
if not found_dev:
|
||||
raise RuntimeError(_("Did not find selected device."))
|
||||
|
||||
return found_dev
|
||||
|
||||
gobject.type_register(vmmDomainVirtinst)
|
||||
gobject.type_register(vmmDomainBase)
|
||||
gobject.type_register(vmmDomain)
|
||||
|
Loading…
Reference in New Issue
Block a user