mirror of
https://github.com/virt-manager/virt-manager.git
synced 2025-01-18 06:03:58 +03:00
virtinst: move UI only functions into virtManager
These throw off code coverage testing. They are mostly: * pretty* device helpers * network + snapshot validation + creation routines
This commit is contained in:
parent
c9233aa6c3
commit
b5a664bd1b
@ -48,7 +48,6 @@ class TestNodeDev(unittest.TestCase):
|
|||||||
dev = NodeDevice(self.conn, funky_chars_xml)
|
dev = NodeDevice(self.conn, funky_chars_xml)
|
||||||
self.assertEqual(dev.name, "L3B2616")
|
self.assertEqual(dev.name, "L3B2616")
|
||||||
self.assertEqual(dev.device_type, "LENOVO")
|
self.assertEqual(dev.device_type, "LENOVO")
|
||||||
self.assertEqual(dev.pretty_name(), dev.name)
|
|
||||||
|
|
||||||
def testNetDevice(self):
|
def testNetDevice(self):
|
||||||
devname = "net_00_1c_25_10_b1_e4"
|
devname = "net_00_1c_25_10_b1_e4"
|
||||||
@ -57,19 +56,8 @@ class TestNodeDev(unittest.TestCase):
|
|||||||
self.assertEqual(dev.parent, "pci_8086_1049")
|
self.assertEqual(dev.parent, "pci_8086_1049")
|
||||||
self.assertEqual(dev.device_type, "net")
|
self.assertEqual(dev.device_type, "net")
|
||||||
self.assertEqual(dev.interface, "eth0")
|
self.assertEqual(dev.interface, "eth0")
|
||||||
self.assertEqual(dev.pretty_name(), "Interface eth0")
|
|
||||||
|
|
||||||
def testPCIDevice(self):
|
def testPCIDevice(self):
|
||||||
devname = "pci_1180_592"
|
|
||||||
dev = self._nodeDevFromName(devname)
|
|
||||||
self.assertEqual(dev.pretty_name(),
|
|
||||||
"0000:15:00:4 Ricoh Co Ltd R5C592 Memory Stick Bus Host Adapter")
|
|
||||||
|
|
||||||
devname = "pci_8086_1049"
|
|
||||||
dev = self._nodeDevFromName(devname)
|
|
||||||
self.assertEqual(dev.pretty_name(),
|
|
||||||
"0000:00:19:0 Intel Corporation 82566MM Gigabit Network Connection")
|
|
||||||
|
|
||||||
nodename = "pci_8086_10fb"
|
nodename = "pci_8086_10fb"
|
||||||
obj = self._nodeDevFromName(nodename)
|
obj = self._nodeDevFromName(nodename)
|
||||||
self.assertEqual(obj.is_pci_sriov(), True)
|
self.assertEqual(obj.is_pci_sriov(), True)
|
||||||
@ -81,13 +69,8 @@ class TestNodeDev(unittest.TestCase):
|
|||||||
def testUSBDevDevice(self):
|
def testUSBDevDevice(self):
|
||||||
devname = "usb_device_781_5151_2004453082054CA1BEEE"
|
devname = "usb_device_781_5151_2004453082054CA1BEEE"
|
||||||
dev = self._nodeDevFromName(devname)
|
dev = self._nodeDevFromName(devname)
|
||||||
self.assertEqual(dev.pretty_name(),
|
self.assertEqual(dev.vendor_name, "SanDisk Corp.")
|
||||||
"001:004 SanDisk Corp. Cruzer Micro 256/512MB Flash Drive")
|
self.assertEqual(dev.product_name, "Cruzer Micro 256/512MB Flash Drive")
|
||||||
|
|
||||||
devname = "usb_device_483_2016_noserial"
|
|
||||||
dev = self._nodeDevFromName(devname)
|
|
||||||
self.assertEqual(dev.pretty_name(),
|
|
||||||
"003:002 SGS Thomson Microelectronics Fingerprint Reader")
|
|
||||||
|
|
||||||
devname = "usb_device_1d6b_1_0000_00_1a_0"
|
devname = "usb_device_1d6b_1_0000_00_1a_0"
|
||||||
dev = self._nodeDevFromName(devname)
|
dev = self._nodeDevFromName(devname)
|
||||||
@ -126,8 +109,6 @@ class TestNodeDev(unittest.TestCase):
|
|||||||
"/dev/dri/by-path/pci-0000:00:02.0-render")
|
"/dev/dri/by-path/pci-0000:00:02.0-render")
|
||||||
self.assertEqual(dev.devnodes[1].node_type, "link")
|
self.assertEqual(dev.devnodes[1].node_type, "link")
|
||||||
self.assertEqual(dev.is_drm_render(), True)
|
self.assertEqual(dev.is_drm_render(), True)
|
||||||
self.assertEqual(dev.pretty_name(),
|
|
||||||
"0000:00:02:0 Intel Corporation HD Graphics 530 (render)")
|
|
||||||
|
|
||||||
|
|
||||||
# NodeDevice 2 Device XML tests
|
# NodeDevice 2 Device XML tests
|
||||||
|
@ -280,7 +280,7 @@ class vmmAddHardware(vmmGObjectUI):
|
|||||||
True, None)
|
True, None)
|
||||||
add_hw_option(_("RNG"), "system-run", PAGE_RNG, True, None)
|
add_hw_option(_("RNG"), "system-run", PAGE_RNG, True, None)
|
||||||
add_hw_option(_("Panic Notifier"), "system-run", PAGE_PANIC,
|
add_hw_option(_("Panic Notifier"), "system-run", PAGE_PANIC,
|
||||||
bool(DevicePanic.get_models(self.vm.get_xmlobj().os)),
|
bool(DevicePanic.get_models(self.vm.get_xmlobj())),
|
||||||
_("Not supported for this hypervisor/libvirt/arch combination."))
|
_("Not supported for this hypervisor/libvirt/arch combination."))
|
||||||
add_hw_option(_("Virtio VSOCK"), "network-idle", PAGE_VSOCK,
|
add_hw_option(_("Virtio VSOCK"), "network-idle", PAGE_VSOCK,
|
||||||
self.vm.is_hvm(),
|
self.vm.is_hvm(),
|
||||||
@ -403,6 +403,295 @@ class vmmAddHardware(vmmGObjectUI):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
#####################
|
||||||
|
# Pretty UI helpers #
|
||||||
|
#####################
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def char_recommended_types(char_class):
|
||||||
|
if char_class.XML_NAME == "console":
|
||||||
|
return [DeviceSerial.TYPE_PTY]
|
||||||
|
|
||||||
|
ret = [DeviceSerial.TYPE_PTY,
|
||||||
|
DeviceSerial.TYPE_FILE,
|
||||||
|
DeviceSerial.TYPE_UNIX]
|
||||||
|
if char_class.XML_NAME == "channel":
|
||||||
|
ret = [DeviceSerial.TYPE_SPICEVMC,
|
||||||
|
DeviceSerial.TYPE_SPICEPORT] + ret
|
||||||
|
return ret
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def char_pretty_channel_name(val):
|
||||||
|
if val == DeviceChannel.CHANNEL_NAME_SPICE:
|
||||||
|
return "spice"
|
||||||
|
if val == DeviceChannel.CHANNEL_NAME_QEMUGA:
|
||||||
|
return "qemu-ga"
|
||||||
|
if val == DeviceChannel.CHANNEL_NAME_LIBGUESTFS:
|
||||||
|
return "libguestfs"
|
||||||
|
if val == DeviceChannel.CHANNEL_NAME_SPICE_WEBDAV:
|
||||||
|
return "spice-webdav"
|
||||||
|
return None
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def char_pretty_type(ctype):
|
||||||
|
"""
|
||||||
|
Return a human readable description of the passed char type
|
||||||
|
"""
|
||||||
|
if ctype == DeviceSerial.TYPE_PTY:
|
||||||
|
return _("Pseudo TTY")
|
||||||
|
elif ctype == DeviceSerial.TYPE_FILE:
|
||||||
|
return _("Output to a file")
|
||||||
|
elif ctype == DeviceSerial.TYPE_TCP:
|
||||||
|
return _("TCP net console")
|
||||||
|
elif ctype == DeviceSerial.TYPE_UDP:
|
||||||
|
return _("UDP net console")
|
||||||
|
elif ctype == DeviceSerial.TYPE_UNIX:
|
||||||
|
return _("Unix socket")
|
||||||
|
elif ctype == DeviceSerial.TYPE_SPICEVMC:
|
||||||
|
return _("Spice agent")
|
||||||
|
elif ctype == DeviceSerial.TYPE_SPICEPORT:
|
||||||
|
return _("Spice port")
|
||||||
|
return ctype
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def controller_recommended_types():
|
||||||
|
return [DeviceController.TYPE_SCSI,
|
||||||
|
DeviceController.TYPE_USB,
|
||||||
|
DeviceController.TYPE_VIRTIOSERIAL,
|
||||||
|
DeviceController.TYPE_CCID]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def controller_pretty_type(ctype):
|
||||||
|
pretty_mappings = {
|
||||||
|
DeviceController.TYPE_IDE: "IDE",
|
||||||
|
DeviceController.TYPE_FDC: _("Floppy"),
|
||||||
|
DeviceController.TYPE_SCSI: "SCSI",
|
||||||
|
DeviceController.TYPE_SATA: "SATA",
|
||||||
|
DeviceController.TYPE_VIRTIOSERIAL: "VirtIO Serial",
|
||||||
|
DeviceController.TYPE_USB: "USB",
|
||||||
|
DeviceController.TYPE_PCI: "PCI",
|
||||||
|
DeviceController.TYPE_CCID: "CCID",
|
||||||
|
DeviceController.TYPE_XENBUS: "xenbus",
|
||||||
|
}
|
||||||
|
if ctype not in pretty_mappings:
|
||||||
|
return ctype
|
||||||
|
return pretty_mappings[ctype]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def controller_pretty_desc(dev):
|
||||||
|
ret = vmmAddHardware.controller_pretty_type(dev.type)
|
||||||
|
if dev.type == "scsi":
|
||||||
|
if dev.model == "virtio-scsi":
|
||||||
|
ret = "Virtio " + ret
|
||||||
|
elif dev.address.type == "spapr-vio":
|
||||||
|
ret = "sPAPR " + ret
|
||||||
|
if dev.type == "pci" and dev.model == "pcie-root":
|
||||||
|
ret = "PCIe"
|
||||||
|
return ret
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def disk_old_recommended_buses(guest):
|
||||||
|
ret = []
|
||||||
|
if guest.os.is_hvm() or guest.conn.is_test():
|
||||||
|
if not guest.os.is_q35():
|
||||||
|
ret.append("ide")
|
||||||
|
ret.append("sata")
|
||||||
|
ret.append("fdc")
|
||||||
|
ret.append("scsi")
|
||||||
|
ret.append("usb")
|
||||||
|
|
||||||
|
if guest.type in ["qemu", "kvm", "test"]:
|
||||||
|
ret.append("sd")
|
||||||
|
ret.append("virtio")
|
||||||
|
if "scsi" not in ret:
|
||||||
|
ret.append("scsi")
|
||||||
|
|
||||||
|
if guest.conn.is_xen() or guest.conn.is_test():
|
||||||
|
ret.append("xen")
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def disk_recommended_buses(guest, domcaps, devtype):
|
||||||
|
# try to get supported disk bus types from domain capabilities
|
||||||
|
if "bus" in domcaps.devices.disk.enum_names():
|
||||||
|
buses = domcaps.devices.disk.get_enum("bus").get_values()
|
||||||
|
else:
|
||||||
|
buses = vmmAddHardware.disk_old_recommended_buses(guest)
|
||||||
|
|
||||||
|
bus_map = {
|
||||||
|
"disk": ["ide", "sata", "scsi", "sd", "usb", "virtio", "xen"],
|
||||||
|
"floppy": ["fdc"],
|
||||||
|
"cdrom": ["ide", "sata", "scsi"],
|
||||||
|
"lun": ["scsi"],
|
||||||
|
}
|
||||||
|
return [bus for bus in buses if bus in bus_map.get(devtype, [])]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def disk_pretty_bus(bus):
|
||||||
|
if bus in ["ide", "sata", "scsi", "usb", "sd"]:
|
||||||
|
return bus.upper()
|
||||||
|
if bus in ["xen"]:
|
||||||
|
return bus.capitalize()
|
||||||
|
if bus == "virtio":
|
||||||
|
return "VirtIO"
|
||||||
|
return bus
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def tpm_pretty_type(tpm_type):
|
||||||
|
if tpm_type == DeviceTpm.TYPE_PASSTHROUGH:
|
||||||
|
return _("Passthrough device")
|
||||||
|
if tpm_type == DeviceTpm.TYPE_EMULATOR:
|
||||||
|
return _("Emulated device")
|
||||||
|
return tpm_type
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def tpm_pretty_model(tpm_model):
|
||||||
|
if tpm_model == DeviceTpm.MODEL_TIS:
|
||||||
|
return _("TIS")
|
||||||
|
if tpm_model == DeviceTpm.MODEL_CRB:
|
||||||
|
return _("CRB")
|
||||||
|
return tpm_model
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def panic_pretty_model(panic_model):
|
||||||
|
if panic_model == DevicePanic.MODEL_ISA:
|
||||||
|
return _("ISA")
|
||||||
|
elif panic_model == DevicePanic.MODEL_PSERIES:
|
||||||
|
return _("pSeries")
|
||||||
|
elif panic_model == DevicePanic.MODEL_HYPERV:
|
||||||
|
return _("Hyper-V")
|
||||||
|
elif panic_model == DevicePanic.MODEL_S390:
|
||||||
|
return _("s390")
|
||||||
|
return panic_model
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def rng_pretty_type(rng_type):
|
||||||
|
if rng_type == DeviceRng.TYPE_RANDOM:
|
||||||
|
return _("Random")
|
||||||
|
if rng_type == DeviceRng.TYPE_EGD:
|
||||||
|
return _("Entropy Gathering Daemon")
|
||||||
|
return rng_type
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def rng_pretty_backend_type(backend_type):
|
||||||
|
return {"udp": "UDP",
|
||||||
|
"tcp": "TCP"}.get(backend_type) or backend_type
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def rng_pretty_mode(mode):
|
||||||
|
return {"bind": _("Bind"),
|
||||||
|
"connect": _("Connect")}.get(mode) or mode
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def sound_recommended_models(_guest):
|
||||||
|
return ["ich6", "ich9", "ac97"]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def sound_pretty_model(model):
|
||||||
|
ret = model.upper()
|
||||||
|
if model in ["ich6", "ich9"]:
|
||||||
|
ret = "HDA (%s)" % model.upper()
|
||||||
|
return ret
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def watchdog_pretty_action(action):
|
||||||
|
if action == DeviceWatchdog.ACTION_RESET:
|
||||||
|
return _("Forcefully reset the guest")
|
||||||
|
if action == DeviceWatchdog.ACTION_SHUTDOWN:
|
||||||
|
return _("Gracefully shutdown the guest")
|
||||||
|
if action == DeviceWatchdog.ACTION_POWEROFF:
|
||||||
|
return _("Forcefully power off the guest")
|
||||||
|
if action == DeviceWatchdog.ACTION_PAUSE:
|
||||||
|
return _("Pause the guest")
|
||||||
|
if action == DeviceWatchdog.ACTION_NONE:
|
||||||
|
return _("No action")
|
||||||
|
if action == DeviceWatchdog.ACTION_DUMP:
|
||||||
|
return _("Dump guest memory core")
|
||||||
|
return action
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def input_pretty_name(typ, bus):
|
||||||
|
if typ == "tablet" and bus == "usb":
|
||||||
|
return _("EvTouch USB Graphics Tablet")
|
||||||
|
|
||||||
|
if bus in ["usb", "ps2"]:
|
||||||
|
return _("Generic") + (" %s %s" %
|
||||||
|
(bus.upper(), str(typ).capitalize()))
|
||||||
|
return "%s %s" % (str(bus).capitalize(), str(typ).capitalize())
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def interface_recommended_models(guest):
|
||||||
|
if not guest.os.is_hvm():
|
||||||
|
return []
|
||||||
|
|
||||||
|
ret = []
|
||||||
|
if guest.type in ["kvm", "qemu", "vz", "test"]:
|
||||||
|
ret.append("virtio")
|
||||||
|
if guest.os.is_x86():
|
||||||
|
if guest.os.is_q35():
|
||||||
|
ret.append("e1000e")
|
||||||
|
else:
|
||||||
|
ret.append("rtl8139")
|
||||||
|
ret.append("e1000")
|
||||||
|
if guest.type in ["xen", "test"]:
|
||||||
|
ret.append("netfront")
|
||||||
|
|
||||||
|
ret.sort()
|
||||||
|
return ret
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def redirdev_pretty_type(typ):
|
||||||
|
if typ == "tcp":
|
||||||
|
return "TCP"
|
||||||
|
if typ == "spicevmc":
|
||||||
|
return "SpiceVMC"
|
||||||
|
return typ and typ.capitalize()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def video_recommended_models(guest):
|
||||||
|
if guest.conn.is_xen():
|
||||||
|
return ["xen", "vga"]
|
||||||
|
if guest.conn.is_qemu() or guest.conn.is_test():
|
||||||
|
return ["vga", "qxl", "virtio"]
|
||||||
|
return []
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def video_pretty_model(model):
|
||||||
|
if model in ["qxl", "vmvga", "vga"]:
|
||||||
|
return model.upper()
|
||||||
|
return model.capitalize()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def hostdev_pretty_name(hostdev):
|
||||||
|
def dehex(val):
|
||||||
|
if val.startswith("0x"):
|
||||||
|
val = val[2:]
|
||||||
|
return val
|
||||||
|
|
||||||
|
def safeint(val, fmt="%.3d"):
|
||||||
|
try:
|
||||||
|
int(val)
|
||||||
|
except Exception:
|
||||||
|
return str(val)
|
||||||
|
return fmt % int(val)
|
||||||
|
|
||||||
|
label = hostdev.type.upper()
|
||||||
|
|
||||||
|
if hostdev.vendor and hostdev.product:
|
||||||
|
label += " %s:%s" % (dehex(hostdev.vendor), dehex(hostdev.product))
|
||||||
|
|
||||||
|
elif hostdev.bus and hostdev.device:
|
||||||
|
label += " %s:%s" % (safeint(hostdev.bus), safeint(hostdev.device))
|
||||||
|
|
||||||
|
elif (hostdev.bus and hostdev.slot and
|
||||||
|
hostdev.function and hostdev.domain):
|
||||||
|
label += (" %s:%s:%s.%s" %
|
||||||
|
(dehex(hostdev.domain), dehex(hostdev.bus),
|
||||||
|
dehex(hostdev.slot), dehex(hostdev.function)))
|
||||||
|
|
||||||
|
return label
|
||||||
|
|
||||||
|
|
||||||
#########################
|
#########################
|
||||||
# UI init/reset helpers #
|
# UI init/reset helpers #
|
||||||
@ -467,11 +756,11 @@ class vmmAddHardware(vmmGObjectUI):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def populate_disk_bus_combo(vm, devtype, model):
|
def populate_disk_bus_combo(vm, devtype, model):
|
||||||
domcaps = vm.get_domain_capabilities()
|
domcaps = vm.get_domain_capabilities()
|
||||||
buses = DeviceDisk.get_recommended_buses(vm.xmlobj, domcaps, devtype)
|
buses = vmmAddHardware.disk_recommended_buses(vm.xmlobj, domcaps, devtype)
|
||||||
|
|
||||||
model.clear()
|
model.clear()
|
||||||
for bus in buses:
|
for bus in buses:
|
||||||
model.append([bus, DeviceDisk.pretty_disk_bus(bus)])
|
model.append([bus, vmmAddHardware.disk_pretty_bus(bus)])
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -481,7 +770,7 @@ class vmmAddHardware(vmmGObjectUI):
|
|||||||
|
|
||||||
# [xml value, label]
|
# [xml value, label]
|
||||||
model.append([None, _("Hypervisor default")])
|
model.append([None, _("Hypervisor default")])
|
||||||
for netmodel in DeviceInterface.get_models(vm.xmlobj):
|
for netmodel in vmmAddHardware.interface_recommended_models(vm.xmlobj):
|
||||||
model.append([netmodel, netmodel])
|
model.append([netmodel, netmodel])
|
||||||
|
|
||||||
uiutil.set_list_selection(
|
uiutil.set_list_selection(
|
||||||
@ -502,15 +791,16 @@ class vmmAddHardware(vmmGObjectUI):
|
|||||||
(DeviceInput.TYPE_TABLET, DeviceInput.BUS_VIRTIO),
|
(DeviceInput.TYPE_TABLET, DeviceInput.BUS_VIRTIO),
|
||||||
]
|
]
|
||||||
|
|
||||||
cvals = [((t, b), DeviceInput.pretty_name(t, b)) for t, b in devices]
|
cvals = [((t, b), vmmAddHardware.input_pretty_name(t, b))
|
||||||
|
for t, b in devices]
|
||||||
_build_combo(self.widget("input-type"), cvals)
|
_build_combo(self.widget("input-type"), cvals)
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def build_sound_combo(vm, combo):
|
def build_sound_combo(vm, combo):
|
||||||
values = []
|
values = []
|
||||||
for m in DeviceSound.get_recommended_models(vm.xmlobj):
|
for m in vmmAddHardware.sound_recommended_models(vm.xmlobj):
|
||||||
values.append([m, DeviceSound.pretty_model(m)])
|
values.append([m, vmmAddHardware.sound_pretty_model(m)])
|
||||||
|
|
||||||
default = DeviceSound.default_model(vm.xmlobj)
|
default = DeviceSound.default_model(vm.xmlobj)
|
||||||
_build_combo(combo, values, default_value=default)
|
_build_combo(combo, values, default_value=default)
|
||||||
@ -540,12 +830,12 @@ class vmmAddHardware(vmmGObjectUI):
|
|||||||
continue
|
continue
|
||||||
if dev.xmlobj.is_pci_bridge():
|
if dev.xmlobj.is_pci_bridge():
|
||||||
continue
|
continue
|
||||||
prettyname = dev.xmlobj.pretty_name()
|
prettyname = dev.pretty_name()
|
||||||
|
|
||||||
if devtype == "pci":
|
if devtype == "pci":
|
||||||
for subdev in netdevs:
|
for subdev in netdevs:
|
||||||
if dev.xmlobj.name == subdev.xmlobj.parent:
|
if dev.xmlobj.name == subdev.xmlobj.parent:
|
||||||
prettyname += " (%s)" % subdev.xmlobj.pretty_name()
|
prettyname += " (%s)" % subdev.pretty_name()
|
||||||
|
|
||||||
model.append([dev.xmlobj, prettyname])
|
model.append([dev.xmlobj, prettyname])
|
||||||
|
|
||||||
@ -557,8 +847,8 @@ class vmmAddHardware(vmmGObjectUI):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def build_video_combo(vm, combo):
|
def build_video_combo(vm, combo):
|
||||||
values = []
|
values = []
|
||||||
for m in DeviceVideo.get_recommended_models(vm.xmlobj):
|
for m in vmmAddHardware.video_recommended_models(vm.xmlobj):
|
||||||
values.append([m, DeviceVideo.pretty_model(m)])
|
values.append([m, vmmAddHardware.video_pretty_model(m)])
|
||||||
if not values:
|
if not values:
|
||||||
values.append([None, _("Hypervisor default")])
|
values.append([None, _("Hypervisor default")])
|
||||||
default = DeviceVideo.default_model(vm.xmlobj)
|
default = DeviceVideo.default_model(vm.xmlobj)
|
||||||
@ -584,8 +874,8 @@ class vmmAddHardware(vmmGObjectUI):
|
|||||||
model = self.widget("char-device-type").get_model()
|
model = self.widget("char-device-type").get_model()
|
||||||
model.clear()
|
model.clear()
|
||||||
|
|
||||||
for t in char_class.get_recommended_types(self.vm.xmlobj):
|
for t in vmmAddHardware.char_recommended_types(char_class):
|
||||||
model.append([t, char_class.pretty_type(t) + " (%s)" % t])
|
model.append([t, vmmAddHardware.char_pretty_type(t) + " (%s)" % t])
|
||||||
uiutil.set_list_selection(self.widget("char-device-type"), "pty")
|
uiutil.set_list_selection(self.widget("char-device-type"), "pty")
|
||||||
|
|
||||||
|
|
||||||
@ -600,7 +890,7 @@ class vmmAddHardware(vmmGObjectUI):
|
|||||||
def build_watchdogaction_combo(_vm, combo):
|
def build_watchdogaction_combo(_vm, combo):
|
||||||
values = []
|
values = []
|
||||||
for m in DeviceWatchdog.ACTIONS:
|
for m in DeviceWatchdog.ACTIONS:
|
||||||
values.append([m, DeviceWatchdog.get_action_desc(m)])
|
values.append([m, vmmAddHardware.watchdog_pretty_action(m)])
|
||||||
_build_combo(combo, values, default_value=DeviceWatchdog.ACTION_RESET)
|
_build_combo(combo, values, default_value=DeviceWatchdog.ACTION_RESET)
|
||||||
|
|
||||||
|
|
||||||
@ -621,11 +911,11 @@ class vmmAddHardware(vmmGObjectUI):
|
|||||||
def _build_tpm_type_combo(self):
|
def _build_tpm_type_combo(self):
|
||||||
values = []
|
values = []
|
||||||
for t in DeviceTpm.TYPES:
|
for t in DeviceTpm.TYPES:
|
||||||
values.append([t, DeviceTpm.get_pretty_type(t)])
|
values.append([t, vmmAddHardware.tpm_pretty_type(t)])
|
||||||
_build_combo(self.widget("tpm-type"), values)
|
_build_combo(self.widget("tpm-type"), values)
|
||||||
values = []
|
values = []
|
||||||
for t in DeviceTpm.MODELS:
|
for t in DeviceTpm.MODELS:
|
||||||
values.append([t, DeviceTpm.get_pretty_model(t)])
|
values.append([t, vmmAddHardware.tpm_pretty_model(t)])
|
||||||
_build_combo(self.widget("tpm-model"), values)
|
_build_combo(self.widget("tpm-model"), values)
|
||||||
values = []
|
values = []
|
||||||
for t in DeviceTpm.VERSIONS:
|
for t in DeviceTpm.VERSIONS:
|
||||||
@ -650,7 +940,7 @@ class vmmAddHardware(vmmGObjectUI):
|
|||||||
|
|
||||||
mod_list = vmmAddHardware._get_tpm_model_list(vm, tpmversion)
|
mod_list = vmmAddHardware._get_tpm_model_list(vm, tpmversion)
|
||||||
for m in mod_list:
|
for m in mod_list:
|
||||||
model.append([m, DeviceTpm.get_pretty_model(m)])
|
model.append([m, vmmAddHardware.tpm_pretty_model(m)])
|
||||||
combo.set_active(0)
|
combo.set_active(0)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -661,8 +951,8 @@ class vmmAddHardware(vmmGObjectUI):
|
|||||||
|
|
||||||
def _build_panic_model_combo(self):
|
def _build_panic_model_combo(self):
|
||||||
values = []
|
values = []
|
||||||
for m in DevicePanic.get_models(self.vm.get_xmlobj().os):
|
for m in DevicePanic.get_models(self.vm.get_xmlobj()):
|
||||||
values.append([m, DevicePanic.get_pretty_model(m)])
|
values.append([m, vmmAddHardware.panic_pretty_model(m)])
|
||||||
|
|
||||||
default = DevicePanic.get_default_model(self.vm.get_xmlobj())
|
default = DevicePanic.get_default_model(self.vm.get_xmlobj())
|
||||||
_build_combo(self.widget("panic-model"), values, default_value=default)
|
_build_combo(self.widget("panic-model"), values, default_value=default)
|
||||||
@ -670,8 +960,8 @@ class vmmAddHardware(vmmGObjectUI):
|
|||||||
|
|
||||||
def _build_controller_type_combo(self):
|
def _build_controller_type_combo(self):
|
||||||
values = []
|
values = []
|
||||||
for t in DeviceController.get_recommended_types(self.vm.xmlobj):
|
for t in vmmAddHardware.controller_recommended_types():
|
||||||
values.append([t, DeviceController.pretty_type(t)])
|
values.append([t, vmmAddHardware.controller_pretty_type(t)])
|
||||||
|
|
||||||
_build_combo(self.widget("controller-type"), values,
|
_build_combo(self.widget("controller-type"), values,
|
||||||
default_value=DeviceController.TYPE_SCSI)
|
default_value=DeviceController.TYPE_SCSI)
|
||||||
|
@ -11,6 +11,9 @@ from gi.repository import Gtk
|
|||||||
from gi.repository import Gdk
|
from gi.repository import Gdk
|
||||||
from gi.repository import Pango
|
from gi.repository import Pango
|
||||||
|
|
||||||
|
import libvirt
|
||||||
|
|
||||||
|
from virtinst import generatename
|
||||||
from virtinst import Network
|
from virtinst import Network
|
||||||
|
|
||||||
from . import uiutil
|
from . import uiutil
|
||||||
@ -110,8 +113,9 @@ class vmmCreateNetwork(vmmGObjectUI):
|
|||||||
mode_model.append(["hostdev", _("SR-IOV pool")])
|
mode_model.append(["hostdev", _("SR-IOV pool")])
|
||||||
|
|
||||||
def reset_state(self):
|
def reset_state(self):
|
||||||
default_name = Network.find_free_name(
|
basename = "network"
|
||||||
self.conn.get_backend(), "network")
|
default_name = generatename.generate_name(
|
||||||
|
basename, self.conn.get_backend().networkLookupByName)
|
||||||
self.widget("net-name").set_text(default_name)
|
self.widget("net-name").set_text(default_name)
|
||||||
|
|
||||||
self.widget("net-dns-use-netname").set_active(True)
|
self.widget("net-dns-use-netname").set_active(True)
|
||||||
@ -161,7 +165,7 @@ class vmmCreateNetwork(vmmGObjectUI):
|
|||||||
for pcidev in self.conn.filter_nodedevs("pci"):
|
for pcidev in self.conn.filter_nodedevs("pci"):
|
||||||
if not pcidev.xmlobj.is_pci_sriov():
|
if not pcidev.xmlobj.is_pci_sriov():
|
||||||
continue
|
continue
|
||||||
devdesc = pcidev.xmlobj.pretty_name()
|
devdesc = pcidev.pretty_name()
|
||||||
for netdev in self.conn.filter_nodedevs("net"):
|
for netdev in self.conn.filter_nodedevs("net"):
|
||||||
if pcidev.xmlobj.name != netdev.xmlobj.parent:
|
if pcidev.xmlobj.name != netdev.xmlobj.parent:
|
||||||
continue
|
continue
|
||||||
@ -353,6 +357,15 @@ class vmmCreateNetwork(vmmGObjectUI):
|
|||||||
# XML build and install #
|
# XML build and install #
|
||||||
#########################
|
#########################
|
||||||
|
|
||||||
|
def _validate(self, net):
|
||||||
|
net.validate_generic_name(_("Network"), net.name)
|
||||||
|
|
||||||
|
try:
|
||||||
|
net.conn.networkLookupByName(net.name)
|
||||||
|
except libvirt.libvirtError:
|
||||||
|
return
|
||||||
|
raise ValueError(_("Name '%s' already in use by another network." %
|
||||||
|
net.name))
|
||||||
|
|
||||||
def _build_xmlobj(self):
|
def _build_xmlobj(self):
|
||||||
net = Network(self.conn.get_backend())
|
net = Network(self.conn.get_backend())
|
||||||
@ -418,12 +431,22 @@ class vmmCreateNetwork(vmmGObjectUI):
|
|||||||
|
|
||||||
def _async_net_create(self, asyncjob, net):
|
def _async_net_create(self, asyncjob, net):
|
||||||
ignore = asyncjob
|
ignore = asyncjob
|
||||||
net.install()
|
xml = net.get_xml()
|
||||||
|
logging.debug("Creating virtual network '%s' with xml:\n%s",
|
||||||
|
net.name, xml)
|
||||||
|
|
||||||
|
netobj = self.conn.get_backend().networkDefineXML(xml)
|
||||||
|
try:
|
||||||
|
netobj.create()
|
||||||
|
netobj.setAutostart(True)
|
||||||
|
except Exception:
|
||||||
|
netobj.undefine()
|
||||||
|
raise
|
||||||
|
|
||||||
def finish(self, ignore):
|
def finish(self, ignore):
|
||||||
try:
|
try:
|
||||||
net = self._build_xmlobj()
|
net = self._build_xmlobj()
|
||||||
net.validate()
|
self._validate(net)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.err.show_err(_("Error generating network xml: %s") % str(e))
|
self.err.show_err(_("Error generating network xml: %s") % str(e))
|
||||||
return
|
return
|
||||||
|
@ -173,7 +173,7 @@ def _label_for_device(dev):
|
|||||||
devtype = dev.DEVICE_TYPE
|
devtype = dev.DEVICE_TYPE
|
||||||
|
|
||||||
if devtype == "disk":
|
if devtype == "disk":
|
||||||
busstr = virtinst.DeviceDisk.pretty_disk_bus(dev.bus) or ""
|
busstr = vmmAddHardware.disk_pretty_bus(dev.bus) or ""
|
||||||
|
|
||||||
if dev.device == "floppy":
|
if dev.device == "floppy":
|
||||||
devstr = _("Floppy")
|
devstr = _("Floppy")
|
||||||
@ -220,28 +220,30 @@ def _label_for_device(dev):
|
|||||||
|
|
||||||
if devtype == "channel":
|
if devtype == "channel":
|
||||||
label = _("Channel")
|
label = _("Channel")
|
||||||
name = dev.pretty_channel_name(dev.target_name)
|
name = vmmAddHardware.char_pretty_channel_name(dev.target_name)
|
||||||
if not name:
|
if not name:
|
||||||
name = dev.pretty_type(dev.type)
|
name = vmmAddHardware.char_pretty_type(dev.type)
|
||||||
if name:
|
if name:
|
||||||
label += " %s" % name
|
label += " %s" % name
|
||||||
return label
|
return label
|
||||||
|
|
||||||
if devtype == "graphics":
|
if devtype == "graphics":
|
||||||
return _("Display %s") % dev.pretty_type_simple(dev.type)
|
pretty = vmmGraphicsDetails.graphics_pretty_type_simple(dev.type)
|
||||||
|
return _("Display %s") % pretty
|
||||||
if devtype == "redirdev":
|
if devtype == "redirdev":
|
||||||
return _("%s Redirector %s") % (dev.bus.upper(),
|
return _("%s Redirector %s") % (dev.bus.upper(),
|
||||||
dev.get_xml_idx() + 1)
|
dev.get_xml_idx() + 1)
|
||||||
if devtype == "hostdev":
|
if devtype == "hostdev":
|
||||||
return dev.pretty_name()
|
return vmmAddHardware.hostdev_pretty_name(dev)
|
||||||
if devtype == "sound":
|
if devtype == "sound":
|
||||||
return _("Sound %s") % dev.model
|
return _("Sound %s") % dev.model
|
||||||
if devtype == "video":
|
if devtype == "video":
|
||||||
return _("Video %s") % dev.pretty_model(dev.model)
|
return _("Video %s") % vmmAddHardware.video_pretty_model(dev.model)
|
||||||
if devtype == "filesystem":
|
if devtype == "filesystem":
|
||||||
return _("Filesystem %s") % dev.target[:8]
|
return _("Filesystem %s") % dev.target[:8]
|
||||||
if devtype == "controller":
|
if devtype == "controller":
|
||||||
return _("Controller %s %s") % (dev.pretty_desc(), dev.index)
|
return _("Controller %s %s") % (
|
||||||
|
vmmAddHardware.controller_pretty_desc(dev), dev.index)
|
||||||
if devtype == "rng":
|
if devtype == "rng":
|
||||||
label = _("RNG")
|
label = _("RNG")
|
||||||
if dev.device:
|
if dev.device:
|
||||||
@ -2269,7 +2271,7 @@ class vmmDetails(vmmGObjectUI):
|
|||||||
self.netlist.set_dev(net)
|
self.netlist.set_dev(net)
|
||||||
|
|
||||||
def refresh_input_page(self, inp):
|
def refresh_input_page(self, inp):
|
||||||
dev = inp.pretty_name(inp.type, inp.bus)
|
dev = vmmAddHardware.input_pretty_name(inp.type, inp.bus)
|
||||||
|
|
||||||
mode = None
|
mode = None
|
||||||
if inp.type == "tablet":
|
if inp.type == "tablet":
|
||||||
@ -2302,7 +2304,8 @@ class vmmDetails(vmmGObjectUI):
|
|||||||
address = _("%s:%s") % (rd.source.host, rd.source.service)
|
address = _("%s:%s") % (rd.source.host, rd.source.service)
|
||||||
|
|
||||||
self.widget("redir-title").set_markup(_label_for_device(rd))
|
self.widget("redir-title").set_markup(_label_for_device(rd))
|
||||||
self.widget("redir-type").set_text(rd.pretty_type(rd.type))
|
self.widget("redir-type").set_text(
|
||||||
|
vmmAddHardware.redirdev_pretty_type(rd.type))
|
||||||
|
|
||||||
self.widget("redir-address").set_text(address or "")
|
self.widget("redir-address").set_text(address or "")
|
||||||
uiutil.set_grid_row_visible(
|
uiutil.set_grid_row_visible(
|
||||||
@ -2316,7 +2319,7 @@ class vmmDetails(vmmGObjectUI):
|
|||||||
|
|
||||||
dev_type = tpmdev.type
|
dev_type = tpmdev.type
|
||||||
self.widget("tpm-dev-type").set_text(
|
self.widget("tpm-dev-type").set_text(
|
||||||
virtinst.DeviceTpm.get_pretty_type(dev_type))
|
vmmAddHardware.tpm_pretty_type(dev_type))
|
||||||
|
|
||||||
vmmAddHardware.populate_tpm_model_combo(
|
vmmAddHardware.populate_tpm_model_combo(
|
||||||
self.vm, self.widget("tpm-model"), tpmdev.version)
|
self.vm, self.widget("tpm-model"), tpmdev.version)
|
||||||
@ -2328,7 +2331,7 @@ class vmmDetails(vmmGObjectUI):
|
|||||||
|
|
||||||
def refresh_panic_page(self, dev):
|
def refresh_panic_page(self, dev):
|
||||||
model = dev.model or "isa"
|
model = dev.model or "isa"
|
||||||
pmodel = virtinst.DevicePanic.get_pretty_model(model)
|
pmodel = vmmAddHardware.panic_pretty_model(model)
|
||||||
self.widget("panic-model").set_text(pmodel)
|
self.widget("panic-model").set_text(pmodel)
|
||||||
|
|
||||||
def refresh_rng_page(self, dev):
|
def refresh_rng_page(self, dev):
|
||||||
@ -2336,7 +2339,7 @@ class vmmDetails(vmmGObjectUI):
|
|||||||
uiutil.set_grid_row_visible(self.widget("rng-device"), is_random)
|
uiutil.set_grid_row_visible(self.widget("rng-device"), is_random)
|
||||||
|
|
||||||
self.widget("rng-type").set_text(
|
self.widget("rng-type").set_text(
|
||||||
dev.get_pretty_type(dev.backend_model))
|
vmmAddHardware.rng_pretty_type(dev.backend_model))
|
||||||
self.widget("rng-device").set_text(dev.device or "")
|
self.widget("rng-device").set_text(dev.device or "")
|
||||||
|
|
||||||
def refresh_vsock_page(self, dev):
|
def refresh_vsock_page(self, dev):
|
||||||
@ -2413,13 +2416,13 @@ class vmmDetails(vmmGObjectUI):
|
|||||||
nodedev = None
|
nodedev = None
|
||||||
for trydev in self.vm.conn.filter_nodedevs(devtype):
|
for trydev in self.vm.conn.filter_nodedevs(devtype):
|
||||||
if trydev.xmlobj.compare_to_hostdev(hostdev):
|
if trydev.xmlobj.compare_to_hostdev(hostdev):
|
||||||
nodedev = trydev.xmlobj
|
nodedev = trydev
|
||||||
|
|
||||||
pretty_name = None
|
pretty_name = None
|
||||||
if nodedev:
|
if nodedev:
|
||||||
pretty_name = nodedev.pretty_name()
|
pretty_name = nodedev.pretty_name()
|
||||||
if not pretty_name:
|
if not pretty_name:
|
||||||
pretty_name = hostdev.pretty_name()
|
pretty_name = vmmAddHardware.hostdev_pretty_name(hostdev)
|
||||||
|
|
||||||
uiutil.set_grid_row_visible(
|
uiutil.set_grid_row_visible(
|
||||||
self.widget("hostdev-rombar"), hostdev.type == "pci")
|
self.widget("hostdev-rombar"), hostdev.type == "pci")
|
||||||
@ -2499,7 +2502,7 @@ class vmmDetails(vmmGObjectUI):
|
|||||||
_("Cannot remove controller while devices are attached."))
|
_("Cannot remove controller while devices are attached."))
|
||||||
break
|
break
|
||||||
|
|
||||||
type_label = controller.pretty_desc()
|
type_label = vmmAddHardware.controller_pretty_desc(controller)
|
||||||
self.widget("controller-type").set_text(type_label)
|
self.widget("controller-type").set_text(type_label)
|
||||||
|
|
||||||
combo = self.widget("controller-model")
|
combo = self.widget("controller-model")
|
||||||
|
@ -131,11 +131,28 @@ class vmmDomainSnapshot(vmmLibvirtObject):
|
|||||||
ignore = force
|
ignore = force
|
||||||
self._backend.delete()
|
self._backend.delete()
|
||||||
|
|
||||||
|
def _state_str_to_int(self):
|
||||||
|
state = self.get_xmlobj().state
|
||||||
|
statemap = {
|
||||||
|
"nostate": libvirt.VIR_DOMAIN_NOSTATE,
|
||||||
|
"running": libvirt.VIR_DOMAIN_RUNNING,
|
||||||
|
"blocked": libvirt.VIR_DOMAIN_BLOCKED,
|
||||||
|
"paused": libvirt.VIR_DOMAIN_PAUSED,
|
||||||
|
"shutdown": libvirt.VIR_DOMAIN_SHUTDOWN,
|
||||||
|
"shutoff": libvirt.VIR_DOMAIN_SHUTOFF,
|
||||||
|
"crashed": libvirt.VIR_DOMAIN_CRASHED,
|
||||||
|
"pmsuspended": getattr(libvirt, "VIR_DOMAIN_PMSUSPENDED", 7)
|
||||||
|
}
|
||||||
|
|
||||||
|
if state == "disk-snapshot" or state not in statemap:
|
||||||
|
state = "shutoff"
|
||||||
|
return statemap.get(state, libvirt.VIR_DOMAIN_NOSTATE)
|
||||||
|
|
||||||
def run_status(self):
|
def run_status(self):
|
||||||
status = DomainSnapshot.state_str_to_int(self.get_xmlobj().state)
|
status = self._state_str_to_int()
|
||||||
return LibvirtEnumMap.pretty_run_status(status, False)
|
return LibvirtEnumMap.pretty_run_status(status, False)
|
||||||
def run_status_icon_name(self):
|
def run_status_icon_name(self):
|
||||||
status = DomainSnapshot.state_str_to_int(self.get_xmlobj().state)
|
status = self._state_str_to_int()
|
||||||
if status not in LibvirtEnumMap.VM_STATUS_ICONS:
|
if status not in LibvirtEnumMap.VM_STATUS_ICONS:
|
||||||
logging.debug("Unknown status %d, using NOSTATE", status)
|
logging.debug("Unknown status %d, using NOSTATE", status)
|
||||||
status = libvirt.VIR_DOMAIN_NOSTATE
|
status = libvirt.VIR_DOMAIN_NOSTATE
|
||||||
|
@ -55,6 +55,20 @@ class vmmGraphicsDetails(vmmGObjectUI):
|
|||||||
self.vm = None
|
self.vm = None
|
||||||
self.conn = None
|
self.conn = None
|
||||||
|
|
||||||
|
|
||||||
|
#####################
|
||||||
|
# Pretty UI helpers #
|
||||||
|
#####################
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def graphics_pretty_type_simple(gtype):
|
||||||
|
if (gtype in [virtinst.DeviceGraphics.TYPE_VNC,
|
||||||
|
virtinst.DeviceGraphics.TYPE_SDL,
|
||||||
|
virtinst.DeviceGraphics.TYPE_RDP]):
|
||||||
|
return str(gtype).upper()
|
||||||
|
return str(gtype).capitalize()
|
||||||
|
|
||||||
|
|
||||||
##########################
|
##########################
|
||||||
# Initialization methods #
|
# Initialization methods #
|
||||||
##########################
|
##########################
|
||||||
@ -109,7 +123,7 @@ class vmmGraphicsDetails(vmmGObjectUI):
|
|||||||
if not drm.is_drm_render():
|
if not drm.is_drm_render():
|
||||||
continue
|
continue
|
||||||
rendernode = drm.get_devnode().path
|
rendernode = drm.get_devnode().path
|
||||||
model.append([rendernode, i.xmlobj.pretty_name()])
|
model.append([rendernode, i.pretty_name()])
|
||||||
|
|
||||||
def _get_config_graphics_ports(self):
|
def _get_config_graphics_ports(self):
|
||||||
port = uiutil.spin_get_helper(self.widget("graphics-port"))
|
port = uiutil.spin_get_helper(self.widget("graphics-port"))
|
||||||
@ -193,8 +207,8 @@ class vmmGraphicsDetails(vmmGObjectUI):
|
|||||||
is_vnc = (gtype == "vnc")
|
is_vnc = (gtype == "vnc")
|
||||||
is_sdl = (gtype == "sdl")
|
is_sdl = (gtype == "sdl")
|
||||||
is_spice = (gtype == "spice")
|
is_spice = (gtype == "spice")
|
||||||
title = (_("%(graphicstype)s Server") %
|
pretty_type = vmmGraphicsDetails.graphics_pretty_type_simple(gtype)
|
||||||
{"graphicstype": gfx.pretty_type_simple(gtype)})
|
title = (_("%(graphicstype)s Server") % {"graphicstype": pretty_type})
|
||||||
|
|
||||||
if is_vnc or is_spice:
|
if is_vnc or is_spice:
|
||||||
use_passwd = gfx.passwd is not None
|
use_passwd = gfx.passwd is not None
|
||||||
|
@ -275,8 +275,15 @@ class vmmHostNets(vmmGObjectUI):
|
|||||||
def _populate_qos_state(self, net):
|
def _populate_qos_state(self, net):
|
||||||
qos = net.get_qos()
|
qos = net.get_qos()
|
||||||
|
|
||||||
self.widget("net-qos-inbound-enable").set_active(qos.is_inbound())
|
def is_inbound():
|
||||||
self.widget("net-qos-outbound-enable").set_active(qos.is_outbound())
|
return bool(qos.inbound_average or qos.inbound_peak or
|
||||||
|
qos.inbound_burst or qos.inbound_floor)
|
||||||
|
def is_outbound():
|
||||||
|
return bool(qos.outbound_average or qos.outbound_peak or
|
||||||
|
qos.outbound_burst)
|
||||||
|
|
||||||
|
self.widget("net-qos-inbound-enable").set_active(is_inbound())
|
||||||
|
self.widget("net-qos-outbound-enable").set_active(is_outbound())
|
||||||
|
|
||||||
self._update_qos_widgets()
|
self._update_qos_widgets()
|
||||||
|
|
||||||
|
@ -125,8 +125,6 @@ class vmmNetwork(vmmLibvirtObject):
|
|||||||
return self.get_xmlobj().ipv6
|
return self.get_xmlobj().ipv6
|
||||||
def get_ipv4_forward_mode(self):
|
def get_ipv4_forward_mode(self):
|
||||||
return self.get_xmlobj().forward.mode
|
return self.get_xmlobj().forward.mode
|
||||||
def pretty_forward_mode(self):
|
|
||||||
return self.get_xmlobj().forward.pretty_desc()
|
|
||||||
def get_qos(self):
|
def get_qos(self):
|
||||||
return self.get_xmlobj().bandwidth
|
return self.get_xmlobj().bandwidth
|
||||||
|
|
||||||
@ -200,3 +198,30 @@ class vmmNetwork(vmmLibvirtObject):
|
|||||||
pf_name = xmlobj.forward.pf[0].dev
|
pf_name = xmlobj.forward.pf[0].dev
|
||||||
vfs = xmlobj.forward.vfs
|
vfs = xmlobj.forward.vfs
|
||||||
return (ret, pf_name, vfs)
|
return (ret, pf_name, vfs)
|
||||||
|
|
||||||
|
def pretty_forward_mode(self):
|
||||||
|
mode = self.xmlobj.forward.mode
|
||||||
|
dev = self.xmlobj.forward.dev
|
||||||
|
|
||||||
|
if not mode:
|
||||||
|
return _("Isolated network")
|
||||||
|
|
||||||
|
if mode == "nat":
|
||||||
|
if dev:
|
||||||
|
desc = _("NAT to %s") % dev
|
||||||
|
else:
|
||||||
|
desc = _("NAT")
|
||||||
|
elif mode == "route":
|
||||||
|
if dev:
|
||||||
|
desc = _("Route to %s") % dev
|
||||||
|
else:
|
||||||
|
desc = _("Routed network")
|
||||||
|
else:
|
||||||
|
modestr = mode.capitalize()
|
||||||
|
if dev:
|
||||||
|
desc = (_("%(mode)s to %(device)s") %
|
||||||
|
{"mode": modestr, "device": dev})
|
||||||
|
else:
|
||||||
|
desc = _("%s network") % modestr
|
||||||
|
|
||||||
|
return desc
|
||||||
|
@ -9,6 +9,64 @@ from virtinst import NodeDevice
|
|||||||
from .libvirtobject import vmmLibvirtObject
|
from .libvirtobject import vmmLibvirtObject
|
||||||
|
|
||||||
|
|
||||||
|
def _usb_pretty_name(xmlobj):
|
||||||
|
# Hypervisor may return a rather sparse structure, missing
|
||||||
|
# some ol all stringular descriptions of the device altogether.
|
||||||
|
# Do our best to help user identify the device.
|
||||||
|
|
||||||
|
# Certain devices pad their vendor with trailing spaces,
|
||||||
|
# such as "LENOVO ". It does not look well.
|
||||||
|
product = str(xmlobj.product_name).strip()
|
||||||
|
vendor = str(xmlobj.vendor_name).strip()
|
||||||
|
|
||||||
|
if product == "":
|
||||||
|
product = str(xmlobj.product_id)
|
||||||
|
if vendor == "":
|
||||||
|
# No stringular descriptions altogether
|
||||||
|
vendor = str(xmlobj.vendor_id)
|
||||||
|
devstr = "%s:%s" % (vendor, product)
|
||||||
|
else:
|
||||||
|
# Only the vendor is known
|
||||||
|
devstr = "%s %s" % (vendor, product)
|
||||||
|
else:
|
||||||
|
if vendor == "":
|
||||||
|
# Sometimes vendor is left out empty, but product is
|
||||||
|
# already descriptive enough or contains the vendor string:
|
||||||
|
# "Lenovo USB Laser Mouse"
|
||||||
|
devstr = product
|
||||||
|
else:
|
||||||
|
# We know everything. Perfect.
|
||||||
|
devstr = "%s %s" % (vendor, product)
|
||||||
|
|
||||||
|
busstr = "%.3d:%.3d" % (int(xmlobj.bus), int(xmlobj.device))
|
||||||
|
desc = "%s %s" % (busstr, devstr)
|
||||||
|
return desc
|
||||||
|
|
||||||
|
|
||||||
|
def _pretty_name(xmlobj):
|
||||||
|
if xmlobj.device_type == "net":
|
||||||
|
if xmlobj.interface:
|
||||||
|
return _("Interface %s") % xmlobj.interface
|
||||||
|
return xmlobj.name
|
||||||
|
|
||||||
|
if xmlobj.device_type == "pci":
|
||||||
|
devstr = "%.4X:%.2X:%.2X:%X" % (int(xmlobj.domain),
|
||||||
|
int(xmlobj.bus),
|
||||||
|
int(xmlobj.slot),
|
||||||
|
int(xmlobj.function))
|
||||||
|
return "%s %s %s" % (devstr,
|
||||||
|
xmlobj.vendor_name, xmlobj.product_name)
|
||||||
|
if xmlobj.device_type == "usb_device":
|
||||||
|
return _usb_pretty_name(xmlobj)
|
||||||
|
|
||||||
|
if xmlobj.device_type == "drm":
|
||||||
|
parent = NodeDevice.lookupNodedevFromString(
|
||||||
|
xmlobj.conn, xmlobj.parent)
|
||||||
|
return "%s (%s)" % (_pretty_name(parent), xmlobj.drm_type)
|
||||||
|
|
||||||
|
return xmlobj.name
|
||||||
|
|
||||||
|
|
||||||
class vmmNodeDevice(vmmLibvirtObject):
|
class vmmNodeDevice(vmmLibvirtObject):
|
||||||
def __init__(self, conn, backend, key):
|
def __init__(self, conn, backend, key):
|
||||||
vmmLibvirtObject.__init__(self, conn, backend, key, NodeDevice)
|
vmmLibvirtObject.__init__(self, conn, backend, key, NodeDevice)
|
||||||
@ -34,3 +92,6 @@ class vmmNodeDevice(vmmLibvirtObject):
|
|||||||
ignore = stats_update
|
ignore = stats_update
|
||||||
def _init_libvirt_state(self):
|
def _init_libvirt_state(self):
|
||||||
self.ensure_latest_xml()
|
self.ensure_latest_xml()
|
||||||
|
|
||||||
|
def pretty_name(self):
|
||||||
|
return _pretty_name(self.xmlobj)
|
||||||
|
@ -16,6 +16,7 @@ from gi.repository import Gtk
|
|||||||
from gi.repository import Pango
|
from gi.repository import Pango
|
||||||
|
|
||||||
from virtinst import DomainSnapshot
|
from virtinst import DomainSnapshot
|
||||||
|
from virtinst import generatename
|
||||||
from virtinst import xmlutil
|
from virtinst import xmlutil
|
||||||
|
|
||||||
from . import uiutil
|
from . import uiutil
|
||||||
@ -117,8 +118,11 @@ class vmmSnapshotNew(vmmGObjectUI):
|
|||||||
|
|
||||||
def _reset_state(self):
|
def _reset_state(self):
|
||||||
collidelist = [s.get_xmlobj().name for s in self.vm.list_snapshots()]
|
collidelist = [s.get_xmlobj().name for s in self.vm.list_snapshots()]
|
||||||
default_name = DomainSnapshot.find_free_name(
|
basename = "snapshot"
|
||||||
self.vm.get_backend(), collidelist)
|
cb = self.vm.get_backend().snapshotLookupByName
|
||||||
|
default_name = generatename.generate_name(
|
||||||
|
basename, cb, sep="", start_num=1, force_num=True,
|
||||||
|
collidelist=collidelist)
|
||||||
|
|
||||||
self.widget("snapshot-new-name").set_text(default_name)
|
self.widget("snapshot-new-name").set_text(default_name)
|
||||||
self.widget("snapshot-new-name").emit("changed")
|
self.widget("snapshot-new-name").emit("changed")
|
||||||
@ -210,8 +214,8 @@ class vmmSnapshotNew(vmmGObjectUI):
|
|||||||
newsnap = DomainSnapshot(self.vm.conn.get_backend())
|
newsnap = DomainSnapshot(self.vm.conn.get_backend())
|
||||||
newsnap.name = name
|
newsnap.name = name
|
||||||
newsnap.description = desc or None
|
newsnap.description = desc or None
|
||||||
newsnap.validate()
|
|
||||||
newsnap.get_xml()
|
newsnap.get_xml()
|
||||||
|
newsnap.validate_generic_name(_("Snapshot"), newsnap.name)
|
||||||
return newsnap
|
return newsnap
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return self.err.val_err(_("Error validating snapshot: %s") % e)
|
return self.err.val_err(_("Error validating snapshot: %s") % e)
|
||||||
|
@ -90,62 +90,6 @@ class _DeviceChar(Device):
|
|||||||
CHANNEL_NAME_LIBGUESTFS,
|
CHANNEL_NAME_LIBGUESTFS,
|
||||||
CHANNEL_NAME_SPICE_WEBDAV]
|
CHANNEL_NAME_SPICE_WEBDAV]
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_recommended_types(cls, _guest):
|
|
||||||
if cls.XML_NAME == "console":
|
|
||||||
return [cls.TYPE_PTY]
|
|
||||||
|
|
||||||
ret = [cls.TYPE_PTY, cls.TYPE_FILE, cls.TYPE_UNIX]
|
|
||||||
if cls.XML_NAME == "channel":
|
|
||||||
ret = [cls.TYPE_SPICEVMC, cls.TYPE_SPICEPORT] + ret
|
|
||||||
return ret
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def pretty_channel_name(val):
|
|
||||||
if val == _DeviceChar.CHANNEL_NAME_SPICE:
|
|
||||||
return "spice"
|
|
||||||
if val == _DeviceChar.CHANNEL_NAME_QEMUGA:
|
|
||||||
return "qemu-ga"
|
|
||||||
if val == _DeviceChar.CHANNEL_NAME_LIBGUESTFS:
|
|
||||||
return "libguestfs"
|
|
||||||
if val == _DeviceChar.CHANNEL_NAME_SPICE_WEBDAV:
|
|
||||||
return "spice-webdav"
|
|
||||||
return None
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def pretty_type(ctype):
|
|
||||||
"""
|
|
||||||
Return a human readable description of the passed char type
|
|
||||||
"""
|
|
||||||
desc = ""
|
|
||||||
|
|
||||||
if ctype == _DeviceChar.TYPE_PTY:
|
|
||||||
desc = _("Pseudo TTY")
|
|
||||||
elif ctype == _DeviceChar.TYPE_DEV:
|
|
||||||
desc = _("Physical host character device")
|
|
||||||
elif ctype == _DeviceChar.TYPE_STDIO:
|
|
||||||
desc = _("Standard input/output")
|
|
||||||
elif ctype == _DeviceChar.TYPE_PIPE:
|
|
||||||
desc = _("Named pipe")
|
|
||||||
elif ctype == _DeviceChar.TYPE_FILE:
|
|
||||||
desc = _("Output to a file")
|
|
||||||
elif ctype == _DeviceChar.TYPE_VC:
|
|
||||||
desc = _("Virtual console")
|
|
||||||
elif ctype == _DeviceChar.TYPE_NULL:
|
|
||||||
desc = _("Null device")
|
|
||||||
elif ctype == _DeviceChar.TYPE_TCP:
|
|
||||||
desc = _("TCP net console")
|
|
||||||
elif ctype == _DeviceChar.TYPE_UDP:
|
|
||||||
desc = _("UDP net console")
|
|
||||||
elif ctype == _DeviceChar.TYPE_UNIX:
|
|
||||||
desc = _("Unix socket")
|
|
||||||
elif ctype == _DeviceChar.TYPE_SPICEVMC:
|
|
||||||
desc = _("Spice agent")
|
|
||||||
elif ctype == _DeviceChar.TYPE_SPICEPORT:
|
|
||||||
desc = _("Spice port")
|
|
||||||
|
|
||||||
return desc
|
|
||||||
|
|
||||||
def set_friendly_target(self, val):
|
def set_friendly_target(self, val):
|
||||||
_set_host_helper(self, "target_address", "target_port", val)
|
_set_host_helper(self, "target_address", "target_port", val)
|
||||||
|
|
||||||
|
@ -21,31 +21,6 @@ class DeviceController(Device):
|
|||||||
TYPE_CCID = "ccid"
|
TYPE_CCID = "ccid"
|
||||||
TYPE_XENBUS = "xenbus"
|
TYPE_XENBUS = "xenbus"
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_recommended_types(_guest):
|
|
||||||
return [DeviceController.TYPE_SCSI,
|
|
||||||
DeviceController.TYPE_USB,
|
|
||||||
DeviceController.TYPE_VIRTIOSERIAL,
|
|
||||||
DeviceController.TYPE_CCID]
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def pretty_type(ctype):
|
|
||||||
pretty_mappings = {
|
|
||||||
DeviceController.TYPE_IDE: "IDE",
|
|
||||||
DeviceController.TYPE_FDC: _("Floppy"),
|
|
||||||
DeviceController.TYPE_SCSI: "SCSI",
|
|
||||||
DeviceController.TYPE_SATA: "SATA",
|
|
||||||
DeviceController.TYPE_VIRTIOSERIAL: "VirtIO Serial",
|
|
||||||
DeviceController.TYPE_USB: "USB",
|
|
||||||
DeviceController.TYPE_PCI: "PCI",
|
|
||||||
DeviceController.TYPE_CCID: "CCID",
|
|
||||||
DeviceController.TYPE_XENBUS: "xenbus",
|
|
||||||
}
|
|
||||||
|
|
||||||
if ctype not in pretty_mappings:
|
|
||||||
return ctype
|
|
||||||
return pretty_mappings[ctype]
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_usb2_controllers(conn):
|
def get_usb2_controllers(conn):
|
||||||
ret = []
|
ret = []
|
||||||
@ -101,17 +76,6 @@ class DeviceController(Device):
|
|||||||
|
|
||||||
index = XMLProperty("./@index", is_int=True)
|
index = XMLProperty("./@index", is_int=True)
|
||||||
|
|
||||||
def pretty_desc(self):
|
|
||||||
ret = self.pretty_type(self.type)
|
|
||||||
if self.type == "scsi":
|
|
||||||
if self.model == "virtio-scsi":
|
|
||||||
ret = "Virtio " + ret
|
|
||||||
elif self.address.type == "spapr-vio":
|
|
||||||
ret = "sPAPR " + ret
|
|
||||||
if self.type == "pci" and self.model == "pcie-root":
|
|
||||||
ret = "PCIe"
|
|
||||||
return ret
|
|
||||||
|
|
||||||
|
|
||||||
##################
|
##################
|
||||||
# Default config #
|
# Default config #
|
||||||
|
@ -77,54 +77,6 @@ class DeviceDisk(Device):
|
|||||||
IO_MODE_THREADS = "threads"
|
IO_MODE_THREADS = "threads"
|
||||||
IO_MODES = [IO_MODE_NATIVE, IO_MODE_THREADS]
|
IO_MODES = [IO_MODE_NATIVE, IO_MODE_THREADS]
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_old_recommended_buses(guest):
|
|
||||||
ret = []
|
|
||||||
if guest.os.is_hvm() or guest.conn.is_test():
|
|
||||||
if not guest.os.is_q35():
|
|
||||||
ret.append("ide")
|
|
||||||
ret.append("sata")
|
|
||||||
ret.append("fdc")
|
|
||||||
ret.append("scsi")
|
|
||||||
ret.append("usb")
|
|
||||||
|
|
||||||
if guest.type in ["qemu", "kvm", "test"]:
|
|
||||||
ret.append("sd")
|
|
||||||
ret.append("virtio")
|
|
||||||
if "scsi" not in ret:
|
|
||||||
ret.append("scsi")
|
|
||||||
|
|
||||||
if guest.conn.is_xen() or guest.conn.is_test():
|
|
||||||
ret.append("xen")
|
|
||||||
|
|
||||||
return ret
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_recommended_buses(guest, domcaps, devtype):
|
|
||||||
# try to get supported disk bus types from domain capabilities
|
|
||||||
if "bus" in domcaps.devices.disk.enum_names():
|
|
||||||
buses = domcaps.devices.disk.get_enum("bus").get_values()
|
|
||||||
else:
|
|
||||||
buses = DeviceDisk.get_old_recommended_buses(guest)
|
|
||||||
|
|
||||||
bus_map = {
|
|
||||||
"disk": ["ide", "sata", "scsi", "sd", "usb", "virtio", "xen"],
|
|
||||||
"floppy": ["fdc"],
|
|
||||||
"cdrom": ["ide", "sata", "scsi"],
|
|
||||||
"lun": ["scsi"],
|
|
||||||
}
|
|
||||||
return [bus for bus in buses if bus in bus_map.get(devtype, [])]
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def pretty_disk_bus(bus):
|
|
||||||
if bus in ["ide", "sata", "scsi", "usb", "sd"]:
|
|
||||||
return bus.upper()
|
|
||||||
if bus in ["xen"]:
|
|
||||||
return bus.capitalize()
|
|
||||||
if bus == "virtio":
|
|
||||||
return "VirtIO"
|
|
||||||
return bus
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def path_definitely_exists(conn, path):
|
def path_definitely_exists(conn, path):
|
||||||
"""
|
"""
|
||||||
|
@ -72,15 +72,6 @@ class DeviceGraphics(Device):
|
|||||||
|
|
||||||
return sort_list
|
return sort_list
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def pretty_type_simple(gtype):
|
|
||||||
if (gtype in [DeviceGraphics.TYPE_VNC,
|
|
||||||
DeviceGraphics.TYPE_SDL,
|
|
||||||
DeviceGraphics.TYPE_RDP]):
|
|
||||||
return str(gtype).upper()
|
|
||||||
|
|
||||||
return str(gtype).capitalize()
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
Device.__init__(self, *args, **kwargs)
|
Device.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
|
@ -68,34 +68,6 @@ class DeviceHostdev(Device):
|
|||||||
else:
|
else:
|
||||||
raise ValueError(_("Unknown node device type %s") % nodedev)
|
raise ValueError(_("Unknown node device type %s") % nodedev)
|
||||||
|
|
||||||
def pretty_name(self):
|
|
||||||
def dehex(val):
|
|
||||||
if val.startswith("0x"):
|
|
||||||
val = val[2:]
|
|
||||||
return val
|
|
||||||
|
|
||||||
def safeint(val, fmt="%.3d"):
|
|
||||||
try:
|
|
||||||
int(val)
|
|
||||||
except Exception:
|
|
||||||
return str(val)
|
|
||||||
return fmt % int(val)
|
|
||||||
|
|
||||||
label = self.type.upper()
|
|
||||||
|
|
||||||
if self.vendor and self.product:
|
|
||||||
label += " %s:%s" % (dehex(self.vendor), dehex(self.product))
|
|
||||||
|
|
||||||
elif self.bus and self.device:
|
|
||||||
label += " %s:%s" % (safeint(self.bus), safeint(self.device))
|
|
||||||
|
|
||||||
elif self.bus and self.slot and self.function and self.domain:
|
|
||||||
label += (" %s:%s:%s.%s" %
|
|
||||||
(dehex(self.domain), dehex(self.bus),
|
|
||||||
dehex(self.slot), dehex(self.function)))
|
|
||||||
|
|
||||||
return label
|
|
||||||
|
|
||||||
|
|
||||||
_XML_PROP_ORDER = ["mode", "type", "managed", "vendor", "product",
|
_XML_PROP_ORDER = ["mode", "type", "managed", "vendor", "product",
|
||||||
"domain", "bus", "slot", "function"]
|
"domain", "bus", "slot", "function"]
|
||||||
|
@ -20,16 +20,6 @@ class DeviceInput(Device):
|
|||||||
BUS_VIRTIO = "virtio"
|
BUS_VIRTIO = "virtio"
|
||||||
BUS_XEN = "xen"
|
BUS_XEN = "xen"
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def pretty_name(typ, bus):
|
|
||||||
if typ == "tablet" and bus == "usb":
|
|
||||||
return _("EvTouch USB Graphics Tablet")
|
|
||||||
|
|
||||||
if bus in ["usb", "ps2"]:
|
|
||||||
return _("Generic") + (" %s %s" %
|
|
||||||
(bus.upper(), str(typ).capitalize()))
|
|
||||||
return "%s %s" % (str(bus).capitalize(), str(typ).capitalize())
|
|
||||||
|
|
||||||
|
|
||||||
type = XMLProperty("./@type")
|
type = XMLProperty("./@type")
|
||||||
bus = XMLProperty("./@bus")
|
bus = XMLProperty("./@bus")
|
||||||
|
@ -117,42 +117,6 @@ class DeviceInterface(Device):
|
|||||||
TYPE_ETHERNET = "ethernet"
|
TYPE_ETHERNET = "ethernet"
|
||||||
TYPE_DIRECT = "direct"
|
TYPE_DIRECT = "direct"
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_models(guest):
|
|
||||||
if not guest.os.is_hvm():
|
|
||||||
return []
|
|
||||||
|
|
||||||
ret = []
|
|
||||||
if guest.type in ["kvm", "qemu", "vz", "test"]:
|
|
||||||
ret.append("virtio")
|
|
||||||
if guest.os.is_x86():
|
|
||||||
if guest.os.is_q35():
|
|
||||||
ret.append("e1000e")
|
|
||||||
else:
|
|
||||||
ret.append("rtl8139")
|
|
||||||
ret.append("e1000")
|
|
||||||
if guest.type in ["xen", "test"]:
|
|
||||||
ret.append("netfront")
|
|
||||||
|
|
||||||
ret.sort()
|
|
||||||
return ret
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_network_type_desc(net_type):
|
|
||||||
"""
|
|
||||||
Return human readable description for passed network type
|
|
||||||
"""
|
|
||||||
desc = net_type.capitalize()
|
|
||||||
|
|
||||||
if net_type == DeviceInterface.TYPE_BRIDGE:
|
|
||||||
desc = _("Shared physical device")
|
|
||||||
elif net_type == DeviceInterface.TYPE_VIRTUAL:
|
|
||||||
desc = _("Virtual networking")
|
|
||||||
elif net_type == DeviceInterface.TYPE_USER:
|
|
||||||
desc = _("Usermode networking")
|
|
||||||
|
|
||||||
return desc
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def generate_mac(conn):
|
def generate_mac(conn):
|
||||||
"""
|
"""
|
||||||
|
@ -17,29 +17,6 @@ class DevicePanic(Device):
|
|||||||
MODEL_HYPERV = "hyperv"
|
MODEL_HYPERV = "hyperv"
|
||||||
MODEL_S390 = "s390"
|
MODEL_S390 = "s390"
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_pretty_model(panic_model):
|
|
||||||
if panic_model == DevicePanic.MODEL_ISA:
|
|
||||||
return _("ISA")
|
|
||||||
elif panic_model == DevicePanic.MODEL_PSERIES:
|
|
||||||
return _("pSeries")
|
|
||||||
elif panic_model == DevicePanic.MODEL_HYPERV:
|
|
||||||
return _("Hyper-V")
|
|
||||||
elif panic_model == DevicePanic.MODEL_S390:
|
|
||||||
return _("s390")
|
|
||||||
return panic_model
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_models(os):
|
|
||||||
if os.is_x86():
|
|
||||||
return [DevicePanic.MODEL_ISA,
|
|
||||||
DevicePanic.MODEL_HYPERV]
|
|
||||||
elif os.is_pseries():
|
|
||||||
return [DevicePanic.MODEL_PSERIES]
|
|
||||||
elif os.is_s390x():
|
|
||||||
return [DevicePanic.MODEL_S390]
|
|
||||||
return []
|
|
||||||
|
|
||||||
model = XMLProperty("./@model")
|
model = XMLProperty("./@model")
|
||||||
|
|
||||||
|
|
||||||
@ -47,9 +24,20 @@ class DevicePanic(Device):
|
|||||||
# Default config #
|
# Default config #
|
||||||
##################
|
##################
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_models(guest):
|
||||||
|
if guest.os.is_x86():
|
||||||
|
return [DevicePanic.MODEL_ISA,
|
||||||
|
DevicePanic.MODEL_HYPERV]
|
||||||
|
elif guest.os.is_pseries():
|
||||||
|
return [DevicePanic.MODEL_PSERIES]
|
||||||
|
elif guest.os.is_s390x():
|
||||||
|
return [DevicePanic.MODEL_S390]
|
||||||
|
return []
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_default_model(guest):
|
def get_default_model(guest):
|
||||||
models = DevicePanic.get_models(guest.os)
|
models = DevicePanic.get_models(guest)
|
||||||
if models:
|
if models:
|
||||||
return models[0]
|
return models[0]
|
||||||
return None
|
return None
|
||||||
|
@ -12,14 +12,6 @@ from ..xmlbuilder import XMLChildProperty, XMLProperty
|
|||||||
class DeviceRedirdev(Device):
|
class DeviceRedirdev(Device):
|
||||||
XML_NAME = "redirdev"
|
XML_NAME = "redirdev"
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def pretty_type(typ):
|
|
||||||
if typ == "tcp":
|
|
||||||
return "TCP"
|
|
||||||
if typ == "spicevmc":
|
|
||||||
return "SpiceVMC"
|
|
||||||
return typ and typ.capitalize()
|
|
||||||
|
|
||||||
_XML_PROP_ORDER = ["bus", "type", "source"]
|
_XML_PROP_ORDER = ["bus", "type", "source"]
|
||||||
|
|
||||||
bus = XMLProperty("./@bus")
|
bus = XMLProperty("./@bus")
|
||||||
|
@ -15,24 +15,6 @@ class DeviceRng(Device):
|
|||||||
TYPE_RANDOM = "random"
|
TYPE_RANDOM = "random"
|
||||||
TYPE_EGD = "egd"
|
TYPE_EGD = "egd"
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_pretty_type(rng_type):
|
|
||||||
if rng_type == DeviceRng.TYPE_RANDOM:
|
|
||||||
return _("Random")
|
|
||||||
if rng_type == DeviceRng.TYPE_EGD:
|
|
||||||
return _("Entropy Gathering Daemon")
|
|
||||||
return rng_type
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_pretty_backend_type(backend_type):
|
|
||||||
return {"udp": "UDP",
|
|
||||||
"tcp": "TCP"}.get(backend_type) or backend_type
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_pretty_mode(mode):
|
|
||||||
return {"bind": _("Bind"),
|
|
||||||
"connect": _("Connect")}.get(mode) or mode
|
|
||||||
|
|
||||||
model = XMLProperty("./@model")
|
model = XMLProperty("./@model")
|
||||||
|
|
||||||
backend_model = XMLProperty("./backend/@model")
|
backend_model = XMLProperty("./backend/@model")
|
||||||
|
@ -20,18 +20,6 @@ class _Codec(XMLBuilder):
|
|||||||
class DeviceSound(Device):
|
class DeviceSound(Device):
|
||||||
XML_NAME = "sound"
|
XML_NAME = "sound"
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_recommended_models(_guest):
|
|
||||||
return ["ich6", "ich9", "ac97"]
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def pretty_model(model):
|
|
||||||
ret = model.upper()
|
|
||||||
if model in ["ich6", "ich9"]:
|
|
||||||
ret = "HDA (%s)" % model.upper()
|
|
||||||
return ret
|
|
||||||
|
|
||||||
|
|
||||||
model = XMLProperty("./@model")
|
model = XMLProperty("./@model")
|
||||||
codecs = XMLChildProperty(_Codec)
|
codecs = XMLChildProperty(_Codec)
|
||||||
|
|
||||||
|
@ -24,22 +24,6 @@ class DeviceTpm(Device):
|
|||||||
MODEL_CRB = "tpm-crb"
|
MODEL_CRB = "tpm-crb"
|
||||||
MODELS = [MODEL_TIS, MODEL_CRB]
|
MODELS = [MODEL_TIS, MODEL_CRB]
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_pretty_type(tpm_type):
|
|
||||||
if tpm_type == DeviceTpm.TYPE_PASSTHROUGH:
|
|
||||||
return _("Passthrough device")
|
|
||||||
if tpm_type == DeviceTpm.TYPE_EMULATOR:
|
|
||||||
return _("Emulated device")
|
|
||||||
return tpm_type
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_pretty_model(tpm_model):
|
|
||||||
if tpm_model == DeviceTpm.MODEL_TIS:
|
|
||||||
return _("TIS")
|
|
||||||
if tpm_model == DeviceTpm.MODEL_CRB:
|
|
||||||
return _("CRB")
|
|
||||||
return tpm_model
|
|
||||||
|
|
||||||
type = XMLProperty("./backend/@type")
|
type = XMLProperty("./backend/@type")
|
||||||
version = XMLProperty("./backend/@version")
|
version = XMLProperty("./backend/@version")
|
||||||
model = XMLProperty("./@model")
|
model = XMLProperty("./@model")
|
||||||
|
@ -11,20 +11,6 @@ from ..xmlbuilder import XMLProperty
|
|||||||
class DeviceVideo(Device):
|
class DeviceVideo(Device):
|
||||||
XML_NAME = "video"
|
XML_NAME = "video"
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_recommended_models(guest):
|
|
||||||
if guest.conn.is_xen():
|
|
||||||
return ["xen", "vga"]
|
|
||||||
if guest.conn.is_qemu() or guest.conn.is_test():
|
|
||||||
return ["vga", "qxl", "virtio"]
|
|
||||||
return []
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def pretty_model(model):
|
|
||||||
if model in ["qxl", "vmvga", "vga"]:
|
|
||||||
return model.upper()
|
|
||||||
return model.capitalize()
|
|
||||||
|
|
||||||
_XML_PROP_ORDER = ["model", "vram", "heads", "vgamem"]
|
_XML_PROP_ORDER = ["model", "vram", "heads", "vgamem"]
|
||||||
model = XMLProperty("./model/@type")
|
model = XMLProperty("./model/@type")
|
||||||
vram = XMLProperty("./model/@vram", is_int=True)
|
vram = XMLProperty("./model/@vram", is_int=True)
|
||||||
|
@ -26,22 +26,6 @@ class DeviceWatchdog(Device):
|
|||||||
ACTION_POWEROFF, ACTION_PAUSE,
|
ACTION_POWEROFF, ACTION_PAUSE,
|
||||||
ACTION_DUMP, ACTION_NONE]
|
ACTION_DUMP, ACTION_NONE]
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_action_desc(action):
|
|
||||||
if action == DeviceWatchdog.ACTION_RESET:
|
|
||||||
return _("Forcefully reset the guest")
|
|
||||||
if action == DeviceWatchdog.ACTION_SHUTDOWN:
|
|
||||||
return _("Gracefully shutdown the guest")
|
|
||||||
if action == DeviceWatchdog.ACTION_POWEROFF:
|
|
||||||
return _("Forcefully power off the guest")
|
|
||||||
if action == DeviceWatchdog.ACTION_PAUSE:
|
|
||||||
return _("Pause the guest")
|
|
||||||
if action == DeviceWatchdog.ACTION_NONE:
|
|
||||||
return _("No action")
|
|
||||||
if action == DeviceWatchdog.ACTION_DUMP:
|
|
||||||
return _("Dump guest memory core")
|
|
||||||
return action
|
|
||||||
|
|
||||||
_XML_PROP_ORDER = ["model", "action"]
|
_XML_PROP_ORDER = ["model", "action"]
|
||||||
model = XMLProperty("./@model")
|
model = XMLProperty("./@model")
|
||||||
action = XMLProperty("./@action")
|
action = XMLProperty("./@action")
|
||||||
|
@ -7,11 +7,6 @@
|
|||||||
Classes for building and installing libvirt <network> XML
|
Classes for building and installing libvirt <network> XML
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
import libvirt
|
|
||||||
|
|
||||||
from . import generatename
|
|
||||||
from .xmlbuilder import XMLBuilder, XMLChildProperty, XMLProperty
|
from .xmlbuilder import XMLBuilder, XMLChildProperty, XMLProperty
|
||||||
|
|
||||||
|
|
||||||
@ -77,9 +72,6 @@ class _NetworkForward(XMLBuilder):
|
|||||||
pf = XMLChildProperty(_NetworkForwardPf)
|
pf = XMLChildProperty(_NetworkForwardPf)
|
||||||
vfs = XMLChildProperty(_NetworkForwardAddress)
|
vfs = XMLChildProperty(_NetworkForwardAddress)
|
||||||
|
|
||||||
def pretty_desc(self):
|
|
||||||
return Network.pretty_forward_desc(self.mode, self.dev)
|
|
||||||
|
|
||||||
|
|
||||||
class _NetworkBandwidth(XMLBuilder):
|
class _NetworkBandwidth(XMLBuilder):
|
||||||
XML_NAME = "bandwidth"
|
XML_NAME = "bandwidth"
|
||||||
@ -93,45 +85,6 @@ class _NetworkBandwidth(XMLBuilder):
|
|||||||
outbound_peak = XMLProperty("./outbound/@peak")
|
outbound_peak = XMLProperty("./outbound/@peak")
|
||||||
outbound_burst = XMLProperty("./outbound/@burst")
|
outbound_burst = XMLProperty("./outbound/@burst")
|
||||||
|
|
||||||
def is_inbound(self):
|
|
||||||
return bool(self.inbound_average or self.inbound_peak or
|
|
||||||
self.inbound_burst or self.inbound_floor)
|
|
||||||
|
|
||||||
def is_outbound(self):
|
|
||||||
return bool(self.outbound_average or self.outbound_peak or
|
|
||||||
self.outbound_burst)
|
|
||||||
|
|
||||||
def pretty_desc(self, inbound=True, outbound=True):
|
|
||||||
items_in = [(self.inbound_average, _("Average"), "KiB/s"),
|
|
||||||
(self.inbound_peak, _("Peak"), "KiB"),
|
|
||||||
(self.inbound_burst, _("Burst"), "KiB/s"),
|
|
||||||
(self.inbound_floor, _("Floor"), "KiB/s")]
|
|
||||||
|
|
||||||
items_out = [(self.outbound_average, _("Average"), "KiB/s"),
|
|
||||||
(self.outbound_peak, _("Peak"), "KiB"),
|
|
||||||
(self.outbound_burst, _("Burst"), "KiB/s")]
|
|
||||||
|
|
||||||
def stringify_items(items):
|
|
||||||
return ", ".join(["%s: %s %s" % (desc, val, unit)
|
|
||||||
for val, desc, unit in items if val])
|
|
||||||
|
|
||||||
ret = ""
|
|
||||||
show_name = inbound and outbound
|
|
||||||
|
|
||||||
if inbound:
|
|
||||||
if show_name:
|
|
||||||
ret += _("Inbound: ")
|
|
||||||
ret += stringify_items(items_in)
|
|
||||||
|
|
||||||
if outbound:
|
|
||||||
if ret:
|
|
||||||
ret += "\n"
|
|
||||||
if show_name:
|
|
||||||
ret += _("Outbound: ")
|
|
||||||
ret += stringify_items(items_out)
|
|
||||||
|
|
||||||
return ret
|
|
||||||
|
|
||||||
|
|
||||||
class _NetworkPortgroup(XMLBuilder):
|
class _NetworkPortgroup(XMLBuilder):
|
||||||
XML_NAME = "portgroup"
|
XML_NAME = "portgroup"
|
||||||
@ -144,70 +97,6 @@ class Network(XMLBuilder):
|
|||||||
"""
|
"""
|
||||||
Top level class for <network> object XML
|
Top level class for <network> object XML
|
||||||
"""
|
"""
|
||||||
@staticmethod
|
|
||||||
def find_free_name(conn, basename, **kwargs):
|
|
||||||
cb = conn.networkLookupByName
|
|
||||||
return generatename.generate_name(basename, cb, **kwargs)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def pretty_forward_desc(mode, dev):
|
|
||||||
if not mode:
|
|
||||||
return _("Isolated network")
|
|
||||||
|
|
||||||
if mode == "nat":
|
|
||||||
if dev:
|
|
||||||
desc = _("NAT to %s") % dev
|
|
||||||
else:
|
|
||||||
desc = _("NAT")
|
|
||||||
elif mode == "route":
|
|
||||||
if dev:
|
|
||||||
desc = _("Route to %s") % dev
|
|
||||||
else:
|
|
||||||
desc = _("Routed network")
|
|
||||||
else:
|
|
||||||
modestr = mode.capitalize()
|
|
||||||
if dev:
|
|
||||||
desc = (_("%(mode)s to %(device)s") %
|
|
||||||
{"mode": modestr, "device": dev})
|
|
||||||
else:
|
|
||||||
desc = _("%s network") % modestr
|
|
||||||
|
|
||||||
return desc
|
|
||||||
|
|
||||||
|
|
||||||
###################
|
|
||||||
# Helper routines #
|
|
||||||
###################
|
|
||||||
|
|
||||||
def can_pxe(self):
|
|
||||||
forward = self.forward.mode
|
|
||||||
if forward and forward != "nat":
|
|
||||||
return True
|
|
||||||
for ip in self.ips:
|
|
||||||
if ip.bootp_file:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
######################
|
|
||||||
# Validation helpers #
|
|
||||||
######################
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def validate_name(conn, name):
|
|
||||||
XMLBuilder.validate_generic_name(_("Network"), name)
|
|
||||||
|
|
||||||
try:
|
|
||||||
conn.networkLookupByName(name)
|
|
||||||
except libvirt.libvirtError:
|
|
||||||
return
|
|
||||||
raise ValueError(_("Name '%s' already in use by another network." %
|
|
||||||
name))
|
|
||||||
|
|
||||||
|
|
||||||
##################
|
|
||||||
# XML properties #
|
|
||||||
##################
|
|
||||||
|
|
||||||
XML_NAME = "network"
|
XML_NAME = "network"
|
||||||
_XML_PROP_ORDER = ["ipv6", "name", "uuid", "forward", "virtualport_type",
|
_XML_PROP_ORDER = ["ipv6", "name", "uuid", "forward", "virtualport_type",
|
||||||
"bridge", "stp", "delay", "domain_name",
|
"bridge", "stp", "delay", "domain_name",
|
||||||
@ -235,23 +124,15 @@ class Network(XMLBuilder):
|
|||||||
bandwidth = XMLChildProperty(_NetworkBandwidth, is_single=True)
|
bandwidth = XMLChildProperty(_NetworkBandwidth, is_single=True)
|
||||||
|
|
||||||
|
|
||||||
##################
|
###################
|
||||||
# build routines #
|
# Helper routines #
|
||||||
##################
|
###################
|
||||||
|
|
||||||
def install(self, start=True, autostart=True):
|
def can_pxe(self):
|
||||||
xml = self.get_xml()
|
forward = self.forward.mode
|
||||||
logging.debug("Creating virtual network '%s' with xml:\n%s",
|
if forward and forward != "nat":
|
||||||
self.name, xml)
|
return True
|
||||||
|
for ip in self.ips:
|
||||||
net = self.conn.networkDefineXML(xml)
|
if ip.bootp_file:
|
||||||
try:
|
return True
|
||||||
if start:
|
return False
|
||||||
net.create()
|
|
||||||
if autostart:
|
|
||||||
net.setAutostart(autostart)
|
|
||||||
except Exception:
|
|
||||||
net.undefine()
|
|
||||||
raise
|
|
||||||
|
|
||||||
return net
|
|
||||||
|
@ -106,68 +106,6 @@ class NodeDevice(XMLBuilder):
|
|||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _usb_pretty_name(self):
|
|
||||||
# Hypervisor may return a rather sparse structure, missing
|
|
||||||
# some ol all stringular descriptions of the device altogether.
|
|
||||||
# Do our best to help user identify the device.
|
|
||||||
|
|
||||||
# Certain devices pad their vendor with trailing spaces,
|
|
||||||
# such as "LENOVO ". It does not look well.
|
|
||||||
product = str(self._product_name).strip()
|
|
||||||
vendor = str(self._vendor_name).strip()
|
|
||||||
|
|
||||||
if product == "":
|
|
||||||
product = str(self.product_id)
|
|
||||||
if vendor == "":
|
|
||||||
# No stringular descriptions altogether
|
|
||||||
vendor = str(self.vendor_id)
|
|
||||||
devstr = "%s:%s" % (vendor, product)
|
|
||||||
else:
|
|
||||||
# Only the vendor is known
|
|
||||||
devstr = "%s %s" % (vendor, product)
|
|
||||||
else:
|
|
||||||
if vendor == "":
|
|
||||||
# Sometimes vendor is left out empty, but product is
|
|
||||||
# already descriptive enough or contains the vendor string:
|
|
||||||
# "Lenovo USB Laser Mouse"
|
|
||||||
devstr = product
|
|
||||||
else:
|
|
||||||
# We know everything. Perfect.
|
|
||||||
devstr = "%s %s" % (vendor, product)
|
|
||||||
|
|
||||||
busstr = "%.3d:%.3d" % (int(self.bus), int(self.device))
|
|
||||||
desc = "%s %s" % (busstr, devstr)
|
|
||||||
return desc
|
|
||||||
|
|
||||||
def pretty_name(self):
|
|
||||||
"""
|
|
||||||
Use device information to attempt to print a human readable device
|
|
||||||
name.
|
|
||||||
|
|
||||||
:returns: Device description string
|
|
||||||
"""
|
|
||||||
if self.device_type == "net":
|
|
||||||
if self.interface:
|
|
||||||
return _("Interface %s") % self.interface
|
|
||||||
return self.name
|
|
||||||
|
|
||||||
if self.device_type == "pci":
|
|
||||||
devstr = "%.4X:%.2X:%.2X:%X" % (int(self.domain),
|
|
||||||
int(self.bus),
|
|
||||||
int(self.slot),
|
|
||||||
int(self.function))
|
|
||||||
return "%s %s %s" % (devstr,
|
|
||||||
self._vendor_name, self._product_name)
|
|
||||||
if self.device_type == "usb_device":
|
|
||||||
return self._usb_pretty_name()
|
|
||||||
|
|
||||||
if self.device_type == "drm":
|
|
||||||
parent = NodeDevice.lookupNodedevFromString(
|
|
||||||
self.conn, self.parent)
|
|
||||||
return "%s (%s)" % (parent.pretty_name(), self._drm_type)
|
|
||||||
|
|
||||||
return self.name
|
|
||||||
|
|
||||||
|
|
||||||
########################
|
########################
|
||||||
# XML helper functions #
|
# XML helper functions #
|
||||||
@ -183,7 +121,7 @@ class NodeDevice(XMLBuilder):
|
|||||||
self.product_id in ["0x0001", "0x0002", "0x0003"])
|
self.product_id in ["0x0001", "0x0002", "0x0003"])
|
||||||
|
|
||||||
def is_drm_render(self):
|
def is_drm_render(self):
|
||||||
return self.device_type == "drm" and self._drm_type == "render"
|
return self.device_type == "drm" and self.drm_type == "render"
|
||||||
|
|
||||||
|
|
||||||
##################
|
##################
|
||||||
@ -198,8 +136,8 @@ class NodeDevice(XMLBuilder):
|
|||||||
bus = XMLProperty("./capability/bus")
|
bus = XMLProperty("./capability/bus")
|
||||||
slot = XMLProperty("./capability/slot")
|
slot = XMLProperty("./capability/slot")
|
||||||
function = XMLProperty("./capability/function")
|
function = XMLProperty("./capability/function")
|
||||||
_product_name = XMLProperty("./capability/product")
|
product_name = XMLProperty("./capability/product")
|
||||||
_vendor_name = XMLProperty("./capability/vendor")
|
vendor_name = XMLProperty("./capability/vendor")
|
||||||
_capability_type = XMLProperty("./capability/capability/@type")
|
_capability_type = XMLProperty("./capability/capability/@type")
|
||||||
|
|
||||||
# type='usb' options
|
# type='usb' options
|
||||||
@ -223,7 +161,7 @@ class NodeDevice(XMLBuilder):
|
|||||||
is_int=True)
|
is_int=True)
|
||||||
|
|
||||||
# type='drm' options
|
# type='drm' options
|
||||||
_drm_type = XMLProperty("./capability/type")
|
drm_type = XMLProperty("./capability/type")
|
||||||
devnodes = XMLChildProperty(DevNode)
|
devnodes = XMLChildProperty(DevNode)
|
||||||
|
|
||||||
def get_devnode(self, parent="by-path"):
|
def get_devnode(self, parent="by-path"):
|
||||||
|
@ -4,9 +4,6 @@
|
|||||||
# This work is licensed under the GNU GPLv2 or later.
|
# This work is licensed under the GNU GPLv2 or later.
|
||||||
# See the COPYING file in the top-level directory.
|
# See the COPYING file in the top-level directory.
|
||||||
|
|
||||||
import libvirt
|
|
||||||
|
|
||||||
from . import generatename
|
|
||||||
from .xmlbuilder import XMLBuilder, XMLChildProperty, XMLProperty
|
from .xmlbuilder import XMLBuilder, XMLChildProperty, XMLProperty
|
||||||
|
|
||||||
|
|
||||||
@ -17,30 +14,6 @@ class _SnapshotDisk(XMLBuilder):
|
|||||||
|
|
||||||
|
|
||||||
class DomainSnapshot(XMLBuilder):
|
class DomainSnapshot(XMLBuilder):
|
||||||
@staticmethod
|
|
||||||
def find_free_name(vm, collidelist):
|
|
||||||
return generatename.generate_name("snapshot", vm.snapshotLookupByName,
|
|
||||||
sep="", start_num=1, force_num=True,
|
|
||||||
collidelist=collidelist)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def state_str_to_int(state):
|
|
||||||
statemap = {
|
|
||||||
"nostate": libvirt.VIR_DOMAIN_NOSTATE,
|
|
||||||
"running": libvirt.VIR_DOMAIN_RUNNING,
|
|
||||||
"blocked": libvirt.VIR_DOMAIN_BLOCKED,
|
|
||||||
"paused": libvirt.VIR_DOMAIN_PAUSED,
|
|
||||||
"shutdown": libvirt.VIR_DOMAIN_SHUTDOWN,
|
|
||||||
"shutoff": libvirt.VIR_DOMAIN_SHUTOFF,
|
|
||||||
"crashed": libvirt.VIR_DOMAIN_CRASHED,
|
|
||||||
"pmsuspended": getattr(libvirt, "VIR_DOMAIN_PMSUSPENDED", 7)
|
|
||||||
}
|
|
||||||
|
|
||||||
if state == "disk-snapshot" or state not in statemap:
|
|
||||||
state = "shutoff"
|
|
||||||
return statemap.get(state, libvirt.VIR_DOMAIN_NOSTATE)
|
|
||||||
|
|
||||||
|
|
||||||
XML_NAME = "domainsnapshot"
|
XML_NAME = "domainsnapshot"
|
||||||
_XML_PROP_ORDER = ["name", "description", "creationTime"]
|
_XML_PROP_ORDER = ["name", "description", "creationTime"]
|
||||||
|
|
||||||
@ -53,12 +26,3 @@ class DomainSnapshot(XMLBuilder):
|
|||||||
memory_type = XMLProperty("./memory/@snapshot")
|
memory_type = XMLProperty("./memory/@snapshot")
|
||||||
|
|
||||||
disks = XMLChildProperty(_SnapshotDisk, relative_xpath="./disks")
|
disks = XMLChildProperty(_SnapshotDisk, relative_xpath="./disks")
|
||||||
|
|
||||||
|
|
||||||
##################
|
|
||||||
# Public helpers #
|
|
||||||
##################
|
|
||||||
|
|
||||||
def validate(self):
|
|
||||||
if not self.name:
|
|
||||||
raise RuntimeError(_("A name must be specified."))
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user