Move many shared UI functions to addhw static functions

Much of uihelpers is just simple stuff that's shared between addhw
and details UI, so just make it staticmethods in addhw, which details
already has a reference to.
This commit is contained in:
Cole Robinson 2014-01-26 17:09:07 -05:00
parent ad363f9774
commit 20088ab8fb
9 changed files with 532 additions and 537 deletions

View File

@ -176,11 +176,11 @@ class vmmAddHardware(vmmGObjectUI):
# Virtual network list
net_list = self.widget("net-list")
bridge_box = self.widget("net-bridge-box")
uihelpers.init_network_list(net_list, bridge_box)
uihelpers.build_network_list(net_list, bridge_box)
# Network model list
netmodel_list = self.widget("net-model")
uihelpers.build_netmodel_combo(self.vm, netmodel_list)
self.build_network_model_combo(self.vm, netmodel_list)
# Disk bus type
widget = self.widget("config-storage-bustype")
@ -205,10 +205,10 @@ class vmmAddHardware(vmmGObjectUI):
# Disk cache mode
cache_list = self.widget("config-storage-cache")
uihelpers.build_cache_combo(self.vm, cache_list)
self.build_disk_cache_combo(self.vm, cache_list)
# Disk format mode
self.populate_disk_format_combo(True)
self.populate_disk_format_combo_wrapper(True)
# Sparse tooltip
sparse_info = self.widget("config-storage-nosparse-info")
@ -239,7 +239,7 @@ class vmmAddHardware(vmmGObjectUI):
# Sound model list
sound_list = self.widget("sound-model")
uihelpers.build_sound_combo(self.vm, sound_list)
self.build_sound_combo(self.vm, sound_list)
# Host device list
# model = [ Description, nodedev name ]
@ -256,7 +256,7 @@ class vmmAddHardware(vmmGObjectUI):
# Video device
video_dev = self.widget("video-model")
uihelpers.build_video_combo(self.vm, video_dev)
self.build_video_combo(self.vm, video_dev)
# Character dev mode
char_mode = self.widget("char-mode")
@ -297,25 +297,24 @@ class vmmAddHardware(vmmGObjectUI):
# Watchdog widgets
combo = self.widget("watchdog-model")
uihelpers.build_watchdogmodel_combo(self.vm, combo)
self.build_watchdogmodel_combo(self.vm, combo)
combo = self.widget("watchdog-action")
uihelpers.build_watchdogaction_combo(self.vm, combo)
self.build_watchdogaction_combo(self.vm, combo)
# Filesystem widgets
self.fsDetails.set_initial_state()
# Smartcard widgets
combo = self.widget("smartcard-mode")
uihelpers.build_smartcard_mode_combo(self.vm, combo)
self.build_smartcard_mode_combo(self.vm, combo)
# Usbredir widgets
combo = self.widget("usbredir-list")
uihelpers.build_redir_type_combo(self.vm, combo)
self.build_redir_type_combo(self.vm, combo)
# TPM widgets
combo = self.widget("tpm-type")
uihelpers.build_tpm_type_combo(self.vm, combo)
self.build_tpm_type_combo(self.vm, combo)
# RNG widgets
combo = self.widget("rng-type")
@ -418,7 +417,7 @@ class vmmAddHardware(vmmGObjectUI):
not can_alloc and
(_("Disk format '%s' does not support full allocation.") % fmt) or
"")
self.populate_disk_format_combo(True)
self.populate_disk_format_combo_wrapper(True)
self.populate_disk_bus()
# Network init
@ -440,7 +439,7 @@ class vmmAddHardware(vmmGObjectUI):
net_warn.hide()
netmodel = self.widget("net-model")
uihelpers.populate_netmodel_combo(self.vm, netmodel)
self.populate_network_model_combo(self.vm, netmodel)
netmodel.set_active(0)
# Input device init
@ -486,7 +485,7 @@ class vmmAddHardware(vmmGObjectUI):
self.fsDetails.reset_state()
# Video params
uihelpers.populate_video_combo(self.vm, self.widget("video-model"))
self.populate_video_combo(self.vm, self.widget("video-model"))
# TPM paams
self.widget("tpm-device-path").set_text("/dev/tpm0")
@ -512,6 +511,304 @@ class vmmAddHardware(vmmGObjectUI):
self.set_hw_selection(0)
#####################
# Shared UI helpers #
#####################
@staticmethod
def populate_video_combo(vm, combo, no_default=None):
model = combo.get_model()
has_spice = bool([g for g in vm.get_graphics_devices()
if g.type == g.TYPE_SPICE])
has_qxl = bool([v for v in vm.get_video_devices()
if v.model == "qxl"])
model.clear()
tmpdev = virtinst.VirtualVideoDevice(vm.conn.get_backend())
for m in tmpdev.MODELS:
if vm.stable_defaults():
if m == "qxl" and not has_spice and not has_qxl:
# Only list QXL video option when VM has SPICE video
continue
if m == tmpdev.MODEL_DEFAULT and no_default:
continue
model.append([m, tmpdev.pretty_model(m)])
if len(model) > 0:
combo.set_active(0)
@staticmethod
def build_video_combo(vm, combo, no_default=None):
model = Gtk.ListStore(str, str)
combo.set_model(model)
uihelpers.set_combo_text_column(combo, 1)
combo.get_model().set_sort_column_id(1, Gtk.SortType.ASCENDING)
vmmAddHardware.populate_video_combo(vm, combo, no_default)
@staticmethod
def build_sound_combo(vm, combo, no_default=False):
model = Gtk.ListStore(str)
combo.set_model(model)
uihelpers.set_combo_text_column(combo, 0)
model.set_sort_column_id(0, Gtk.SortType.ASCENDING)
stable_defaults = vm.stable_defaults()
stable_soundmodels = ["ich6", "ac97"]
for m in virtinst.VirtualAudio.MODELS:
if m == virtinst.VirtualAudio.MODEL_DEFAULT and no_default:
continue
if (stable_defaults and m not in stable_soundmodels):
continue
model.append([m])
if len(model) > 0:
combo.set_active(0)
@staticmethod
def build_watchdogmodel_combo(vm, combo, no_default=False):
ignore = vm
model = Gtk.ListStore(str)
combo.set_model(model)
uihelpers.set_combo_text_column(combo, 0)
model.set_sort_column_id(0, Gtk.SortType.ASCENDING)
for m in virtinst.VirtualWatchdog.MODELS:
if m == virtinst.VirtualAudio.MODEL_DEFAULT and no_default:
continue
model.append([m])
if len(model) > 0:
combo.set_active(0)
@staticmethod
def build_watchdogaction_combo(vm, combo, no_default=False):
ignore = vm
model = Gtk.ListStore(str, str)
combo.set_model(model)
uihelpers.set_combo_text_column(combo, 1)
model.set_sort_column_id(0, Gtk.SortType.ASCENDING)
for m in virtinst.VirtualWatchdog.ACTIONS:
if m == virtinst.VirtualWatchdog.ACTION_DEFAULT and no_default:
continue
model.append([m, virtinst.VirtualWatchdog.get_action_desc(m)])
if len(model) > 0:
combo.set_active(0)
@staticmethod
def populate_network_source_mode_combo(vm, combo):
ignore = vm
model = combo.get_model()
model.clear()
# [xml value, label]
model.append([None, "Default"])
model.append(["vepa", "VEPA"])
model.append(["bridge", "Bridge"])
model.append(["private", "Private"])
model.append(["passthrough", "Passthrough"])
@staticmethod
def build_network_source_mode_combo(vm, combo):
model = Gtk.ListStore(str, str)
combo.set_model(model)
uihelpers.set_combo_text_column(combo, 1)
vmmAddHardware.populate_network_source_mode_combo(vm, combo)
combo.set_active(0)
@staticmethod
def populate_network_model_combo(vm, combo):
model = combo.get_model()
model.clear()
# [xml value, label]
model.append([None, _("Hypervisor default")])
if vm.is_hvm():
mod_list = ["rtl8139", "ne2k_pci", "pcnet", "e1000"]
if vm.get_hv_type() in ["kvm", "qemu", "test"]:
mod_list.append("virtio")
if (vm.get_hv_type() == "kvm" and
vm.get_machtype() == "pseries"):
mod_list.append("spapr-vlan")
if vm.get_hv_type() in ["xen", "test"]:
mod_list.append("netfront")
mod_list.sort()
for m in mod_list:
model.append([m, m])
@staticmethod
def build_network_model_combo(vm, combo):
model = Gtk.ListStore(str, str)
combo.set_model(model)
uihelpers.set_combo_text_column(combo, 1)
model.set_sort_column_id(0, Gtk.SortType.ASCENDING)
vmmAddHardware.populate_network_model_combo(vm, combo)
combo.set_active(0)
@staticmethod
def populate_smartcard_mode_combo(vm, combo):
ignore = vm
model = combo.get_model()
model.clear()
# [xml value, label]
model.append(["passthrough", "Passthrough"])
model.append(["host", "Host"])
@staticmethod
def build_smartcard_mode_combo(vm, combo):
model = Gtk.ListStore(str, str)
combo.set_model(model)
uihelpers.set_combo_text_column(combo, 1)
model.set_sort_column_id(0, Gtk.SortType.ASCENDING)
vmmAddHardware.populate_smartcard_mode_combo(vm, combo)
idx = -1
for rowid in range(len(combo.get_model())):
idx = 0
row = combo.get_model()[rowid]
if row[0] == virtinst.VirtualSmartCardDevice.MODE_DEFAULT:
idx = rowid
break
combo.set_active(idx)
@staticmethod
def populate_redir_type_combo(vm, combo):
ignore = vm
model = combo.get_model()
model.clear()
# [xml value, label, conn details]
model.append(["spicevmc", "Spice channel", False])
model.append(["tcp", "TCP", True])
@staticmethod
def build_redir_type_combo(vm, combo):
model = Gtk.ListStore(str, str, bool)
combo.set_model(model)
uihelpers.set_combo_text_column(combo, 1)
vmmAddHardware.populate_redir_type_combo(vm, combo)
combo.set_active(0)
@staticmethod
def populate_tpm_type_combo(vm, combo):
ignore = vm
types = combo.get_model()
types.clear()
# [xml value, label]
for t in virtinst.VirtualTPMDevice.TYPES:
types.append([t, virtinst.VirtualTPMDevice.get_pretty_type(t)])
@staticmethod
def build_tpm_type_combo(vm, combo):
model = Gtk.ListStore(str, str)
combo.set_model(model)
uihelpers.set_combo_text_column(combo, 1)
model.set_sort_column_id(0, Gtk.SortType.ASCENDING)
vmmAddHardware.populate_tpm_type_combo(vm, combo)
idx = -1
for rowid in range(len(combo.get_model())):
idx = 0
row = combo.get_model()[rowid]
if row[0] == virtinst.VirtualTPMDevice.TYPE_DEFAULT:
idx = rowid
break
combo.set_active(idx)
@staticmethod
def build_graphics_keymap_combo(vm, combo, no_default=False):
ignore = vm
model = Gtk.ListStore(str, str)
combo.set_model(model)
uihelpers.set_combo_text_column(combo, 1)
if not no_default:
model.append([None, "default"])
else:
model.append([None, "Auto"])
model.append([virtinst.VirtualGraphics.KEYMAP_LOCAL,
"Copy local keymap"])
for k in virtinst.VirtualGraphics.valid_keymaps():
model.append([k, k])
combo.set_active(-1)
@staticmethod
def build_disk_cache_combo(vm, combo):
ignore = vm
model = Gtk.ListStore(str, str)
combo.set_model(model)
uihelpers.set_combo_text_column(combo, 1)
combo.set_active(-1)
for m in virtinst.VirtualDisk.cache_types:
model.append([m, m])
_iter = model.insert(0, [None, "default"])
combo.set_active_iter(_iter)
@staticmethod
def build_disk_io_combo(vm, combo, no_default=False):
ignore = vm
model = Gtk.ListStore(str, str)
combo.set_model(model)
uihelpers.set_combo_text_column(combo, 1)
model.set_sort_column_id(0, Gtk.SortType.ASCENDING)
combo.set_active(-1)
for m in virtinst.VirtualDisk.io_modes:
model.append([m, m])
if not no_default:
model.append([None, "default"])
combo.set_active(0)
@staticmethod
def build_disk_bus_combo(vm, combo, no_default=False):
ignore = vm
model = Gtk.ListStore(str, str)
combo.set_model(model)
uihelpers.set_combo_text_column(combo, 1)
model.set_sort_column_id(1, Gtk.SortType.ASCENDING)
if not no_default:
model.append([None, "default"])
combo.set_active(-1)
@staticmethod
def populate_disk_format_combo(vm, combo, create):
model = Gtk.ListStore(str)
combo.set_model(model)
uihelpers.set_combo_text_column(combo, 0)
formats = ["raw", "qcow2", "qed"]
no_create_formats = []
if not vm.stable_defaults():
formats.append("vmdk")
no_create_formats.append("vdi")
for m in formats:
model.append([m])
if not create:
for m in no_create_formats:
model.append([m])
if create:
combo.set_active(0)
#########################
# UI population methods #
#########################
@ -606,9 +903,9 @@ class vmmAddHardware(vmmGObjectUI):
model.append([_("No Devices Available"), None, None, None])
uihelpers.set_list_selection(devlist, 0)
def populate_disk_format_combo(self, create):
def populate_disk_format_combo_wrapper(self, create):
format_list = self.widget("config-storage-format")
uihelpers.update_storage_format_combo(self.vm, format_list, create)
self.populate_disk_format_combo(self.vm, format_list, create)
if not create:
format_list.get_child().set_text("")
@ -998,7 +1295,7 @@ class vmmAddHardware(vmmGObjectUI):
def toggle_storage_select(self, src):
act = src.get_active()
self.widget("config-storage-browse-box").set_sensitive(act)
self.populate_disk_format_combo(not act)
self.populate_disk_format_combo_wrapper(not act)
def set_disk_storage_path(self, ignore, path):
self.widget("config-storage-entry").set_text(path)

View File

@ -149,7 +149,7 @@ class vmmChooseCD(vmmGObjectUI):
warn = self.widget("cd-path-warn")
error = self.conn.mediadev_error
uihelpers.init_mediadev_combo(widget)
uihelpers.build_mediadev_combo(widget)
uihelpers.populate_mediadev_combo(self.conn, widget, self.media_type)
if error:

View File

@ -38,7 +38,6 @@ import signal
import socket
import threading
import virtManager.uihelpers as uihelpers
from virtManager.autodrawer import AutoDrawer
from virtManager.baseclass import vmmGObjectUI, vmmGObject
from virtManager.serialcon import vmmSerialConsole
@ -59,6 +58,7 @@ def has_property(obj, setting):
return True
class ConnectionInfo(object):
"""
Holds all the bits needed to make a connection to a graphical console
@ -794,7 +794,7 @@ class vmmConsolePages(vmmGObjectUI):
self.send_key_button = None
self.fs_toolbar = None
self.fs_drawer = None
self.keycombo_menu = uihelpers.build_keycombo_menu(self.send_key)
self.keycombo_menu = self.build_keycombo_menu(self.send_key)
self.init_fs_toolbar()
# Make viewer widget background always be black
@ -822,6 +822,7 @@ class vmmConsolePages(vmmGObjectUI):
self.page_changed()
def is_visible(self):
if self.topwin:
return self.topwin.get_visible()
@ -851,6 +852,30 @@ class vmmConsolePages(vmmGObjectUI):
# Initialization helpers #
##########################
@staticmethod
def build_keycombo_menu(cb):
# Shared with vmmDetails
menu = Gtk.Menu()
def make_item(name, combo):
item = Gtk.MenuItem.new_with_mnemonic(name)
item.connect("activate", cb, combo)
menu.add(item)
make_item("Ctrl+Alt+_Backspace", ["Control_L", "Alt_L", "BackSpace"])
make_item("Ctrl+Alt+_Delete", ["Control_L", "Alt_L", "Delete"])
menu.add(Gtk.SeparatorMenuItem())
for i in range(1, 13):
make_item("Ctrl+Alt+F_%d" % i, ["Control_L", "Alt_L", "F%d" % i])
menu.add(Gtk.SeparatorMenuItem())
make_item("_Printscreen", ["Print"])
menu.show_all()
return menu
def init_fs_toolbar(self):
scroll = self.widget("console-gfx-scroll")
pages = self.widget("console-pages")

View File

@ -291,13 +291,13 @@ class vmmCreate(vmmGObjectUI):
# Physical CD-ROM model
cd_list = self.widget("install-local-cdrom-combo")
uihelpers.init_mediadev_combo(cd_list)
uihelpers.build_mediadev_combo(cd_list)
# Networking
# [ interface type, device name, label, sensitive ]
net_list = self.widget("config-netdev")
bridge_box = self.widget("config-netdev-bridge-box")
uihelpers.init_network_list(net_list, bridge_box)
uihelpers.build_network_list(net_list, bridge_box)
# Archtecture
# [value, label]

View File

@ -160,10 +160,21 @@ class vmmCreateInterface(vmmGObjectUI):
self.bond_config.destroy()
self.bond_config = None
###########################
# Initialization routines #
###########################
@staticmethod
def build_interface_startmode_combo(combo):
model = Gtk.ListStore(str)
combo.set_model(model)
uihelpers.set_combo_text_column(combo, 0)
model.append(["none"])
model.append(["onboot"])
model.append(["hotplug"])
def set_initial_state(self):
self.widget("pages").set_show_tabs(False)
self.widget("bond-pages").set_show_tabs(False)
@ -188,7 +199,7 @@ class vmmCreateInterface(vmmGObjectUI):
_("VLAN")])
# Start mode
uihelpers.build_startmode_combo(
self.build_interface_startmode_combo(
self.widget("interface-startmode"))
# Parent/slave Interface list

View File

@ -688,8 +688,8 @@ class vmmDetails(vmmGObjectUI):
self.config.get_details_show_toolbar())
# Keycombo menu (ctrl+alt+del etc.)
self.keycombo_menu = uihelpers.build_keycombo_menu(
self.console.send_key)
self.keycombo_menu = self.console.build_keycombo_menu(
self.console.send_key)
self.widget("details-menu-send-key").set_submenu(self.keycombo_menu)
@ -913,19 +913,19 @@ class vmmDetails(vmmGObjectUI):
# Disk cache combo
disk_cache = self.widget("disk-cache")
uihelpers.build_cache_combo(self.vm, disk_cache)
vmmAddHardware.build_disk_cache_combo(self.vm, disk_cache)
# Disk io combo
disk_io = self.widget("disk-io")
uihelpers.build_io_combo(self.vm, disk_io)
vmmAddHardware.build_disk_io_combo(self.vm, disk_io)
# Disk format combo
format_list = self.widget("disk-format")
uihelpers.update_storage_format_combo(self.vm, format_list, False)
vmmAddHardware.populate_disk_format_combo(self.vm, format_list, False)
# Disk bus combo
disk_bus = self.widget("disk-bus")
uihelpers.build_disk_bus_combo(self.vm, disk_bus)
vmmAddHardware.build_disk_bus_combo(self.vm, disk_bus)
# Disk iotune expander
if not (self.conn.is_qemu() or self.conn.is_test_conn()):
@ -936,16 +936,16 @@ class vmmDetails(vmmGObjectUI):
net_bridge = self.widget("network-bridge-box")
source_mode_combo = self.widget("network-source-mode")
vport_expander = self.widget("vport-expander")
uihelpers.init_network_list(net_source, net_bridge,
uihelpers.build_network_list(net_source, net_bridge,
source_mode_combo, vport_expander)
# source mode
source_mode = self.widget("network-source-mode")
uihelpers.build_source_mode_combo(self.vm, source_mode)
vmmAddHardware.build_network_source_mode_combo(self.vm, source_mode)
# Network model
net_model = self.widget("network-model")
uihelpers.build_netmodel_combo(self.vm, net_model)
vmmAddHardware.build_network_model_combo(self.vm, net_model)
# Graphics type
gfx_type = self.widget("gfx-type")
@ -958,30 +958,32 @@ class vmmDetails(vmmGObjectUI):
# Graphics keymap
gfx_keymap = self.widget("gfx-keymap")
uihelpers.build_vnc_keymap_combo(self.vm, gfx_keymap,
vmmAddHardware.build_graphics_keymap_combo(self.vm, gfx_keymap,
no_default=no_default)
# Sound model
sound_dev = self.widget("sound-model")
uihelpers.build_sound_combo(self.vm, sound_dev, no_default=no_default)
vmmAddHardware.build_sound_combo(self.vm, sound_dev,
no_default=no_default)
# Video model combo
video_dev = self.widget("video-model")
uihelpers.build_video_combo(self.vm, video_dev, no_default=no_default)
vmmAddHardware.build_video_combo(self.vm, video_dev,
no_default=no_default)
# Watchdog model combo
combo = self.widget("watchdog-model")
uihelpers.build_watchdogmodel_combo(self.vm, combo,
vmmAddHardware.build_watchdogmodel_combo(self.vm, combo,
no_default=no_default)
# Watchdog action combo
combo = self.widget("watchdog-action")
uihelpers.build_watchdogaction_combo(self.vm, combo,
vmmAddHardware.build_watchdogaction_combo(self.vm, combo,
no_default=no_default)
# Smartcard mode
sc_mode = self.widget("smartcard-mode")
uihelpers.build_smartcard_mode_combo(self.vm, sc_mode)
vmmAddHardware.build_smartcard_mode_combo(self.vm, sc_mode)
# Controller model
combo = self.widget("controller-model")
@ -2736,7 +2738,7 @@ class vmmDetails(vmmGObjectUI):
self.widget("vport-expander").set_visible(is_direct)
# source mode
uihelpers.populate_source_mode_combo(self.vm,
vmmAddHardware.populate_network_source_mode_combo(self.vm,
self.widget("network-source-mode"))
self.set_combo_entry("network-source-mode", source_mode)
@ -2749,7 +2751,7 @@ class vmmDetails(vmmGObjectUI):
str(vport.typeidversion) or "")
self.widget("vport-instanceid").set_text(vport.instanceid or "")
uihelpers.populate_netmodel_combo(self.vm,
vmmAddHardware.populate_network_model_combo(self.vm,
self.widget("network-model"))
self.set_combo_entry("network-model", model)
@ -3062,9 +3064,9 @@ class vmmDetails(vmmGObjectUI):
return
no_default = not self.is_customize_dialog
uihelpers.populate_video_combo(self.vm,
self.widget("video-model"),
no_default=no_default)
vmmAddHardware.populate_video_combo(self.vm,
self.widget("video-model"),
no_default=no_default)
model = vid.model
ram = vid.vram

View File

@ -38,6 +38,18 @@ from virtManager import uihelpers
from virtManager.libvirtobject import vmmLibvirtObject
vm_status_icons = {
libvirt.VIR_DOMAIN_BLOCKED: "state_running",
libvirt.VIR_DOMAIN_CRASHED: "state_shutoff",
libvirt.VIR_DOMAIN_PAUSED: "state_paused",
libvirt.VIR_DOMAIN_RUNNING: "state_running",
libvirt.VIR_DOMAIN_SHUTDOWN: "state_shutoff",
libvirt.VIR_DOMAIN_SHUTOFF: "state_shutoff",
libvirt.VIR_DOMAIN_NOSTATE: "state_running",
getattr(libvirt, "VIR_DOMAIN_PMSUSPENDED", 7): "state_paused",
}
def compare_device(origdev, newdev, idx):
devprops = {
"disk" : ["target", "bus"],
@ -170,10 +182,10 @@ class vmmDomainSnapshot(vmmLibvirtObject):
return vmmDomain.pretty_run_status(status)
def run_status_icon_name(self):
status = DomainSnapshot.state_str_to_int(self.get_xmlobj().state)
if status not in uihelpers.vm_status_icons:
if status not in vm_status_icons:
logging.debug("Unknown status %d, using NOSTATE", status)
status = libvirt.VIR_DOMAIN_NOSTATE
return uihelpers.vm_status_icons[status]
return vm_status_icons[status]
def is_external(self):
if self.get_xmlobj().memory_type == "external":
@ -1548,10 +1560,10 @@ class vmmDomain(vmmLibvirtObject):
return self.pretty_run_status(self.status(), self.hasSavedImage())
def run_status_icon_name(self):
status = self.status()
if status not in uihelpers.vm_status_icons:
if status not in vm_status_icons:
logging.debug("Unknown status %d, using NOSTATE", status)
status = libvirt.VIR_DOMAIN_NOSTATE
return uihelpers.vm_status_icons[status]
return vm_status_icons[status]
def force_update_status(self):
"""

View File

@ -243,7 +243,8 @@ class vmmHost(vmmGObjectUI):
interfaceListModel.set_sort_column_id(1, Gtk.SortType.ASCENDING)
# Starmode combo
uihelpers.build_startmode_combo(self.widget("interface-startmode"))
vmmCreateInterface.build_interface_startmode_combo(
self.widget("interface-startmode"))
# [ name, type ]
childListModel = Gtk.ListStore(str, str)

View File

@ -47,18 +47,6 @@ try:
except (ValueError, AttributeError):
can_set_row_none = False
vm_status_icons = {
libvirt.VIR_DOMAIN_BLOCKED: "state_running",
libvirt.VIR_DOMAIN_CRASHED: "state_shutoff",
libvirt.VIR_DOMAIN_PAUSED: "state_paused",
libvirt.VIR_DOMAIN_RUNNING: "state_running",
libvirt.VIR_DOMAIN_SHUTDOWN: "state_shutoff",
libvirt.VIR_DOMAIN_SHUTOFF: "state_shutoff",
libvirt.VIR_DOMAIN_NOSTATE: "state_running",
# VIR_DOMAIN_PMSUSPENDED
7: "state_paused",
}
############################################################
# Helpers for shared storage UI between create/addhardware #
@ -130,319 +118,29 @@ def check_default_pool_active(err, conn):
return True
#####################################################
# Hardware model list building (for details, addhw) #
#####################################################
#########################################
# VM <interface> device listing helpers #
#########################################
def set_combo_text_column(combo, col):
if combo.get_has_entry():
combo.set_entry_text_column(col)
else:
text = Gtk.CellRendererText()
combo.pack_start(text, True)
combo.add_attribute(text, 'text', col)
def _net_list_changed(net_list, bridge_box,
source_mode_combo, vport_expander):
active = net_list.get_active()
if active < 0:
return
if not bridge_box:
return
def build_video_combo(vm, combo, no_default=None):
model = Gtk.ListStore(str, str)
combo.set_model(model)
set_combo_text_column(combo, 1)
combo.get_model().set_sort_column_id(1, Gtk.SortType.ASCENDING)
row = net_list.get_model()[active]
populate_video_combo(vm, combo, no_default)
if source_mode_combo is not None:
doshow = (row[0] == virtinst.VirtualNetworkInterface.TYPE_DIRECT)
set_grid_row_visible(source_mode_combo, doshow)
vport_expander.set_visible(doshow)
show_bridge = row[5]
set_grid_row_visible(bridge_box, show_bridge)
def populate_video_combo(vm, combo, no_default=None):
model = combo.get_model()
has_spice = bool([g for g in vm.get_graphics_devices()
if g.type == g.TYPE_SPICE])
has_qxl = bool([v for v in vm.get_video_devices()
if v.model == "qxl"])
model.clear()
tmpdev = virtinst.VirtualVideoDevice(vm.conn.get_backend())
for m in tmpdev.MODELS:
if vm.stable_defaults():
if m == "qxl" and not has_spice and not has_qxl:
# Only list QXL video option when VM has SPICE video
continue
if m == tmpdev.MODEL_DEFAULT and no_default:
continue
model.append([m, tmpdev.pretty_model(m)])
if len(model) > 0:
combo.set_active(0)
def build_sound_combo(vm, combo, no_default=False):
model = Gtk.ListStore(str)
combo.set_model(model)
set_combo_text_column(combo, 0)
model.set_sort_column_id(0, Gtk.SortType.ASCENDING)
stable_defaults = vm.stable_defaults()
stable_soundmodels = ["ich6", "ac97"]
for m in virtinst.VirtualAudio.MODELS:
if m == virtinst.VirtualAudio.MODEL_DEFAULT and no_default:
continue
if (stable_defaults and m not in stable_soundmodels):
continue
model.append([m])
if len(model) > 0:
combo.set_active(0)
def build_watchdogmodel_combo(vm, combo, no_default=False):
ignore = vm
model = Gtk.ListStore(str)
combo.set_model(model)
set_combo_text_column(combo, 0)
model.set_sort_column_id(0, Gtk.SortType.ASCENDING)
for m in virtinst.VirtualWatchdog.MODELS:
if m == virtinst.VirtualAudio.MODEL_DEFAULT and no_default:
continue
model.append([m])
if len(model) > 0:
combo.set_active(0)
def build_watchdogaction_combo(vm, combo, no_default=False):
ignore = vm
model = Gtk.ListStore(str, str)
combo.set_model(model)
set_combo_text_column(combo, 1)
model.set_sort_column_id(0, Gtk.SortType.ASCENDING)
for m in virtinst.VirtualWatchdog.ACTIONS:
if m == virtinst.VirtualWatchdog.ACTION_DEFAULT and no_default:
continue
model.append([m, virtinst.VirtualWatchdog.get_action_desc(m)])
if len(model) > 0:
combo.set_active(0)
def build_source_mode_combo(vm, combo):
model = Gtk.ListStore(str, str)
combo.set_model(model)
set_combo_text_column(combo, 1)
populate_source_mode_combo(vm, combo)
combo.set_active(0)
def populate_source_mode_combo(vm, combo):
ignore = vm
model = combo.get_model()
model.clear()
# [xml value, label]
model.append([None, "Default"])
model.append(["vepa", "VEPA"])
model.append(["bridge", "Bridge"])
model.append(["private", "Private"])
model.append(["passthrough", "Passthrough"])
def build_smartcard_mode_combo(vm, combo):
model = Gtk.ListStore(str, str)
combo.set_model(model)
set_combo_text_column(combo, 1)
model.set_sort_column_id(0, Gtk.SortType.ASCENDING)
populate_smartcard_mode_combo(vm, combo)
idx = -1
for rowid in range(len(combo.get_model())):
idx = 0
row = combo.get_model()[rowid]
if row[0] == virtinst.VirtualSmartCardDevice.MODE_DEFAULT:
idx = rowid
break
combo.set_active(idx)
def populate_smartcard_mode_combo(vm, combo):
ignore = vm
model = combo.get_model()
model.clear()
# [xml value, label]
model.append(["passthrough", "Passthrough"])
model.append(["host", "Host"])
def build_redir_type_combo(vm, combo):
model = Gtk.ListStore(str, str, bool)
combo.set_model(model)
set_combo_text_column(combo, 1)
populate_redir_type_combo(vm, combo)
combo.set_active(0)
def populate_redir_type_combo(vm, combo):
ignore = vm
model = combo.get_model()
model.clear()
# [xml value, label, conn details]
model.append(["spicevmc", "Spice channel", False])
model.append(["tcp", "TCP", True])
def build_tpm_type_combo(vm, combo):
model = Gtk.ListStore(str, str)
combo.set_model(model)
set_combo_text_column(combo, 1)
model.set_sort_column_id(0, Gtk.SortType.ASCENDING)
populate_tpm_type_combo(vm, combo)
idx = -1
for rowid in range(len(combo.get_model())):
idx = 0
row = combo.get_model()[rowid]
if row[0] == virtinst.VirtualTPMDevice.TYPE_DEFAULT:
idx = rowid
break
combo.set_active(idx)
def populate_tpm_type_combo(vm, combo):
ignore = vm
types = combo.get_model()
types.clear()
# [xml value, label]
for t in virtinst.VirtualTPMDevice.TYPES:
types.append([t, virtinst.VirtualTPMDevice.get_pretty_type(t)])
def build_netmodel_combo(vm, combo):
model = Gtk.ListStore(str, str)
combo.set_model(model)
set_combo_text_column(combo, 1)
model.set_sort_column_id(0, Gtk.SortType.ASCENDING)
populate_netmodel_combo(vm, combo)
combo.set_active(0)
def populate_netmodel_combo(vm, combo):
model = combo.get_model()
model.clear()
# [xml value, label]
model.append([None, _("Hypervisor default")])
if vm.is_hvm():
mod_list = ["rtl8139", "ne2k_pci", "pcnet", "e1000"]
if vm.get_hv_type() in ["kvm", "qemu", "test"]:
mod_list.append("virtio")
if (vm.get_hv_type() == "kvm" and
vm.get_machtype() == "pseries"):
mod_list.append("spapr-vlan")
if vm.get_hv_type() in ["xen", "test"]:
mod_list.append("netfront")
mod_list.sort()
for m in mod_list:
model.append([m, m])
def build_cache_combo(vm, combo):
ignore = vm
model = Gtk.ListStore(str, str)
combo.set_model(model)
set_combo_text_column(combo, 1)
combo.set_active(-1)
for m in virtinst.VirtualDisk.cache_types:
model.append([m, m])
_iter = model.insert(0, [None, "default"])
combo.set_active_iter(_iter)
def build_io_combo(vm, combo, no_default=False):
ignore = vm
model = Gtk.ListStore(str, str)
combo.set_model(model)
set_combo_text_column(combo, 1)
model.set_sort_column_id(0, Gtk.SortType.ASCENDING)
combo.set_active(-1)
for m in virtinst.VirtualDisk.io_modes:
model.append([m, m])
if not no_default:
model.append([None, "default"])
combo.set_active(0)
def build_disk_bus_combo(vm, combo, no_default=False):
ignore = vm
model = Gtk.ListStore(str, str)
combo.set_model(model)
set_combo_text_column(combo, 1)
model.set_sort_column_id(1, Gtk.SortType.ASCENDING)
if not no_default:
model.append([None, "default"])
combo.set_active(-1)
def build_vnc_keymap_combo(vm, combo, no_default=False):
ignore = vm
model = Gtk.ListStore(str, str)
combo.set_model(model)
set_combo_text_column(combo, 1)
if not no_default:
model.append([None, "default"])
else:
model.append([None, "Auto"])
model.append([virtinst.VirtualGraphics.KEYMAP_LOCAL,
"Copy local keymap"])
for k in virtinst.VirtualGraphics.valid_keymaps():
model.append([k, k])
combo.set_active(-1)
#####################################
# Storage format list/combo helpers #
#####################################
def update_storage_format_combo(vm, combo, create):
model = Gtk.ListStore(str)
combo.set_model(model)
set_combo_text_column(combo, 0)
formats = ["raw", "qcow2", "qed"]
no_create_formats = []
if not vm.stable_defaults():
formats.append("vmdk")
no_create_formats.append("vdi")
for m in formats:
model.append([m])
if not create:
for m in no_create_formats:
model.append([m])
if create:
combo.set_active(0)
#######################################################################
# Widgets for listing network device options (in create, addhardware) #
#######################################################################
def pretty_network_desc(nettype, source=None, netobj=None):
if nettype == virtinst.VirtualNetworkInterface.TYPE_USER:
@ -466,14 +164,14 @@ def pretty_network_desc(nettype, source=None, netobj=None):
return ret
def init_network_list(net_list, bridge_box, source_mode_combo=None,
def build_network_list(net_list, bridge_box, source_mode_combo=None,
vport_expander=None):
# [ network type, source name, label, sensitive?, net is active,
# manual bridge, net instance]
net_model = Gtk.ListStore(str, str, str, bool, bool, bool, object)
net_list.set_model(net_model)
net_list.connect("changed", net_list_changed, bridge_box,
net_list.connect("changed", _net_list_changed, bridge_box,
source_mode_combo, vport_expander)
text = Gtk.CellRendererText()
@ -482,26 +180,6 @@ def init_network_list(net_list, bridge_box, source_mode_combo=None,
net_list.add_attribute(text, 'sensitive', 3)
def net_list_changed(net_list, bridge_box,
source_mode_combo, vport_expander):
active = net_list.get_active()
if active < 0:
return
if not bridge_box:
return
row = net_list.get_model()[active]
if source_mode_combo is not None:
doshow = (row[0] == virtinst.VirtualNetworkInterface.TYPE_DIRECT)
set_grid_row_visible(source_mode_combo, doshow)
vport_expander.set_visible(doshow)
show_bridge = row[5]
set_grid_row_visible(bridge_box, show_bridge)
def get_network_selection(net_list, bridge_entry):
idx = net_list.get_active()
if idx == -1:
@ -740,7 +418,107 @@ def validate_network(err, conn, nettype, devname, macaddr, model=None):
# Populate media widget (choosecd, create) #
############################################
def init_mediadev_combo(widget):
def _set_mediadev_default(model):
if len(model) == 0:
model.append([None, _("No device present"), False, None, None, False])
def _set_mediadev_row_from_object(row, obj):
row[OPTICAL_DEV_PATH] = obj.get_path()
row[OPTICAL_LABEL] = obj.pretty_label()
row[OPTICAL_IS_MEDIA_PRESENT] = obj.has_media()
row[OPTICAL_DEV_KEY] = obj.get_key()
row[OPTICAL_MEDIA_KEY] = obj.get_media_key()
row[OPTICAL_IS_VALID] = True
def _mediadev_set_default_selection(widget):
# Set the first active cdrom device as selected, otherwise none
model = widget.get_model()
idx = 0
active = widget.get_active()
if active != -1:
# already a selection, don't change it
return
for row in model:
if row[OPTICAL_IS_MEDIA_PRESENT] is True:
widget.set_active(idx)
return
idx += 1
widget.set_active(-1)
def _mediadev_media_changed(newobj, widget):
model = widget.get_model()
active = widget.get_active()
idx = 0
# Search for the row with matching device node and
# fill in info about inserted media. If model has no current
# selection, select the new media.
for row in model:
if row[OPTICAL_DEV_PATH] == newobj.get_path():
_set_mediadev_row_from_object(row, newobj)
has_media = row[OPTICAL_IS_MEDIA_PRESENT]
if has_media and active == -1:
widget.set_active(idx)
elif not has_media and active == idx:
widget.set_active(-1)
idx = idx + 1
_mediadev_set_default_selection(widget)
def _mediadev_added(ignore_helper, newobj, widget, devtype):
model = widget.get_model()
if newobj.get_media_type() != devtype:
return
if model is None:
return
if len(model) == 1 and model[0][OPTICAL_IS_VALID] is False:
# Only entry is the 'No device' entry
model.clear()
newobj.connect("media-added", _mediadev_media_changed, widget)
newobj.connect("media-removed", _mediadev_media_changed, widget)
# Brand new device
row = [None, None, None, None, None, None]
_set_mediadev_row_from_object(row, newobj)
model.append(row)
_mediadev_set_default_selection(widget)
def _mediadev_removed(ignore_helper, key, widget):
model = widget.get_model()
active = widget.get_active()
idx = 0
for row in model:
if row[OPTICAL_DEV_KEY] == key:
# Whole device removed
del(model[idx])
if idx > active and active != -1:
widget.set_active(active - 1)
elif idx == active:
widget.set_active(-1)
idx += 1
_set_mediadev_default(model)
_mediadev_set_default_selection(widget)
def build_mediadev_combo(widget):
# [Device path, pretty label, has_media?, device key, media key,
# vmmMediaDevice, is valid device]
model = Gtk.ListStore(str, str, bool, str, str, bool)
@ -758,117 +536,18 @@ def populate_mediadev_combo(conn, widget, devtype):
model = widget.get_model()
model.clear()
set_mediadev_default(model)
_set_mediadev_default(model)
sigs.append(conn.connect("mediadev-added", mediadev_added, widget, devtype))
sigs.append(conn.connect("mediadev-removed", mediadev_removed, widget))
sigs.append(conn.connect("mediadev-added",
_mediadev_added, widget, devtype))
sigs.append(conn.connect("mediadev-removed", _mediadev_removed, widget))
widget.set_active(-1)
mediadev_set_default_selection(widget)
_mediadev_set_default_selection(widget)
return sigs
def set_mediadev_default(model):
if len(model) == 0:
model.append([None, _("No device present"), False, None, None, False])
def set_row_from_object(row, obj):
row[OPTICAL_DEV_PATH] = obj.get_path()
row[OPTICAL_LABEL] = obj.pretty_label()
row[OPTICAL_IS_MEDIA_PRESENT] = obj.has_media()
row[OPTICAL_DEV_KEY] = obj.get_key()
row[OPTICAL_MEDIA_KEY] = obj.get_media_key()
row[OPTICAL_IS_VALID] = True
def mediadev_removed(ignore_helper, key, widget):
model = widget.get_model()
active = widget.get_active()
idx = 0
for row in model:
if row[OPTICAL_DEV_KEY] == key:
# Whole device removed
del(model[idx])
if idx > active and active != -1:
widget.set_active(active - 1)
elif idx == active:
widget.set_active(-1)
idx += 1
set_mediadev_default(model)
mediadev_set_default_selection(widget)
def mediadev_added(ignore_helper, newobj, widget, devtype):
model = widget.get_model()
if newobj.get_media_type() != devtype:
return
if model is None:
return
if len(model) == 1 and model[0][OPTICAL_IS_VALID] is False:
# Only entry is the 'No device' entry
model.clear()
newobj.connect("media-added", mediadev_media_changed, widget)
newobj.connect("media-removed", mediadev_media_changed, widget)
# Brand new device
row = [None, None, None, None, None, None]
set_row_from_object(row, newobj)
model.append(row)
mediadev_set_default_selection(widget)
def mediadev_media_changed(newobj, widget):
model = widget.get_model()
active = widget.get_active()
idx = 0
# Search for the row with matching device node and
# fill in info about inserted media. If model has no current
# selection, select the new media.
for row in model:
if row[OPTICAL_DEV_PATH] == newobj.get_path():
set_row_from_object(row, newobj)
has_media = row[OPTICAL_IS_MEDIA_PRESENT]
if has_media and active == -1:
widget.set_active(idx)
elif not has_media and active == idx:
widget.set_active(-1)
idx = idx + 1
mediadev_set_default_selection(widget)
def mediadev_set_default_selection(widget):
# Set the first active cdrom device as selected, otherwise none
model = widget.get_model()
idx = 0
active = widget.get_active()
if active != -1:
# already a selection, don't change it
return
for row in model:
if row[OPTICAL_IS_MEDIA_PRESENT] is True:
widget.set_active(idx)
return
idx += 1
widget.set_active(-1)
####################################################################
# Build toolbar shutdown button menu (manager and details toolbar) #
####################################################################
@ -1065,50 +744,18 @@ def check_path_search_for_qemu(err, conn, path):
config.running_config.add_perms_fix_ignore(errors.keys())
######################################
# Interface startmode widget builder #
######################################
################
# Misc helpers #
################
def build_startmode_combo(combo):
model = Gtk.ListStore(str)
combo.set_model(model)
set_combo_text_column(combo, 0)
def set_combo_text_column(combo, col):
if combo.get_has_entry():
combo.set_entry_text_column(col)
else:
text = Gtk.CellRendererText()
combo.pack_start(text, True)
combo.add_attribute(text, 'text', col)
model.append(["none"])
model.append(["onboot"])
model.append(["hotplug"])
#########################
# Console keycombo menu #
#########################
def build_keycombo_menu(cb):
menu = Gtk.Menu()
def make_item(name, combo):
item = Gtk.MenuItem.new_with_mnemonic(name)
item.connect("activate", cb, combo)
menu.add(item)
make_item("Ctrl+Alt+_Backspace", ["Control_L", "Alt_L", "BackSpace"])
make_item("Ctrl+Alt+_Delete", ["Control_L", "Alt_L", "Delete"])
menu.add(Gtk.SeparatorMenuItem())
for i in range(1, 13):
make_item("Ctrl+Alt+F_%d" % i, ["Control_L", "Alt_L", "F%d" % i])
menu.add(Gtk.SeparatorMenuItem())
make_item("_Printscreen", ["Print"])
menu.show_all()
return menu
#############
# Misc bits #
#############
def spin_get_helper(widget):
adj = widget.get_adjustment()