2006-06-28 23:50:17 +04:00
#
2014-01-07 13:20:44 +04:00
# Copyright (C) 2006-2008, 2013, 2014 Red Hat, Inc.
2006-06-28 23:50:17 +04:00
# Copyright (C) 2006 Daniel P. Berrange <berrange@redhat.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
2007-11-20 19:12:20 +03:00
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA.
2006-06-28 23:50:17 +04:00
#
2006-06-14 18:59:40 +04:00
2006-09-26 02:41:47 +04:00
import logging
2007-04-11 03:07:53 +04:00
import traceback
2013-04-12 01:16:33 +04:00
# pylint: disable=E0611
2012-05-14 17:24:56 +04:00
from gi . repository import GObject
from gi . repository import Gtk
from gi . repository import Gdk
2013-04-12 01:16:33 +04:00
# pylint: enable=E0611
2011-04-29 00:17:44 +04:00
import libvirt
2013-08-09 17:23:01 +04:00
from virtManager import uihelpers
2010-12-12 07:00:19 +03:00
from virtManager . storagebrowse import vmmStorageBrowser
2010-12-09 01:26:19 +03:00
from virtManager . baseclass import vmmGObjectUI
2007-04-12 23:36:04 +04:00
from virtManager . addhardware import vmmAddHardware
2007-09-22 00:28:31 +04:00
from virtManager . choosecd import vmmChooseCD
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 18:18:47 +04:00
from virtManager . snapshots import vmmSnapshotPage
2009-07-22 18:21:33 +04:00
from virtManager . graphwidgets import Sparkline
2013-10-25 19:13:29 +04:00
from virtinst import VirtualRNGDevice
2007-04-11 03:07:53 +04:00
2007-04-11 22:48:36 +04:00
import virtinst
2013-08-09 17:23:01 +04:00
from virtinst import util
2007-04-11 22:48:36 +04:00
2012-02-02 20:32:29 +04:00
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 18:18:47 +04:00
# Parameters that can be editted in the details window
2011-07-15 00:18:42 +04:00
( EDIT_NAME ,
2013-09-24 15:02:27 +04:00
EDIT_TITLE ,
2011-07-15 00:18:42 +04:00
EDIT_ACPI ,
EDIT_APIC ,
EDIT_CLOCK ,
2012-01-05 13:35:40 +04:00
EDIT_MACHTYPE ,
2011-07-15 00:18:42 +04:00
EDIT_SECURITY ,
EDIT_DESC ,
EDIT_VCPUS ,
EDIT_CPUSET ,
EDIT_CPU ,
EDIT_TOPOLOGY ,
EDIT_MEM ,
EDIT_AUTOSTART ,
EDIT_BOOTORDER ,
EDIT_BOOTMENU ,
EDIT_KERNEL ,
EDIT_INIT ,
EDIT_DISK_RO ,
EDIT_DISK_SHARE ,
2013-10-04 05:39:01 +04:00
EDIT_DISK_REMOVABLE ,
2011-07-15 00:18:42 +04:00
EDIT_DISK_CACHE ,
2011-07-24 04:41:35 +04:00
EDIT_DISK_IO ,
2011-07-15 00:18:42 +04:00
EDIT_DISK_BUS ,
EDIT_DISK_SERIAL ,
EDIT_DISK_FORMAT ,
2013-02-17 17:40:37 +04:00
EDIT_DISK_IOTUNE ,
2011-07-15 00:18:42 +04:00
EDIT_SOUND_MODEL ,
EDIT_SMARTCARD_MODE ,
EDIT_NET_MODEL ,
EDIT_NET_VPORT ,
EDIT_NET_SOURCE ,
EDIT_GFX_PASSWD ,
2013-08-01 03:14:17 +04:00
EDIT_GFX_USE_PASSWD ,
2011-07-15 00:18:42 +04:00
EDIT_GFX_TYPE ,
EDIT_GFX_KEYMAP ,
EDIT_VIDEO_MODEL ,
EDIT_WATCHDOG_MODEL ,
EDIT_WATCHDOG_ACTION ,
2011-09-23 19:14:15 +04:00
2013-06-26 05:45:08 +04:00
EDIT_CONTROLLER_MODEL ,
EDIT_TPM_TYPE ,
2013-10-04 05:39:01 +04:00
) = range ( 1 , 42 )
2011-07-15 00:18:42 +04:00
2007-07-14 22:43:20 +04:00
# Columns in hw list model
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 18:18:47 +04:00
( HW_LIST_COL_LABEL ,
HW_LIST_COL_ICON_NAME ,
HW_LIST_COL_ICON_SIZE ,
HW_LIST_COL_TYPE ,
HW_LIST_COL_DEVICE ) = range ( 5 )
2007-07-14 22:43:20 +04:00
2008-07-24 00:23:56 +04:00
# Types for the hw list model: numbers specify what order they will be listed
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 18:18:47 +04:00
( HW_LIST_TYPE_GENERAL ,
HW_LIST_TYPE_STATS ,
HW_LIST_TYPE_CPU ,
HW_LIST_TYPE_MEMORY ,
HW_LIST_TYPE_BOOT ,
HW_LIST_TYPE_DISK ,
HW_LIST_TYPE_NIC ,
HW_LIST_TYPE_INPUT ,
HW_LIST_TYPE_GRAPHICS ,
HW_LIST_TYPE_SOUND ,
HW_LIST_TYPE_CHAR ,
HW_LIST_TYPE_HOSTDEV ,
HW_LIST_TYPE_VIDEO ,
HW_LIST_TYPE_WATCHDOG ,
HW_LIST_TYPE_CONTROLLER ,
HW_LIST_TYPE_FILESYSTEM ,
HW_LIST_TYPE_SMARTCARD ,
HW_LIST_TYPE_REDIRDEV ,
2013-09-23 17:39:56 +04:00
HW_LIST_TYPE_TPM ,
2014-01-10 13:37:55 +04:00
HW_LIST_TYPE_RNG ,
HW_LIST_TYPE_PANIC ) = range ( 21 )
2006-06-14 18:59:40 +04:00
2010-12-10 19:47:07 +03:00
remove_pages = [ HW_LIST_TYPE_NIC , HW_LIST_TYPE_INPUT ,
HW_LIST_TYPE_GRAPHICS , HW_LIST_TYPE_SOUND , HW_LIST_TYPE_CHAR ,
HW_LIST_TYPE_HOSTDEV , HW_LIST_TYPE_DISK , HW_LIST_TYPE_VIDEO ,
2011-05-19 23:18:33 +04:00
HW_LIST_TYPE_WATCHDOG , HW_LIST_TYPE_CONTROLLER ,
2011-09-02 05:23:27 +04:00
HW_LIST_TYPE_FILESYSTEM , HW_LIST_TYPE_SMARTCARD ,
2013-09-23 17:39:56 +04:00
HW_LIST_TYPE_REDIRDEV , HW_LIST_TYPE_TPM ,
2014-01-10 13:37:55 +04:00
HW_LIST_TYPE_RNG , HW_LIST_TYPE_PANIC ]
2009-07-09 22:35:36 +04:00
2010-02-25 04:37:41 +03:00
# Boot device columns
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 18:18:47 +04:00
( BOOT_DEV_TYPE ,
BOOT_LABEL ,
BOOT_ICON ,
BOOT_ACTIVE ) = range ( 4 )
2010-02-25 04:37:41 +03:00
2009-02-24 02:50:27 +03:00
# Main tab pages
2013-09-02 01:40:38 +04:00
( DETAILS_PAGE_DETAILS ,
DETAILS_PAGE_CONSOLE ,
DETAILS_PAGE_SNAPSHOTS ) = range ( 3 )
2008-05-07 19:14:20 +04:00
2013-04-13 22:34:52 +04:00
2009-12-02 05:34:29 +03:00
def prettyify_disk_bus ( bus ) :
2013-08-18 16:59:19 +04:00
if bus in [ " ide " , " sata " , " scsi " , " usb " , " sd " ] :
2009-12-02 05:34:29 +03:00
return bus . upper ( )
if bus in [ " xen " ] :
return bus . capitalize ( )
if bus == " virtio " :
return " VirtIO "
2012-02-29 12:48:18 +04:00
if bus == " spapr-vscsi " :
return " vSCSI "
2009-12-02 05:34:29 +03:00
return bus
2013-04-13 22:34:52 +04:00
2009-12-02 05:34:29 +03:00
def prettyify_disk ( devtype , bus , idx ) :
busstr = prettyify_disk_bus ( bus ) or " "
if devtype == " floppy " :
devstr = " Floppy "
busstr = " "
elif devtype == " cdrom " :
devstr = " CDROM "
else :
devstr = devtype . capitalize ( )
if busstr :
ret = " %s %s " % ( busstr , devstr )
else :
ret = devstr
return " %s %s " % ( ret , idx )
2009-10-30 20:25:27 +03:00
2013-04-13 22:34:52 +04:00
2010-09-07 20:09:48 +04:00
def safeint ( val , fmt = " %.3d " ) :
try :
int ( val )
except :
return str ( val )
return fmt % int ( val )
2013-04-13 22:34:52 +04:00
2010-03-04 23:29:51 +03:00
def prettyify_bytes ( val ) :
2010-12-10 19:47:07 +03:00
if val > ( 1024 * 1024 * 1024 ) :
return " %2.2f GB " % ( val / ( 1024.0 * 1024.0 * 1024.0 ) )
2010-03-04 02:43:48 +03:00
else :
2010-12-10 19:47:07 +03:00
return " %2.2f MB " % ( val / ( 1024.0 * 1024.0 ) )
2010-03-04 02:43:48 +03:00
2013-04-13 22:34:52 +04:00
2011-09-02 05:23:27 +04:00
def build_redir_label ( redirdev ) :
# String shown in the devices details section
addrlabel = " "
# String shown in the VMs hardware list
hwlabel = " "
if redirdev . type == ' spicevmc ' :
addrlabel = None
elif redirdev . type == ' tcp ' :
addrlabel + = _ ( " %s : %s " ) % ( redirdev . host , redirdev . service )
else :
raise RuntimeError ( " unhandled redirection kind: %s " % redirdev . type )
hwlabel = _ ( " Redirected %s " ) % redirdev . bus . upper ( )
return addrlabel , hwlabel
2010-09-07 20:09:48 +04:00
def build_hostdev_label ( hostdev ) :
# String shown in the devices details section
srclabel = " "
# String shown in the VMs hardware list
hwlabel = " "
typ = hostdev . type
vendor = hostdev . vendor
product = hostdev . product
addrbus = hostdev . bus
addrdev = hostdev . device
addrslt = hostdev . slot
addrfun = hostdev . function
addrdom = hostdev . domain
def dehex ( val ) :
if val . startswith ( " 0x " ) :
val = val [ 2 : ]
return val
hwlabel = typ . upper ( )
srclabel = typ . upper ( )
if vendor and product :
# USB by vendor + product
devstr = " %s : %s " % ( dehex ( vendor ) , dehex ( product ) )
srclabel + = devstr
hwlabel + = devstr
elif addrbus and addrdev :
# USB by bus + dev
srclabel + = ( " Bus %s Device %s " %
( safeint ( addrbus ) , safeint ( addrdev ) ) )
hwlabel + = " %s : %s " % ( safeint ( addrbus ) , safeint ( addrdev ) )
elif addrbus and addrslt and addrfun and addrdom :
# PCI by bus:slot:function
devstr = ( " %s : %s : %s . %s " %
( dehex ( addrdom ) , dehex ( addrbus ) ,
dehex ( addrslt ) , dehex ( addrfun ) ) )
srclabel + = devstr
hwlabel + = devstr
return srclabel , hwlabel
2013-04-13 22:34:52 +04:00
2010-09-07 20:09:48 +04:00
def lookup_nodedev ( vmmconn , hostdev ) :
def intify ( val , do_hex = False ) :
try :
if do_hex :
return int ( val or ' 0x00 ' , 16 )
else :
return int ( val )
except :
return - 1
def attrVal ( node , attr ) :
if not hasattr ( node , attr ) :
return None
return getattr ( node , attr )
2013-04-23 17:30:34 +04:00
devtype = hostdev . type
2010-09-07 20:09:48 +04:00
found_dev = None
2013-09-28 02:06:39 +04:00
vendor_id = product_id = bus = device = domain = slot = func = None
2013-04-23 17:30:34 +04:00
2010-09-07 20:09:48 +04:00
# For USB we want a device, not a bus
if devtype == ' usb ' :
2013-04-23 17:30:34 +04:00
devtype = ' usb_device '
vendor_id = hostdev . vendor or - 1
product_id = hostdev . product or - 1
bus = intify ( hostdev . bus )
device = intify ( hostdev . device )
elif devtype == ' pci ' :
domain = intify ( hostdev . domain , True )
bus = intify ( hostdev . bus , True )
slot = intify ( hostdev . slot , True )
func = intify ( hostdev . function , True )
2010-09-07 20:09:48 +04:00
2011-04-08 02:08:29 +04:00
devs = vmmconn . get_nodedevs ( devtype , None )
2010-09-07 20:09:48 +04:00
for dev in devs :
2012-05-08 17:37:17 +04:00
# Try to match with product_id|vendor_id|bus|device
2013-09-28 02:40:00 +04:00
if ( ( attrVal ( dev , " product_id " ) == product_id or product_id == - 1 ) and
( attrVal ( dev , " vendor_id " ) == vendor_id or vendor_id == - 1 ) and
( attrVal ( dev , " bus " ) == bus or bus == - 1 ) and
( attrVal ( dev , " device " ) == device or device == - 1 ) ) :
2010-09-07 20:09:48 +04:00
found_dev = dev
else :
# Try to get info from bus/addr
dev_id = intify ( attrVal ( dev , " device " ) )
bus_id = intify ( attrVal ( dev , " bus " ) )
dom_id = intify ( attrVal ( dev , " domain " ) )
func_id = intify ( attrVal ( dev , " function " ) )
slot_id = intify ( attrVal ( dev , " slot " ) )
if ( ( dev_id == device and bus_id == bus ) or
( dom_id == domain and func_id == func and
bus_id == bus and slot_id == slot ) ) :
found_dev = dev
2013-09-28 02:40:00 +04:00
if found_dev :
break
2010-09-07 20:09:48 +04:00
return found_dev
2013-04-13 22:34:52 +04:00
2010-12-09 01:26:19 +03:00
class vmmDetails ( vmmGObjectUI ) :
2012-05-14 17:24:56 +04:00
__gsignals__ = {
" action-save-domain " : ( GObject . SignalFlags . RUN_FIRST , None , [ str , str ] ) ,
" action-destroy-domain " : ( GObject . SignalFlags . RUN_FIRST , None , [ str , str ] ) ,
" action-suspend-domain " : ( GObject . SignalFlags . RUN_FIRST , None , [ str , str ] ) ,
" action-resume-domain " : ( GObject . SignalFlags . RUN_FIRST , None , [ str , str ] ) ,
" action-run-domain " : ( GObject . SignalFlags . RUN_FIRST , None , [ str , str ] ) ,
" action-shutdown-domain " : ( GObject . SignalFlags . RUN_FIRST , None , [ str , str ] ) ,
" action-reset-domain " : ( GObject . SignalFlags . RUN_FIRST , None , [ str , str ] ) ,
" action-reboot-domain " : ( GObject . SignalFlags . RUN_FIRST , None , [ str , str ] ) ,
" action-exit-app " : ( GObject . SignalFlags . RUN_FIRST , None , [ ] ) ,
" action-view-manager " : ( GObject . SignalFlags . RUN_FIRST , None , [ ] ) ,
" action-migrate-domain " : ( GObject . SignalFlags . RUN_FIRST , None , [ str , str ] ) ,
2013-06-18 00:29:51 +04:00
" action-delete-domain " : ( GObject . SignalFlags . RUN_FIRST , None , [ str , str ] ) ,
2012-05-14 17:24:56 +04:00
" action-clone-domain " : ( GObject . SignalFlags . RUN_FIRST , None , [ str , str ] ) ,
" details-closed " : ( GObject . SignalFlags . RUN_FIRST , None , [ ] ) ,
" details-opened " : ( GObject . SignalFlags . RUN_FIRST , None , [ ] ) ,
" customize-finished " : ( GObject . SignalFlags . RUN_FIRST , None , [ ] ) ,
}
2011-04-13 18:47:31 +04:00
def __init__ ( self , vm , parent = None ) :
2013-09-23 00:10:16 +04:00
vmmGObjectUI . __init__ ( self , " details.ui " , " vmm-details " )
2006-06-14 18:59:40 +04:00
self . vm = vm
2011-07-23 00:43:26 +04:00
self . conn = self . vm . conn
2006-06-14 18:59:40 +04:00
2010-02-07 20:18:28 +03:00
self . is_customize_dialog = False
if parent :
# Details window is being abused as a 'configure before install'
# dialog, set things as appropriate
2011-10-30 21:28:18 +04:00
self . is_customize_dialog = True
2012-05-14 17:24:56 +04:00
self . topwin . set_type_hint ( Gdk . WindowTypeHint . DIALOG )
2010-02-07 20:18:28 +03:00
self . topwin . set_transient_for ( parent )
2011-10-30 21:28:18 +04:00
self . widget ( " toolbar-box " ) . show ( )
2011-07-14 21:13:13 +04:00
self . widget ( " customize-toolbar " ) . show ( )
self . widget ( " details-toolbar " ) . hide ( )
self . widget ( " details-menubar " ) . hide ( )
pages = self . widget ( " details-pages " )
2013-09-02 01:40:38 +04:00
pages . set_current_page ( DETAILS_PAGE_DETAILS )
2010-02-07 20:18:28 +03:00
2011-07-15 00:18:42 +04:00
self . active_edits = [ ]
2007-04-12 23:36:04 +04:00
self . addhw = None
2009-12-14 22:52:52 +03:00
self . media_choosers = { " cdrom " : None , " floppy " : None }
2010-12-12 07:00:19 +03:00
self . storage_browser = None
2009-03-01 03:27:20 +03:00
2009-11-02 19:21:50 +03:00
self . ignorePause = False
self . ignoreDetails = False
2013-04-26 23:58:18 +04:00
self . _cpu_copy_host = False
2006-06-14 18:59:40 +04:00
2013-09-02 01:40:38 +04:00
from virtManager . console import vmmConsolePages
2013-02-16 22:31:46 +04:00
self . console = vmmConsolePages ( self . vm , self . builder , self . topwin )
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 18:18:47 +04:00
self . snapshots = vmmSnapshotPage ( self . vm , self . builder , self . topwin )
self . widget ( " snapshot-placeholder " ) . add ( self . snapshots . top_box )
2008-04-08 22:30:47 +04:00
2009-11-29 04:07:01 +03:00
# Set default window size
w , h = self . vm . get_details_window_size ( )
self . topwin . set_default_size ( w or 800 , h or 600 )
2013-04-17 03:17:47 +04:00
self . oldhwkey = None
2010-02-12 22:01:59 +03:00
self . addhwmenu = None
2011-05-19 02:54:27 +04:00
self . keycombo_menu = None
2009-11-02 19:21:50 +03:00
self . init_menus ( )
self . init_details ( )
self . cpu_usage_graph = None
self . memory_usage_graph = None
self . disk_io_graph = None
self . network_traffic_graph = None
self . init_graphs ( )
2008-04-08 22:30:47 +04:00
2013-02-16 22:31:46 +04:00
self . builder . connect_signals ( {
2006-06-14 18:59:40 +04:00
" on_close_details_clicked " : self . close ,
2006-09-01 19:18:49 +04:00
" on_details_menu_close_activate " : self . close ,
2006-06-14 18:59:40 +04:00
" on_vmm_details_delete_event " : self . close ,
2009-11-29 04:07:01 +03:00
" on_vmm_details_configure_event " : self . window_resized ,
2008-06-13 22:40:26 +04:00
" on_details_menu_quit_activate " : self . exit_app ,
2013-09-23 00:29:58 +04:00
" on_hw_list_changed " : self . hw_changed ,
" on_config_boot_list_changed " : self . config_bootdev_selected ,
2006-06-14 18:59:40 +04:00
2009-10-21 20:01:53 +04:00
" on_control_vm_details_toggled " : self . details_console_changed ,
" on_control_vm_console_toggled " : self . details_console_changed ,
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 18:18:47 +04:00
" on_control_snapshots_toggled " : self . details_console_changed ,
2006-06-14 18:59:40 +04:00
" on_control_run_clicked " : self . control_vm_run ,
" on_control_shutdown_clicked " : self . control_vm_shutdown ,
" on_control_pause_toggled " : self . control_vm_pause ,
2008-04-08 22:30:47 +04:00
" on_control_fullscreen_toggled " : self . control_fullscreen ,
2006-06-14 18:59:40 +04:00
2011-07-19 05:31:06 +04:00
" on_details_customize_finish_clicked " : self . customize_finish ,
" on_details_cancel_customize_clicked " : self . close ,
2010-02-07 20:18:28 +03:00
2013-07-01 22:33:59 +04:00
" on_details_menu_virtual_manager_activate " : self . control_vm_menu ,
2006-09-01 19:18:49 +04:00
" on_details_menu_run_activate " : self . control_vm_run ,
2008-04-08 22:30:47 +04:00
" on_details_menu_poweroff_activate " : self . control_vm_shutdown ,
" on_details_menu_reboot_activate " : self . control_vm_reboot ,
2010-05-12 19:42:59 +04:00
" on_details_menu_save_activate " : self . control_vm_save ,
2013-03-17 01:59:32 +04:00
" on_details_menu_reset_activate " : self . control_vm_reset ,
2006-11-15 20:27:36 +03:00
" on_details_menu_destroy_activate " : self . control_vm_destroy ,
2007-09-28 01:52:29 +04:00
" on_details_menu_pause_activate " : self . control_vm_pause ,
2009-07-26 23:54:14 +04:00
" on_details_menu_clone_activate " : self . control_vm_clone ,
2009-11-18 21:51:36 +03:00
" on_details_menu_migrate_activate " : self . control_vm_migrate ,
2013-06-18 00:29:51 +04:00
" on_details_menu_delete_activate " : self . control_vm_delete ,
2008-05-07 19:40:29 +04:00
" on_details_menu_screenshot_activate " : self . control_vm_screenshot ,
2013-07-01 22:33:59 +04:00
" on_details_menu_usb_redirection " : self . control_vm_usb_redirection ,
2006-09-01 19:18:49 +04:00
" on_details_menu_view_toolbar_activate " : self . toggle_toolbar ,
2008-06-13 22:40:26 +04:00
" on_details_menu_view_manager_activate " : self . view_manager ,
2009-10-21 20:01:53 +04:00
" on_details_menu_view_details_toggled " : self . details_console_changed ,
" on_details_menu_view_console_toggled " : self . details_console_changed ,
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 18:18:47 +04:00
" on_details_menu_view_snapshots_toggled " : self . details_console_changed ,
2006-09-01 19:18:49 +04:00
2008-05-07 19:26:00 +04:00
" on_details_pages_switch_page " : self . switch_page ,
2012-05-14 17:24:56 +04:00
" on_overview_name_changed " : lambda * x : self . enable_apply ( x , EDIT_NAME ) ,
2013-09-24 15:02:27 +04:00
" on_overview_title_changed " : lambda * x : self . enable_apply ( x , EDIT_TITLE ) ,
2011-03-24 21:33:35 +03:00
" on_overview_acpi_changed " : self . config_acpi_changed ,
" on_overview_apic_changed " : self . config_apic_changed ,
2012-05-14 17:24:56 +04:00
" on_overview_clock_changed " : lambda * x : self . enable_apply ( x , EDIT_CLOCK ) ,
" on_machine_type_changed " : lambda * x : self . enable_apply ( x , EDIT_MACHTYPE ) ,
" on_security_label_changed " : lambda * x : self . enable_apply ( x , EDIT_SECURITY ) ,
" on_security_relabel_changed " : lambda * x : self . enable_apply ( x , EDIT_SECURITY ) ,
2010-02-25 04:37:41 +03:00
" on_security_type_changed " : self . security_type_changed ,
2010-05-13 20:55:08 +04:00
" on_config_vcpus_changed " : self . config_vcpus_changed ,
2011-01-13 21:32:19 +03:00
" on_config_maxvcpus_changed " : self . config_maxvcpus_changed ,
2012-05-14 17:24:56 +04:00
" on_config_vcpupin_changed " : lambda * x : self . enable_apply ( x , EDIT_CPUSET ) ,
2010-06-21 21:32:59 +04:00
" on_config_vcpupin_generate_clicked " : self . config_vcpupin_generate ,
2012-05-14 17:24:56 +04:00
" on_cpu_model_changed " : lambda * x : self . enable_apply ( x , EDIT_CPU ) ,
" on_cpu_cores_changed " : lambda * x : self . enable_apply ( x , EDIT_TOPOLOGY ) ,
" on_cpu_sockets_changed " : lambda * x : self . enable_apply ( x , EDIT_TOPOLOGY ) ,
" on_cpu_threads_changed " : lambda * x : self . enable_apply ( x , EDIT_TOPOLOGY ) ,
2013-04-26 23:58:18 +04:00
" on_cpu_copy_host_clicked " : self . config_cpu_copy_host ,
2013-12-03 06:46:47 +04:00
" on_cpu_clear_clicked " : self . config_cpu_clear ,
2010-12-17 00:05:55 +03:00
" on_cpu_topology_enable_toggled " : self . config_cpu_topology_enable ,
2010-02-25 04:37:41 +03:00
2006-11-13 23:31:17 +03:00
" on_config_memory_changed " : self . config_memory_changed ,
" on_config_maxmem_changed " : self . config_maxmem_changed ,
2010-02-25 04:37:41 +03:00
2013-08-18 20:25:20 +04:00
2012-11-08 17:15:02 +04:00
" on_config_boot_moveup_clicked " : lambda * x : self . config_boot_move ( x , True ) ,
" on_config_boot_movedown_clicked " : lambda * x : self . config_boot_move ( x , False ) ,
2012-05-14 17:24:56 +04:00
" on_config_autostart_changed " : lambda * x : self . enable_apply ( x , x , EDIT_AUTOSTART ) ,
" on_boot_menu_changed " : lambda * x : self . enable_apply ( x , EDIT_BOOTMENU ) ,
2013-08-18 20:25:20 +04:00
" on_boot_kernel_enable_toggled " : self . boot_kernel_toggled ,
2012-05-14 17:24:56 +04:00
" on_boot_kernel_changed " : lambda * x : self . enable_apply ( x , EDIT_KERNEL ) ,
2013-08-18 20:25:20 +04:00
" on_boot_initrd_changed " : lambda * x : self . enable_apply ( x , EDIT_KERNEL ) ,
" on_boot_dtb_changed " : lambda * x : self . enable_apply ( x , EDIT_KERNEL ) ,
2012-05-14 17:24:56 +04:00
" on_boot_kernel_args_changed " : lambda * x : self . enable_apply ( x , EDIT_KERNEL ) ,
2010-12-12 07:00:19 +03:00
" on_boot_kernel_browse_clicked " : self . browse_kernel ,
2013-08-18 20:25:20 +04:00
" on_boot_initrd_browse_clicked " : self . browse_initrd ,
" on_boot_dtb_browse_clicked " : self . browse_dtb ,
2012-05-14 17:24:56 +04:00
" on_boot_init_path_changed " : lambda * x : self . enable_apply ( x , EDIT_INIT ) ,
" on_disk_readonly_changed " : lambda * x : self . enable_apply ( x , EDIT_DISK_RO ) ,
" on_disk_shareable_changed " : lambda * x : self . enable_apply ( x , EDIT_DISK_SHARE ) ,
2013-10-04 05:39:01 +04:00
" on_disk_removable_changed " : lambda * x : self . enable_apply ( x , EDIT_DISK_REMOVABLE ) ,
2012-05-14 17:24:56 +04:00
" on_disk_cache_combo_changed " : lambda * x : self . enable_apply ( x , EDIT_DISK_CACHE ) ,
" on_disk_io_combo_changed " : lambda * x : self . enable_apply ( x , EDIT_DISK_IO ) ,
" on_disk_bus_combo_changed " : lambda * x : self . enable_apply ( x , EDIT_DISK_BUS ) ,
" on_disk_format_changed " : lambda * x : self . enable_apply ( x , EDIT_DISK_FORMAT ) ,
" on_disk_serial_changed " : lambda * x : self . enable_apply ( x , EDIT_DISK_SERIAL ) ,
2013-02-17 17:40:37 +04:00
" on_disk_iotune_changed " : self . iotune_changed ,
2012-05-14 17:24:56 +04:00
" on_network_source_combo_changed " : lambda * x : self . enable_apply ( x , EDIT_NET_SOURCE ) ,
" on_network_bridge_changed " : lambda * x : self . enable_apply ( x , EDIT_NET_SOURCE ) ,
" on_network-source-mode-combo_changed " : lambda * x : self . enable_apply ( x , EDIT_NET_SOURCE ) ,
" on_network_model_combo_changed " : lambda * x : self . enable_apply ( x , EDIT_NET_MODEL ) ,
" on_vport_type_changed " : lambda * x : self . enable_apply ( x , EDIT_NET_VPORT ) ,
" on_vport_managerid_changed " : lambda * x : self . enable_apply ( x ,
2011-07-15 00:18:42 +04:00
EDIT_NET_VPORT ) ,
2012-05-14 17:24:56 +04:00
" on_vport_typeid_changed " : lambda * x : self . enable_apply ( x ,
2011-07-15 00:18:42 +04:00
EDIT_NET_VPORT ) ,
2012-05-14 17:24:56 +04:00
" on_vport_typeidversion_changed " : lambda * x : self . enable_apply ( x ,
2011-07-15 00:18:42 +04:00
EDIT_NET_VPORT ) ,
2012-05-14 17:24:56 +04:00
" on_vport_instanceid_changed " : lambda * x : self . enable_apply ( x ,
2011-07-15 00:18:42 +04:00
EDIT_NET_VPORT ) ,
2012-05-14 17:24:56 +04:00
" on_gfx_type_combo_changed " : lambda * x : self . enable_apply ( x , EDIT_GFX_TYPE ) ,
" on_vnc_keymap_combo_changed " : lambda * x : self . enable_apply ( x ,
2011-07-15 00:18:42 +04:00
EDIT_GFX_KEYMAP ) ,
2013-08-01 03:14:17 +04:00
" on_vnc_use_password_toggled " : lambda * x : self . control_gfx_use_passwd ( x ) ,
2012-05-14 17:24:56 +04:00
" on_vnc_password_changed " : lambda * x : self . enable_apply ( x , EDIT_GFX_PASSWD ) ,
2011-07-15 00:18:42 +04:00
2012-05-14 17:24:56 +04:00
" on_sound_model_combo_changed " : lambda * x : self . enable_apply ( x ,
2011-07-15 00:18:42 +04:00
EDIT_SOUND_MODEL ) ,
2012-05-14 17:24:56 +04:00
" on_video_model_combo_changed " : lambda * x : self . enable_apply ( x ,
2011-07-15 00:18:42 +04:00
EDIT_VIDEO_MODEL ) ,
2012-05-14 17:24:56 +04:00
" on_watchdog_model_combo_changed " : lambda * x : self . enable_apply ( x ,
2011-07-15 00:18:42 +04:00
EDIT_WATCHDOG_MODEL ) ,
2012-05-14 17:24:56 +04:00
" on_watchdog_action_combo_changed " : lambda * x : self . enable_apply ( x ,
2011-07-15 00:18:42 +04:00
EDIT_WATCHDOG_ACTION ) ,
2012-05-14 17:24:56 +04:00
" on_smartcard_mode_combo_changed " : lambda * x : self . enable_apply ( x ,
2011-07-15 00:18:42 +04:00
EDIT_SMARTCARD_MODE ) ,
2011-06-23 19:42:03 +04:00
2009-07-09 22:35:36 +04:00
" on_config_apply_clicked " : self . config_apply ,
2011-07-19 22:51:16 +04:00
" on_config_cancel_clicked " : self . config_cancel ,
2009-07-09 22:35:36 +04:00
2009-12-11 03:18:24 +03:00
" on_config_cdrom_connect_clicked " : self . toggle_storage_media ,
2009-07-09 22:35:36 +04:00
" on_config_remove_clicked " : self . remove_xml_dev ,
2007-04-11 22:48:36 +04:00
" on_add_hardware_button_clicked " : self . add_hardware ,
2008-04-08 22:30:47 +04:00
2010-02-12 22:01:59 +03:00
" on_hw_list_button_press_event " : self . popup_addhw_menu ,
2009-10-30 20:25:27 +03:00
# Listeners stored in vmmConsolePages
" on_details_menu_view_fullscreen_activate " : self . console . toggle_fullscreen ,
2009-11-29 04:07:01 +03:00
" on_details_menu_view_size_to_vm_activate " : self . console . size_to_vm ,
2009-10-30 20:25:27 +03:00
" on_details_menu_view_scale_always_toggled " : self . console . set_scale_type ,
" on_details_menu_view_scale_fullscreen_toggled " : self . console . set_scale_type ,
" on_details_menu_view_scale_never_toggled " : self . console . set_scale_type ,
2011-06-01 20:22:05 +04:00
" on_console_pages_switch_page " : self . console . page_changed ,
2009-10-30 20:25:27 +03:00
" on_console_auth_password_activate " : self . console . auth_login ,
" on_console_auth_login_clicked " : self . console . auth_login ,
2012-05-14 17:24:56 +04:00
" on_controller_model_combo_changed " : lambda * x : self . enable_apply ( x ,
2011-09-23 19:14:15 +04:00
EDIT_CONTROLLER_MODEL ) ,
2009-10-30 20:25:27 +03:00
} )
2006-06-14 18:59:40 +04:00
2009-11-02 19:21:50 +03:00
# Deliberately keep all this after signal connection
2010-11-30 19:49:47 +03:00
self . vm . connect ( " status-changed " , self . refresh_vm_state )
self . vm . connect ( " config-changed " , self . refresh_vm_state )
2006-06-15 02:42:04 +04:00
self . vm . connect ( " resources-sampled " , self . refresh_resources )
2007-04-11 22:48:36 +04:00
2009-11-04 21:18:14 +03:00
self . populate_hw_list ( )
self . repopulate_boot_list ( )
2010-02-10 19:54:12 +03:00
self . hw_selected ( )
2010-11-30 19:49:47 +03:00
self . refresh_vm_state ( )
2006-08-29 23:52:19 +04:00
2011-07-24 05:16:54 +04:00
def _cleanup ( self ) :
2013-04-17 03:17:47 +04:00
self . oldhwkey = None
2011-07-20 04:29:07 +04:00
2011-07-24 05:16:54 +04:00
if self . addhw :
self . addhw . cleanup ( )
self . addhw = None
2011-04-12 02:35:21 +04:00
2011-07-24 05:16:54 +04:00
if self . storage_browser :
self . storage_browser . cleanup ( )
self . storage_browser = None
2011-04-12 02:35:21 +04:00
2011-07-24 05:16:54 +04:00
for key in self . media_choosers :
if self . media_choosers [ key ] :
self . media_choosers [ key ] . cleanup ( )
self . media_choosers = { }
2011-04-12 02:35:21 +04:00
2011-07-24 05:16:54 +04:00
self . console . cleanup ( )
self . console = None
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 18:18:47 +04:00
self . snapshots . cleanup ( )
self . snapshots = None
2011-06-20 04:49:41 +04:00
2011-07-24 05:16:54 +04:00
self . vm = None
self . conn = None
self . addhwmenu = None
2008-04-08 22:30:47 +04:00
2009-11-04 21:18:14 +03:00
def show ( self ) :
2012-02-01 03:16:54 +04:00
logging . debug ( " Showing VM details: %s " , self . vm )
2010-12-09 01:26:19 +03:00
vis = self . is_visible ( )
2009-11-04 21:18:14 +03:00
self . topwin . present ( )
2010-12-09 01:26:19 +03:00
if vis :
return
2009-11-04 21:18:14 +03:00
2011-04-13 18:47:31 +04:00
self . emit ( " details-opened " )
2010-11-30 19:49:47 +03:00
self . refresh_vm_state ( )
2009-11-04 21:18:14 +03:00
2011-07-19 05:31:06 +04:00
def customize_finish ( self , src ) :
ignore = src
2011-09-27 04:14:12 +04:00
if self . has_unapplied_changes ( self . get_hw_row ( ) ) :
return
2011-07-19 05:31:06 +04:00
return self . _close ( customize_finish = True )
2010-02-07 20:18:28 +03:00
def close ( self , ignore1 = None , ignore2 = None ) :
2012-02-01 03:16:54 +04:00
logging . debug ( " Closing VM details: %s " , self . vm )
2011-07-19 05:31:06 +04:00
return self . _close ( )
def _close ( self , customize_finish = False ) :
2011-07-14 21:13:13 +04:00
fs = self . widget ( " details-menu-view-fullscreen " )
2009-11-04 21:18:14 +03:00
if fs . get_active ( ) :
fs . set_active ( False )
if not self . is_visible ( ) :
return
self . topwin . hide ( )
2011-07-19 05:31:06 +04:00
if ( self . console . viewer and
2012-02-02 02:26:46 +04:00
self . console . viewer . display and
2012-05-14 17:24:56 +04:00
self . console . viewer . display . get_visible ( ) ) :
2009-11-04 21:18:14 +03:00
try :
2010-12-22 04:13:11 +03:00
self . console . close_viewer ( )
2009-11-04 21:18:14 +03:00
except :
2010-12-22 04:13:11 +03:00
logging . error ( " Failure when disconnecting from desktop server " )
2010-02-07 20:18:28 +03:00
2011-07-19 05:31:06 +04:00
if customize_finish :
self . emit ( " customize-finished " )
else :
self . emit ( " details-closed " )
2009-11-04 21:18:14 +03:00
return 1
def is_visible ( self ) :
2012-05-14 17:24:56 +04:00
return bool ( self . topwin . get_visible ( ) )
2009-11-04 21:18:14 +03:00
2009-11-02 19:21:50 +03:00
##########################
# Initialization helpers #
##########################
def init_menus ( self ) :
2013-07-01 22:33:59 +04:00
# Virtual Machine menu
2013-09-22 21:24:59 +04:00
menu = uihelpers . VMShutdownMenu ( self , lambda : self . vm )
self . widget ( " control-shutdown " ) . set_menu ( menu )
self . widget ( " control-shutdown " ) . set_icon_name ( " system-shutdown " )
2009-11-02 19:21:50 +03:00
2013-09-22 23:44:58 +04:00
topmenu = self . widget ( " details-vm-menu " )
submenu = topmenu . get_submenu ( )
newmenu = uihelpers . VMActionMenu ( self , lambda : self . vm ,
show_open = False )
for child in submenu . get_children ( ) :
submenu . remove ( child )
newmenu . add ( child ) # pylint: disable=E1101
topmenu . set_submenu ( newmenu )
topmenu . show_all ( )
2009-11-18 01:47:34 +03:00
2010-02-12 22:01:59 +03:00
# Add HW popup menu
2012-05-14 17:24:56 +04:00
self . addhwmenu = Gtk . Menu ( )
2011-07-13 05:42:19 +04:00
2012-05-14 17:24:56 +04:00
addHW = Gtk . ImageMenuItem ( _ ( " _Add Hardware " ) )
2013-04-17 02:47:16 +04:00
addHW . set_use_underline ( True )
2012-05-14 17:24:56 +04:00
addHWImg = Gtk . Image ( )
addHWImg . set_from_stock ( Gtk . STOCK_ADD , Gtk . IconSize . MENU )
2010-02-12 22:01:59 +03:00
addHW . set_image ( addHWImg )
addHW . show ( )
addHW . connect ( " activate " , self . add_hardware )
2011-07-13 05:42:19 +04:00
2012-05-14 17:24:56 +04:00
rmHW = Gtk . ImageMenuItem ( _ ( " _Remove Hardware " ) )
2013-04-17 02:47:16 +04:00
rmHW . set_use_underline ( True )
2012-05-14 17:24:56 +04:00
rmHWImg = Gtk . Image ( )
rmHWImg . set_from_stock ( Gtk . STOCK_REMOVE , Gtk . IconSize . MENU )
2011-07-13 05:42:19 +04:00
rmHW . set_image ( rmHWImg )
rmHW . show ( )
rmHW . connect ( " activate " , self . remove_xml_dev )
2010-02-12 22:01:59 +03:00
self . addhwmenu . add ( addHW )
2011-07-13 05:42:19 +04:00
self . addhwmenu . add ( rmHW )
2010-02-12 22:01:59 +03:00
2009-11-02 19:21:50 +03:00
# Don't allowing changing network/disks for Dom0
dom0 = self . vm . is_management_domain ( )
2011-07-14 21:13:13 +04:00
self . widget ( " add-hardware-button " ) . set_sensitive ( not dom0 )
2009-11-02 19:21:50 +03:00
2011-07-14 21:13:13 +04:00
self . widget ( " hw-panel " ) . set_show_tabs ( False )
self . widget ( " details-pages " ) . set_show_tabs ( False )
self . widget ( " console-pages " ) . set_show_tabs ( False )
self . widget ( " details-menu-view-toolbar " ) . set_active (
self . config . get_details_show_toolbar ( ) )
2009-11-02 19:21:50 +03:00
2011-05-19 02:54:27 +04:00
# Keycombo menu (ctrl+alt+del etc.)
self . keycombo_menu = uihelpers . build_keycombo_menu (
self . console . send_key )
2011-07-14 21:13:13 +04:00
self . widget ( " details-menu-send-key " ) . set_submenu ( self . keycombo_menu )
2011-05-19 02:54:27 +04:00
2009-11-02 19:21:50 +03:00
def init_graphs ( self ) :
2013-09-27 22:17:57 +04:00
def _make_graph ( ) :
g = Sparkline ( )
g . set_property ( " reversed " , True )
g . show ( )
return g
2009-11-02 19:21:50 +03:00
2013-09-27 22:17:57 +04:00
self . cpu_usage_graph = _make_graph ( )
self . widget ( " overview-cpu-usage-align " ) . add ( self . cpu_usage_graph )
2009-11-02 19:21:50 +03:00
2013-09-27 22:17:57 +04:00
self . memory_usage_graph = _make_graph ( )
self . widget ( " overview-memory-usage-align " ) . add ( self . memory_usage_graph )
2009-11-02 19:21:50 +03:00
2013-09-27 22:17:57 +04:00
self . disk_io_graph = _make_graph ( )
2009-11-02 19:21:50 +03:00
self . disk_io_graph . set_property ( " filled " , False )
self . disk_io_graph . set_property ( " num_sets " , 2 )
2013-04-12 00:32:00 +04:00
self . disk_io_graph . set_property ( " rgb " , [ x / 255.0 for x in
[ 0x82 , 0x00 , 0x3B , 0x29 , 0x5C , 0x45 ] ] )
2013-09-27 22:17:57 +04:00
self . widget ( " overview-disk-usage-align " ) . add ( self . disk_io_graph )
2009-11-02 19:21:50 +03:00
2013-09-27 22:17:57 +04:00
self . network_traffic_graph = _make_graph ( )
2009-11-02 19:21:50 +03:00
self . network_traffic_graph . set_property ( " filled " , False )
self . network_traffic_graph . set_property ( " num_sets " , 2 )
2013-04-12 00:32:00 +04:00
self . network_traffic_graph . set_property ( " rgb " , [ x / 255.0 for x in
2009-11-02 19:21:50 +03:00
[ 0x82 , 0x00 , 0x3B ,
2013-04-12 00:32:00 +04:00
0x29 , 0x5C , 0x45 ] ] )
2013-09-27 22:17:57 +04:00
self . widget ( " overview-network-traffic-align " ) . add (
self . network_traffic_graph )
2010-06-21 21:47:07 +04:00
2009-11-02 19:21:50 +03:00
def init_details ( self ) :
2009-11-04 21:18:14 +03:00
# Hardware list
2010-09-08 02:38:01 +04:00
# [ label, icon name, icon size, hw type, hw data/class]
2012-05-14 17:24:56 +04:00
hw_list_model = Gtk . ListStore ( str , str , int , int , object )
2011-07-14 21:13:13 +04:00
self . widget ( " hw-list " ) . set_model ( hw_list_model )
2009-11-04 21:18:14 +03:00
2012-05-14 17:24:56 +04:00
hwCol = Gtk . TreeViewColumn ( " Hardware " )
2009-11-04 21:18:14 +03:00
hwCol . set_spacing ( 6 )
hwCol . set_min_width ( 165 )
2012-05-14 17:24:56 +04:00
hw_txt = Gtk . CellRendererText ( )
hw_img = Gtk . CellRendererPixbuf ( )
2009-11-04 21:18:14 +03:00
hwCol . pack_start ( hw_img , False )
hwCol . pack_start ( hw_txt , True )
hwCol . add_attribute ( hw_txt , ' text ' , HW_LIST_COL_LABEL )
hwCol . add_attribute ( hw_img , ' stock-size ' , HW_LIST_COL_ICON_SIZE )
hwCol . add_attribute ( hw_img , ' icon-name ' , HW_LIST_COL_ICON_NAME )
2011-07-14 21:13:13 +04:00
self . widget ( " hw-list " ) . append_column ( hwCol )
2009-11-04 21:18:14 +03:00
2010-02-10 20:16:59 +03:00
# Description text view
2011-07-14 21:13:13 +04:00
desc = self . widget ( " overview-description " )
2012-05-14 17:24:56 +04:00
buf = Gtk . TextBuffer ( )
2011-07-15 00:18:42 +04:00
buf . connect ( " changed " , self . enable_apply , EDIT_DESC )
2010-02-10 20:16:59 +03:00
desc . set_buffer ( buf )
2011-07-18 22:53:57 +04:00
# List of applications.
2012-02-02 02:26:46 +04:00
apps_list = self . widget ( " inspection-apps " )
2012-05-14 17:24:56 +04:00
apps_model = Gtk . ListStore ( str , str , str )
2011-07-18 22:53:57 +04:00
apps_list . set_model ( apps_model )
2012-05-14 17:24:56 +04:00
name_col = Gtk . TreeViewColumn ( _ ( " Name " ) )
version_col = Gtk . TreeViewColumn ( _ ( " Version " ) )
summary_col = Gtk . TreeViewColumn ( )
2011-07-18 22:53:57 +04:00
apps_list . append_column ( name_col )
apps_list . append_column ( version_col )
apps_list . append_column ( summary_col )
2012-05-14 17:24:56 +04:00
name_text = Gtk . CellRendererText ( )
2011-07-18 22:53:57 +04:00
name_col . pack_start ( name_text , True )
name_col . add_attribute ( name_text , ' text ' , 0 )
name_col . set_sort_column_id ( 0 )
2012-05-14 17:24:56 +04:00
version_text = Gtk . CellRendererText ( )
2011-07-18 22:53:57 +04:00
version_col . pack_start ( version_text , True )
version_col . add_attribute ( version_text , ' text ' , 1 )
version_col . set_sort_column_id ( 1 )
2012-05-14 17:24:56 +04:00
summary_text = Gtk . CellRendererText ( )
2011-07-18 22:53:57 +04:00
summary_col . pack_start ( summary_text , True )
summary_col . add_attribute ( summary_text , ' text ' , 2 )
summary_col . set_sort_column_id ( 2 )
2009-11-04 21:16:38 +03:00
# Clock combo
2013-09-28 20:21:35 +04:00
clock_combo = self . widget ( " overview-clock " )
2012-05-14 17:24:56 +04:00
clock_model = Gtk . ListStore ( str )
2009-11-04 21:16:38 +03:00
clock_combo . set_model ( clock_model )
2012-05-14 17:24:56 +04:00
clock_model . set_sort_column_id ( 0 , Gtk . SortType . ASCENDING )
2013-09-28 20:21:35 +04:00
uihelpers . set_combo_text_column ( clock_combo , 0 )
for offset in [ " localtime " ] :
2009-11-04 21:16:38 +03:00
clock_model . append ( [ offset ] )
2012-01-05 13:35:40 +04:00
arch = self . vm . get_arch ( )
2013-07-06 22:12:13 +04:00
caps = self . vm . conn . caps
2012-01-05 13:35:40 +04:00
2013-09-02 03:21:21 +04:00
# Machine type
2013-09-28 20:21:35 +04:00
machtype_combo = self . widget ( " machine-type " )
2013-09-02 03:21:21 +04:00
machtype_model = Gtk . ListStore ( str )
machtype_combo . set_model ( machtype_model )
text = Gtk . CellRendererText ( )
machtype_combo . pack_start ( text , True )
machtype_combo . add_attribute ( text , ' text ' , 0 )
machtype_model . set_sort_column_id ( 0 , Gtk . SortType . ASCENDING )
2012-01-05 13:35:40 +04:00
2013-09-28 20:21:35 +04:00
show_machine = ( arch not in [ " i686 " , " x86_64 " ] )
uihelpers . set_grid_row_visible ( self . widget ( " machine-type " ) ,
show_machine )
if show_machine :
2013-09-02 03:21:21 +04:00
machines = [ ]
try :
ignore , domain = caps . guest_lookup (
os_type = self . vm . get_abi_type ( ) ,
arch = self . vm . get_arch ( ) ,
typ = self . vm . get_hv_type ( ) ,
machine = self . vm . get_machtype ( ) )
machines = domain . machines [ : ]
except :
logging . exception ( " Error determining machine list " )
for machine in machines :
if machine == " none " :
continue
machtype_model . append ( [ machine ] )
2012-01-05 13:35:40 +04:00
2009-11-16 19:36:13 +03:00
# VCPU Pinning list
2011-07-14 21:13:13 +04:00
generate_cpuset = self . widget ( " config-vcpupin-generate " )
generate_warn = self . widget ( " config-vcpupin-generate-err " )
2013-07-06 22:12:13 +04:00
if not self . conn . caps . host . topology :
2010-06-21 21:32:59 +04:00
generate_cpuset . set_sensitive ( False )
generate_warn . show ( )
2013-09-28 20:21:35 +04:00
generate_warn . set_tooltip_text (
_ ( " Libvirt did not detect NUMA capabilities. " ) )
2010-06-21 21:32:59 +04:00
2009-11-16 19:36:13 +03:00
# [ VCPU #, Currently running on Phys CPU #, CPU Pinning list ]
2011-07-14 21:13:13 +04:00
vcpu_list = self . widget ( " config-vcpu-list " )
2012-05-14 17:24:56 +04:00
vcpu_model = Gtk . ListStore ( str , str , str )
2009-11-16 19:36:13 +03:00
vcpu_list . set_model ( vcpu_model )
2012-05-14 17:24:56 +04:00
vcpuCol = Gtk . TreeViewColumn ( _ ( " VCPU " ) )
physCol = Gtk . TreeViewColumn ( _ ( " On CPU " ) )
pinCol = Gtk . TreeViewColumn ( _ ( " Pinning " ) )
2009-11-16 19:36:13 +03:00
vcpu_list . append_column ( vcpuCol )
vcpu_list . append_column ( physCol )
vcpu_list . append_column ( pinCol )
2012-05-14 17:24:56 +04:00
vcpu_text = Gtk . CellRendererText ( )
2009-11-16 19:36:13 +03:00
vcpuCol . pack_start ( vcpu_text , True )
vcpuCol . add_attribute ( vcpu_text , ' text ' , 0 )
vcpuCol . set_sort_column_id ( 0 )
2012-05-14 17:24:56 +04:00
phys_text = Gtk . CellRendererText ( )
2009-11-16 19:36:13 +03:00
physCol . pack_start ( phys_text , True )
physCol . add_attribute ( phys_text , ' text ' , 1 )
physCol . set_sort_column_id ( 1 )
2012-05-14 17:24:56 +04:00
pin_text = Gtk . CellRendererText ( )
2009-11-16 19:36:13 +03:00
pin_text . set_property ( " editable " , True )
pin_text . connect ( " edited " , self . config_vcpu_pin )
pinCol . pack_start ( pin_text , True )
pinCol . add_attribute ( pin_text , ' text ' , 2 )
2009-11-04 21:18:14 +03:00
# Boot device list
2011-07-14 21:13:13 +04:00
boot_list = self . widget ( " config-boot-list " )
2010-02-25 04:37:41 +03:00
# model = [ XML boot type, display name, icon name, enabled ]
2012-05-14 17:24:56 +04:00
boot_list_model = Gtk . ListStore ( str , str , str , bool )
2009-11-04 21:18:14 +03:00
boot_list . set_model ( boot_list_model )
2009-11-02 19:21:50 +03:00
2012-05-14 17:24:56 +04:00
chkCol = Gtk . TreeViewColumn ( )
txtCol = Gtk . TreeViewColumn ( )
2010-02-25 04:37:41 +03:00
boot_list . append_column ( chkCol )
boot_list . append_column ( txtCol )
2012-05-14 17:24:56 +04:00
chk = Gtk . CellRendererToggle ( )
2010-02-25 04:37:41 +03:00
chk . connect ( " toggled " , self . config_boot_toggled )
chkCol . pack_start ( chk , False )
chkCol . add_attribute ( chk , ' active ' , BOOT_ACTIVE )
2012-05-14 17:24:56 +04:00
icon = Gtk . CellRendererPixbuf ( )
2010-02-25 04:37:41 +03:00
txtCol . pack_start ( icon , False )
txtCol . add_attribute ( icon , ' icon-name ' , BOOT_ICON )
2012-05-14 17:24:56 +04:00
text = Gtk . CellRendererText ( )
2010-02-25 04:37:41 +03:00
txtCol . pack_start ( text , True )
txtCol . add_attribute ( text , ' text ' , BOOT_LABEL )
txtCol . add_attribute ( text , ' sensitive ' , BOOT_ACTIVE )
2008-04-08 22:30:47 +04:00
2010-11-29 22:06:43 +03:00
no_default = not self . is_customize_dialog
2010-12-11 03:20:14 +03:00
2011-03-18 00:41:29 +03:00
# CPU features
2013-07-06 22:12:13 +04:00
caps = self . vm . conn . caps
2010-12-17 03:36:07 +03:00
cpu_values = None
cpu_names = [ ]
2011-03-18 00:41:29 +03:00
all_features = [ ]
2010-12-17 03:36:07 +03:00
try :
cpu_values = caps . get_cpu_values ( self . vm . get_arch ( ) )
2013-04-12 00:32:00 +04:00
cpu_names = sorted ( [ c . model for c in cpu_values . cpus ] ,
2010-12-17 03:36:07 +03:00
key = str . lower )
2011-03-18 00:41:29 +03:00
all_features = cpu_values . features
2010-12-17 03:36:07 +03:00
except :
logging . exception ( " Error populating CPU model list " )
2011-07-13 22:35:34 +04:00
# [ feature name, mode]
2011-07-14 21:13:13 +04:00
feat_list = self . widget ( " cpu-features " )
2012-05-14 17:24:56 +04:00
feat_model = Gtk . ListStore ( str , str )
2011-03-18 00:41:29 +03:00
feat_list . set_model ( feat_model )
2012-05-14 17:24:56 +04:00
nameCol = Gtk . TreeViewColumn ( )
polCol = Gtk . TreeViewColumn ( )
2011-07-13 22:35:34 +04:00
polCol . set_min_width ( 80 )
2011-03-18 00:41:29 +03:00
feat_list . append_column ( nameCol )
2011-07-13 22:35:34 +04:00
feat_list . append_column ( polCol )
2011-03-18 00:41:29 +03:00
2011-07-13 22:35:34 +04:00
# Feature name col
2012-05-14 17:24:56 +04:00
name_text = Gtk . CellRendererText ( )
2011-03-18 00:41:29 +03:00
nameCol . pack_start ( name_text , True )
nameCol . add_attribute ( name_text , ' text ' , 0 )
nameCol . set_sort_column_id ( 0 )
2011-07-13 22:35:34 +04:00
# Feature policy col
2012-05-14 17:24:56 +04:00
feat_combo = Gtk . CellRendererCombo ( )
m = Gtk . ListStore ( str )
2011-07-13 22:35:34 +04:00
for p in virtinst . CPUFeature . POLICIES :
m . append ( [ p ] )
m . append ( [ " default " ] )
feat_combo . set_property ( " model " , m )
feat_combo . set_property ( " text-column " , 0 )
feat_combo . set_property ( " editable " , True )
polCol . pack_start ( feat_combo , False )
polCol . add_attribute ( feat_combo , ' text ' , 1 )
polCol . set_sort_column_id ( 1 )
def feature_changed ( src , index , treeiter , model ) :
model [ index ] [ 1 ] = src . get_property ( " model " ) [ treeiter ] [ 0 ]
2011-07-15 00:18:42 +04:00
self . enable_apply ( EDIT_CPU )
2011-03-18 00:41:29 +03:00
2011-07-13 22:35:34 +04:00
feat_combo . connect ( " changed " , feature_changed , feat_model )
2011-03-18 00:41:29 +03:00
for name in all_features :
2011-07-13 22:35:34 +04:00
feat_model . append ( [ name , " default " ] )
2011-03-18 00:41:29 +03:00
# CPU model combo
2011-07-14 21:13:13 +04:00
cpu_model = self . widget ( " cpu-model " )
2010-12-17 03:36:07 +03:00
2012-05-14 17:24:56 +04:00
model = Gtk . ListStore ( str , object )
2010-12-17 03:36:07 +03:00
cpu_model . set_model ( model )
2012-05-14 17:24:56 +04:00
cpu_model . set_entry_text_column ( 0 )
model . set_sort_column_id ( 0 , Gtk . SortType . ASCENDING )
2010-12-17 03:36:07 +03:00
for name in cpu_names :
model . append ( [ name , cpu_values . get_cpu ( name ) ] )
2010-05-20 16:34:32 +04:00
# Disk cache combo
2013-09-28 20:21:35 +04:00
disk_cache = self . widget ( " disk-cache " )
2010-05-20 16:34:32 +04:00
uihelpers . build_cache_combo ( self . vm , disk_cache )
2011-07-24 04:41:35 +04:00
# Disk io combo
2013-09-28 20:21:35 +04:00
disk_io = self . widget ( " disk-io " )
2011-07-24 04:41:35 +04:00
uihelpers . build_io_combo ( self . vm , disk_io )
2010-12-11 03:20:14 +03:00
# Disk format combo
2011-07-14 21:13:13 +04:00
format_list = self . widget ( " disk-format " )
2013-08-20 11:15:47 +04:00
uihelpers . update_storage_format_combo ( self . vm , format_list , False )
2010-12-11 03:20:14 +03:00
2010-12-11 04:33:41 +03:00
# Disk bus combo
2013-09-28 20:21:35 +04:00
disk_bus = self . widget ( " disk-bus " )
2010-12-11 04:33:41 +03:00
uihelpers . build_disk_bus_combo ( self . vm , disk_bus )
2013-02-17 17:40:37 +04:00
# Disk iotune expander
if not ( self . conn . is_qemu ( ) or self . conn . is_test_conn ( ) ) :
2013-09-02 04:18:14 +04:00
self . widget ( " iotune-expander " ) . set_visible ( False )
2013-02-17 17:40:37 +04:00
2011-03-17 23:33:40 +03:00
# Network source
2013-09-28 20:21:35 +04:00
net_source = self . widget ( " network-source " )
2011-07-14 21:13:13 +04:00
net_bridge = self . widget ( " network-bridge-box " )
2013-09-28 20:21:35 +04:00
source_mode_combo = self . widget ( " network-source-mode " )
2011-07-14 21:13:13 +04:00
vport_expander = self . widget ( " vport-expander " )
2013-09-28 20:21:35 +04:00
uihelpers . init_network_list ( net_source , net_bridge ,
source_mode_combo , vport_expander )
2011-04-19 15:08:15 +04:00
# source mode
2013-09-28 20:21:35 +04:00
source_mode = self . widget ( " network-source-mode " )
2011-04-19 15:08:15 +04:00
uihelpers . build_source_mode_combo ( self . vm , source_mode )
2011-03-17 23:33:40 +03:00
2010-03-24 05:15:53 +03:00
# Network model
2013-09-28 20:21:35 +04:00
net_model = self . widget ( " network-model " )
2010-03-24 05:15:53 +03:00
uihelpers . build_netmodel_combo ( self . vm , net_model )
2011-03-17 21:24:36 +03:00
# Graphics type
2013-09-28 20:21:35 +04:00
gfx_type = self . widget ( " gfx-type " )
2012-05-14 17:24:56 +04:00
model = Gtk . ListStore ( str , str )
2011-03-17 21:24:36 +03:00
gfx_type . set_model ( model )
2013-09-28 20:21:35 +04:00
uihelpers . set_combo_text_column ( gfx_type , 1 )
model . append ( [ virtinst . VirtualGraphics . TYPE_VNC , " VNC " ] )
model . append ( [ virtinst . VirtualGraphics . TYPE_SPICE , " Spice " ] )
2011-03-17 21:24:36 +03:00
gfx_type . set_active ( - 1 )
2010-12-12 04:54:48 +03:00
# Graphics keymap
2013-09-28 20:21:35 +04:00
gfx_keymap = self . widget ( " gfx-keymap " )
2011-03-17 21:24:36 +03:00
uihelpers . build_vnc_keymap_combo ( self . vm , gfx_keymap ,
2010-12-12 04:54:48 +03:00
no_default = no_default )
2010-03-24 05:15:53 +03:00
# Sound model
2013-09-28 20:21:35 +04:00
sound_dev = self . widget ( " sound-model " )
2010-03-24 05:15:53 +03:00
uihelpers . build_sound_combo ( self . vm , sound_dev , no_default = no_default )
2009-11-05 22:59:11 +03:00
# Video model combo
2013-09-28 20:21:35 +04:00
video_dev = self . widget ( " video-model " )
2010-03-24 05:15:53 +03:00
uihelpers . build_video_combo ( self . vm , video_dev , no_default = no_default )
2010-03-24 07:22:17 +03:00
# Watchdog model combo
2013-09-28 20:21:35 +04:00
combo = self . widget ( " watchdog-model " )
2010-03-24 07:22:17 +03:00
uihelpers . build_watchdogmodel_combo ( self . vm , combo ,
no_default = no_default )
# Watchdog action combo
2013-09-28 20:21:35 +04:00
combo = self . widget ( " watchdog-action " )
2010-03-24 07:22:17 +03:00
uihelpers . build_watchdogaction_combo ( self . vm , combo ,
no_default = no_default )
2011-06-23 19:42:03 +04:00
# Smartcard mode
2013-09-28 20:21:35 +04:00
sc_mode = self . widget ( " smartcard-mode " )
2011-06-23 19:42:03 +04:00
uihelpers . build_smartcard_mode_combo ( self . vm , sc_mode )
2011-09-23 19:14:15 +04:00
# Controller model
2013-09-28 20:21:35 +04:00
combo = self . widget ( " controller-model " )
2012-05-14 17:24:56 +04:00
model = Gtk . ListStore ( str , str )
2011-09-23 19:14:15 +04:00
combo . set_model ( model )
2013-09-28 20:21:35 +04:00
uihelpers . set_combo_text_column ( combo , 1 )
2011-09-23 19:14:15 +04:00
combo . set_active ( - 1 )
2013-09-28 20:21:35 +04:00
def set_combo_entry ( self , widget , value , label = " " , comparefunc = None ) :
2011-03-17 21:24:36 +03:00
label = label or value
2013-09-28 20:21:35 +04:00
model_combo = self . widget ( widget )
2011-03-17 23:33:40 +03:00
idx = - 1
if comparefunc :
model_in_list , idx = comparefunc ( model_combo . get_model ( ) , value )
else :
2013-09-28 20:21:35 +04:00
model_list = [ x [ 0 ] for x in model_combo . get_model ( ) ]
2011-03-17 23:33:40 +03:00
model_in_list = ( value in model_list )
if model_in_list :
idx = model_list . index ( value )
2010-03-24 05:15:53 +03:00
2013-09-28 20:21:35 +04:00
model_combo . set_active ( idx )
if idx == - 1 and model_combo . get_has_entry ( ) :
model_combo . get_child ( ) . set_text ( value or " " )
2009-11-04 21:18:14 +03:00
2013-09-28 20:21:35 +04:00
def get_combo_entry ( self , widgetname ) :
2011-07-14 21:13:13 +04:00
combo = self . widget ( widgetname )
2013-09-28 20:21:35 +04:00
if combo . get_active ( ) > = 0 :
return combo . get_model ( ) [ combo . get_active ( ) ] [ 0 ]
if not combo . get_has_entry ( ) :
2011-03-17 21:17:31 +03:00
return None
2013-09-28 20:21:35 +04:00
return combo . get_child ( ) . get_text ( ) . strip ( )
2011-03-17 21:17:31 +03:00
2009-11-04 21:18:14 +03:00
##########################
# Window state listeners #
##########################
2006-09-01 19:18:49 +04:00
2009-11-29 04:07:01 +03:00
def window_resized ( self , ignore , event ) :
# Sometimes dimensions change when window isn't visible
if not self . is_visible ( ) :
return
self . vm . set_details_window_size ( event . width , event . height )
2010-02-12 22:01:59 +03:00
def popup_addhw_menu ( self , widget , event ) :
2010-12-09 19:22:35 +03:00
ignore = widget
2010-02-12 22:01:59 +03:00
if event . button != 3 :
return
2013-04-12 16:38:36 +04:00
self . addhwmenu . popup ( None , None , None , None , 0 , event . time )
2010-02-12 22:01:59 +03:00
2009-11-04 21:18:14 +03:00
def control_fullscreen ( self , src ) :
2011-07-14 21:13:13 +04:00
menu = self . widget ( " details-menu-view-fullscreen " )
2009-11-04 21:18:14 +03:00
if src . get_active ( ) != menu . get_active ( ) :
menu . set_active ( src . get_active ( ) )
2008-06-13 22:40:26 +04:00
2009-11-04 21:18:14 +03:00
def toggle_toolbar ( self , src ) :
2011-10-30 21:28:18 +04:00
if self . is_customize_dialog :
return
2009-11-04 21:18:14 +03:00
active = src . get_active ( )
self . config . set_details_show_toolbar ( active )
2011-10-30 21:28:18 +04:00
2011-07-14 21:13:13 +04:00
if ( active and not
self . widget ( " details-menu-view-fullscreen " ) . get_active ( ) ) :
self . widget ( " toolbar-box " ) . show ( )
2009-11-04 21:18:14 +03:00
else :
2011-07-14 21:13:13 +04:00
self . widget ( " toolbar-box " ) . hide ( )
2006-11-03 18:02:02 +03:00
2011-07-20 04:29:07 +04:00
def get_selected_row ( self , widget ) :
2010-02-25 04:37:41 +03:00
selection = widget . get_selection ( )
model , treepath = selection . get_selected ( )
2012-11-08 17:15:02 +04:00
if treepath is None :
2010-02-25 04:37:41 +03:00
return None
return model [ treepath ]
2011-07-20 04:29:07 +04:00
def get_boot_selection ( self ) :
return self . get_selected_row ( self . widget ( " config-boot-list " ) )
2011-08-29 20:47:44 +04:00
def set_hw_selection ( self , page , disable_apply = True ) :
if disable_apply :
2012-09-27 21:47:13 +04:00
self . disable_apply ( )
2011-08-29 20:47:44 +04:00
2011-07-14 21:13:13 +04:00
hwlist = self . widget ( " hw-list " )
2010-11-24 22:19:44 +03:00
selection = hwlist . get_selection ( )
selection . select_path ( str ( page ) )
2011-07-20 04:29:07 +04:00
def get_hw_row ( self ) :
return self . get_selected_row ( self . widget ( " hw-list " ) )
2009-11-04 21:18:14 +03:00
def get_hw_selection ( self , field ) :
2011-07-20 04:29:07 +04:00
row = self . get_hw_row ( )
if not row :
2009-11-04 21:18:14 +03:00
return None
2011-07-20 04:29:07 +04:00
return row [ field ]
2008-06-13 22:40:26 +04:00
2010-02-10 19:54:12 +03:00
def force_get_hw_pagetype ( self , page = None ) :
if page :
return page
2009-07-09 22:35:44 +04:00
2010-02-10 19:54:12 +03:00
page = self . get_hw_selection ( HW_LIST_COL_TYPE )
if page is None :
page = HW_LIST_TYPE_GENERAL
2011-08-29 20:47:44 +04:00
self . set_hw_selection ( 0 )
2009-03-01 03:27:20 +03:00
2010-02-10 19:54:12 +03:00
return page
2011-07-20 04:29:07 +04:00
def has_unapplied_changes ( self , row ) :
if not row :
return False
2012-11-09 15:13:22 +04:00
if not self . widget ( " config-apply " ) . get_sensitive ( ) :
2011-07-20 04:29:07 +04:00
return False
2013-08-09 17:23:01 +04:00
if not uihelpers . chkbox_helper ( self ,
2011-07-20 04:29:07 +04:00
self . config . get_confirm_unapplied ,
self . config . set_confirm_unapplied ,
text1 = ( _ ( " There are unapplied changes. Would you like to apply "
" them now? " ) ) ,
chktext = _ ( " Don ' t warn me again. " ) ,
2011-07-22 21:11:04 +04:00
alwaysrecord = True ,
default = False ) :
2011-07-20 04:29:07 +04:00
return False
return not self . config_apply ( row = row )
def hw_changed ( self , ignore ) :
newrow = self . get_hw_row ( )
model = self . widget ( " hw-list " ) . get_model ( )
2013-04-17 03:17:47 +04:00
if newrow [ HW_LIST_COL_DEVICE ] == self . oldhwkey :
2011-07-20 04:29:07 +04:00
return
2013-04-17 03:17:47 +04:00
oldhwrow = None
for row in model :
if row [ HW_LIST_COL_DEVICE ] == self . oldhwkey :
oldhwrow = row
break
if self . has_unapplied_changes ( oldhwrow ) :
2011-07-20 04:29:07 +04:00
# Unapplied changes, and syncing them failed
pageidx = 0
for idx in range ( len ( model ) ) :
2013-04-17 03:17:47 +04:00
if model [ idx ] [ HW_LIST_COL_DEVICE ] == self . oldhwkey :
2011-07-20 04:29:07 +04:00
pageidx = idx
break
2011-08-29 20:47:44 +04:00
self . set_hw_selection ( pageidx , disable_apply = False )
2011-07-20 04:29:07 +04:00
else :
2013-04-17 03:17:47 +04:00
self . oldhwkey = newrow [ HW_LIST_COL_DEVICE ]
2011-07-20 04:29:07 +04:00
self . hw_selected ( )
def hw_selected ( self , page = None ) :
2010-02-10 19:54:12 +03:00
pagetype = self . force_get_hw_pagetype ( page )
2011-07-14 21:13:13 +04:00
self . widget ( " config-remove " ) . set_sensitive ( True )
self . widget ( " hw-panel " ) . set_sensitive ( True )
self . widget ( " hw-panel " ) . show ( )
2007-04-12 23:36:04 +04:00
2010-03-04 02:47:59 +03:00
try :
if pagetype == HW_LIST_TYPE_GENERAL :
self . refresh_overview_page ( )
elif pagetype == HW_LIST_TYPE_STATS :
self . refresh_stats_page ( )
elif pagetype == HW_LIST_TYPE_CPU :
self . refresh_config_cpu ( )
elif pagetype == HW_LIST_TYPE_MEMORY :
self . refresh_config_memory ( )
elif pagetype == HW_LIST_TYPE_BOOT :
self . refresh_boot_page ( )
elif pagetype == HW_LIST_TYPE_DISK :
self . refresh_disk_page ( )
elif pagetype == HW_LIST_TYPE_NIC :
self . refresh_network_page ( )
elif pagetype == HW_LIST_TYPE_INPUT :
self . refresh_input_page ( )
elif pagetype == HW_LIST_TYPE_GRAPHICS :
self . refresh_graphics_page ( )
elif pagetype == HW_LIST_TYPE_SOUND :
self . refresh_sound_page ( )
elif pagetype == HW_LIST_TYPE_CHAR :
self . refresh_char_page ( )
elif pagetype == HW_LIST_TYPE_HOSTDEV :
self . refresh_hostdev_page ( )
elif pagetype == HW_LIST_TYPE_VIDEO :
self . refresh_video_page ( )
2010-03-24 07:22:17 +03:00
elif pagetype == HW_LIST_TYPE_WATCHDOG :
self . refresh_watchdog_page ( )
2010-12-16 20:41:47 +03:00
elif pagetype == HW_LIST_TYPE_CONTROLLER :
self . refresh_controller_page ( )
2011-05-19 23:18:33 +04:00
elif pagetype == HW_LIST_TYPE_FILESYSTEM :
self . refresh_filesystem_page ( )
2011-06-23 19:42:03 +04:00
elif pagetype == HW_LIST_TYPE_SMARTCARD :
self . refresh_smartcard_page ( )
2011-09-02 05:23:27 +04:00
elif pagetype == HW_LIST_TYPE_REDIRDEV :
self . refresh_redir_page ( )
2013-06-26 05:45:08 +04:00
elif pagetype == HW_LIST_TYPE_TPM :
self . refresh_tpm_page ( )
2013-09-23 17:39:56 +04:00
elif pagetype == HW_LIST_TYPE_RNG :
self . refresh_rng_page ( )
2014-01-10 13:37:55 +04:00
elif pagetype == HW_LIST_TYPE_PANIC :
self . refresh_panic_page ( )
2010-03-04 02:47:59 +03:00
else :
pagetype = - 1
except Exception , e :
2011-04-06 19:22:03 +04:00
self . err . show_err ( _ ( " Error refreshing hardware page: %s " ) % str ( e ) )
2010-03-04 02:47:59 +03:00
return
2009-03-01 03:27:20 +03:00
2009-07-09 22:35:44 +04:00
rem = pagetype in remove_pages
2011-07-20 04:29:07 +04:00
self . disable_apply ( )
2013-09-02 04:18:14 +04:00
self . widget ( " config-remove " ) . set_visible ( rem )
2009-07-09 22:35:36 +04:00
2011-07-14 21:13:13 +04:00
self . widget ( " hw-panel " ) . set_current_page ( pagetype )
2006-06-14 18:59:40 +04:00
2009-10-21 20:01:53 +04:00
def details_console_changed ( self , src ) :
if self . ignoreDetails :
2009-07-28 17:40:43 +04:00
return
2009-10-21 20:01:53 +04:00
if not src . get_active ( ) :
2009-07-28 17:40:43 +04:00
return
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 18:18:47 +04:00
is_details = ( src == self . widget ( " control-vm-details " ) or
src == self . widget ( " details-menu-view-details " ) )
is_snapshot = ( src == self . widget ( " control-snapshots " ) or
src == self . widget ( " details-menu-view-snapshots " ) )
2009-10-21 20:01:53 +04:00
2011-07-14 21:13:13 +04:00
pages = self . widget ( " details-pages " )
2013-09-02 01:40:38 +04:00
if pages . get_current_page ( ) == DETAILS_PAGE_DETAILS :
2011-07-20 04:29:07 +04:00
if self . has_unapplied_changes ( self . get_hw_row ( ) ) :
self . sync_details_console_view ( True )
return
2012-09-27 21:47:13 +04:00
self . disable_apply ( )
2011-07-20 04:29:07 +04:00
2009-10-21 20:01:53 +04:00
if is_details :
2013-09-02 01:40:38 +04:00
pages . set_current_page ( DETAILS_PAGE_DETAILS )
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 18:18:47 +04:00
elif is_snapshot :
self . snapshots . show_page ( )
2013-09-02 01:40:38 +04:00
pages . set_current_page ( DETAILS_PAGE_SNAPSHOTS )
2009-10-21 20:01:53 +04:00
else :
2013-09-02 01:40:38 +04:00
pages . set_current_page ( DETAILS_PAGE_CONSOLE )
2009-07-28 17:40:43 +04:00
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 18:18:47 +04:00
def sync_details_console_view ( self , newpage ) :
2011-07-14 21:13:13 +04:00
details = self . widget ( " control-vm-details " )
details_menu = self . widget ( " details-menu-view-details " )
console = self . widget ( " control-vm-console " )
console_menu = self . widget ( " details-menu-view-console " )
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 18:18:47 +04:00
snapshot = self . widget ( " control-snapshots " )
snapshot_menu = self . widget ( " details-menu-view-snapshots " )
2013-09-02 01:40:38 +04:00
is_details = newpage == DETAILS_PAGE_DETAILS
is_snapshot = newpage == DETAILS_PAGE_SNAPSHOTS
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 18:18:47 +04:00
is_console = not is_details and not is_snapshot
2009-10-21 20:01:53 +04:00
try :
self . ignoreDetails = True
details . set_active ( is_details )
details_menu . set_active ( is_details )
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 18:18:47 +04:00
snapshot . set_active ( is_snapshot )
snapshot_menu . set_active ( is_snapshot )
console . set_active ( is_console )
console_menu . set_active ( is_console )
2009-10-21 20:01:53 +04:00
finally :
self . ignoreDetails = False
2009-11-04 21:18:14 +03:00
def switch_page ( self , ignore1 = None , ignore2 = None , newpage = None ) :
self . page_refresh ( newpage )
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 18:18:47 +04:00
self . sync_details_console_view ( newpage )
2011-06-01 20:22:05 +04:00
self . console . set_allow_fullscreen ( )
2009-11-04 21:18:14 +03:00
2010-05-12 20:57:32 +04:00
def change_run_text ( self , can_restore ) :
if can_restore :
text = _ ( " _Restore " )
else :
text = _ ( " _Run " )
strip_text = text . replace ( " _ " , " " )
2013-09-22 23:44:58 +04:00
self . widget ( " details-vm-menu " ) . get_submenu ( ) . change_run_text ( text )
2011-07-14 21:13:13 +04:00
self . widget ( " control-run " ) . set_label ( strip_text )
2010-05-12 20:57:32 +04:00
2010-11-30 19:49:47 +03:00
def refresh_vm_state ( self , ignore1 = None , ignore2 = None , ignore3 = None ) :
vm = self . vm
status = self . vm . status ( )
2014-01-07 13:20:44 +04:00
self . widget ( " details-menu-view-toolbar " ) . set_active (
self . config . get_details_show_toolbar ( ) )
2011-07-14 21:13:13 +04:00
self . toggle_toolbar ( self . widget ( " details-menu-view-toolbar " ) )
2009-11-04 21:18:14 +03:00
2013-09-22 23:44:58 +04:00
active = vm . is_active ( )
run = vm . is_runable ( )
stop = vm . is_stoppable ( )
paused = vm . is_paused ( )
ro = vm . is_read_only ( )
2009-11-04 21:18:14 +03:00
2010-05-12 20:57:32 +04:00
if vm . managedsave_supported :
self . change_run_text ( vm . hasSavedImage ( ) )
2011-07-14 21:13:13 +04:00
self . widget ( " control-run " ) . set_sensitive ( run )
self . widget ( " control-shutdown " ) . set_sensitive ( stop )
2013-09-22 21:24:59 +04:00
self . widget ( " control-shutdown " ) . get_menu ( ) . update_widget_states ( vm )
2011-07-14 21:13:13 +04:00
self . widget ( " control-pause " ) . set_sensitive ( stop )
2009-11-04 21:18:14 +03:00
2013-09-22 23:44:58 +04:00
self . widget ( " details-vm-menu " ) . get_submenu ( ) . update_widget_states ( vm )
2011-04-14 20:25:51 +04:00
self . set_pause_state ( paused )
2009-11-04 21:18:14 +03:00
2011-07-14 21:13:13 +04:00
self . widget ( " overview-name " ) . set_editable ( not active )
2011-03-23 23:56:12 +03:00
2011-07-14 21:13:13 +04:00
self . widget ( " config-vcpus " ) . set_sensitive ( not ro )
self . widget ( " config-vcpupin " ) . set_sensitive ( not ro )
self . widget ( " config-memory " ) . set_sensitive ( not ro )
self . widget ( " config-maxmem " ) . set_sensitive ( not ro )
2009-11-04 21:18:14 +03:00
2009-11-29 04:13:55 +03:00
# Disable send key menu entries for offline VM
2012-01-30 06:56:18 +04:00
self . console . send_key_button . set_sensitive ( not ( run or paused ) )
2011-07-14 21:13:13 +04:00
send_key = self . widget ( " details-menu-send-key " )
2009-11-29 04:13:55 +03:00
for c in send_key . get_submenu ( ) . get_children ( ) :
c . set_sensitive ( not ( run or paused ) )
2009-11-04 21:18:14 +03:00
self . console . update_widget_states ( vm , status )
2011-06-21 22:06:11 +04:00
if not run :
self . activate_default_console_page ( )
2009-11-04 21:18:14 +03:00
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 18:18:47 +04:00
self . widget ( " overview-status-text " ) . set_text ( self . vm . run_status ( ) )
2011-07-14 21:13:13 +04:00
self . widget ( " overview-status-icon " ) . set_from_icon_name (
2012-05-14 17:24:56 +04:00
self . vm . run_status_icon_name ( ) , Gtk . IconSize . MENU )
2010-11-30 19:49:47 +03:00
2011-07-14 21:13:13 +04:00
details = self . widget ( " details-pages " )
2010-11-30 19:49:47 +03:00
self . page_refresh ( details . get_current_page ( ) )
2011-01-13 21:55:35 +03:00
self . _refresh_runtime_pinning ( )
2013-10-01 04:33:42 +04:00
errmsg = self . vm . snapshots_supported ( )
cansnap = not bool ( errmsg )
self . widget ( " control-snapshots " ) . set_sensitive ( cansnap )
self . widget ( " details-menu-view-snapshots " ) . set_sensitive ( cansnap )
tooltip = _ ( " Manage VM snapshots " )
if not cansnap :
tooltip + = " \n " + errmsg
self . widget ( " control-snapshots " ) . set_tooltip_text ( tooltip )
2009-11-04 21:18:14 +03:00
#############################
# External action listeners #
#############################
2010-12-09 19:22:35 +03:00
def view_manager ( self , src_ignore ) :
2009-11-04 21:18:14 +03:00
self . emit ( " action-view-manager " )
2010-12-09 19:22:35 +03:00
def exit_app ( self , src_ignore ) :
2009-11-04 21:18:14 +03:00
self . emit ( " action-exit-app " )
2011-06-21 22:06:11 +04:00
def activate_default_console_page ( self ) :
2012-03-02 18:16:03 +04:00
pages = self . widget ( " details-pages " )
2013-09-02 01:40:38 +04:00
if pages . get_current_page ( ) != DETAILS_PAGE_CONSOLE :
2012-03-02 18:16:03 +04:00
return
2013-09-02 01:40:38 +04:00
self . console . activate_default_console_page ( )
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 18:18:47 +04:00
# activate_* are called from engine.py via CLI options
2011-06-21 22:06:11 +04:00
def activate_default_page ( self ) :
2011-07-14 21:13:13 +04:00
pages = self . widget ( " details-pages " )
2013-09-02 01:40:38 +04:00
pages . set_current_page ( DETAILS_PAGE_CONSOLE )
2011-06-21 22:06:11 +04:00
self . activate_default_console_page ( )
2011-06-09 00:33:20 +04:00
def activate_console_page ( self ) :
2011-07-14 21:13:13 +04:00
pages = self . widget ( " details-pages " )
2013-09-02 01:40:38 +04:00
pages . set_current_page ( DETAILS_PAGE_CONSOLE )
2009-11-04 21:18:14 +03:00
def activate_performance_page ( self ) :
2013-09-02 01:40:38 +04:00
self . widget ( " details-pages " ) . set_current_page ( DETAILS_PAGE_DETAILS )
2010-11-24 22:19:44 +03:00
self . set_hw_selection ( HW_LIST_TYPE_STATS )
2009-11-04 21:18:14 +03:00
def activate_config_page ( self ) :
2013-09-02 01:40:38 +04:00
self . widget ( " details-pages " ) . set_current_page ( DETAILS_PAGE_DETAILS )
2009-11-04 21:18:14 +03:00
2010-12-09 19:22:35 +03:00
def add_hardware ( self , src_ignore ) :
2011-03-23 17:06:59 +03:00
try :
if self . addhw is None :
2013-07-25 22:11:09 +04:00
self . addhw = vmmAddHardware ( self . vm , self . is_customize_dialog )
2009-11-04 21:18:14 +03:00
2011-04-14 16:47:42 +04:00
self . addhw . show ( self . topwin )
2011-03-23 17:06:59 +03:00
except Exception , e :
self . err . show_err ( ( _ ( " Error launching hardware dialog: %s " ) %
2011-04-06 19:22:03 +04:00
str ( e ) ) )
2009-11-04 21:18:14 +03:00
2010-12-09 19:22:35 +03:00
def remove_xml_dev ( self , src_ignore ) :
2009-11-04 21:18:14 +03:00
info = self . get_hw_selection ( HW_LIST_COL_DEVICE )
if not info :
return
2010-09-08 02:38:01 +04:00
devtype = info . virtual_device_type
self . remove_device ( devtype , info )
2009-11-04 21:18:14 +03:00
2011-04-14 20:25:51 +04:00
def set_pause_state ( self , paused ) :
# Set pause widget states
try :
self . ignorePause = True
2013-09-22 23:44:58 +04:00
self . widget ( " control-pause " ) . set_property ( " active " , paused )
2011-04-14 20:25:51 +04:00
finally :
self . ignorePause = False
2006-06-14 18:59:40 +04:00
def control_vm_pause ( self , src ) :
2006-06-15 02:42:04 +04:00
if self . ignorePause :
return
2013-06-30 22:33:01 +04:00
# Let state handler listener change things if nec.
2011-04-15 22:49:58 +04:00
self . set_pause_state ( not src . get_active ( ) )
2011-04-14 20:25:51 +04:00
if not self . vm . is_paused ( ) :
2010-12-09 19:22:35 +03:00
self . emit ( " action-suspend-domain " ,
2011-07-23 00:43:26 +04:00
self . vm . conn . get_uri ( ) ,
2010-12-09 19:22:35 +03:00
self . vm . get_uuid ( ) )
2006-06-14 18:59:40 +04:00
else :
2010-12-09 19:22:35 +03:00
self . emit ( " action-resume-domain " ,
2011-07-23 00:43:26 +04:00
self . vm . conn . get_uri ( ) ,
2010-12-09 19:22:35 +03:00
self . vm . get_uuid ( ) )
2007-11-27 19:31:30 +03:00
2013-07-01 22:33:59 +04:00
def control_vm_menu ( self , src_ignore ) :
2013-07-09 03:13:52 +04:00
can_usb = bool ( self . console . viewer and
self . console . viewer . has_usb_redirection ( ) and
self . vm . has_spicevmc_type_redirdev ( ) )
self . widget ( " details-menu-usb-redirection " ) . set_sensitive ( can_usb )
2011-04-14 20:25:51 +04:00
2013-08-01 03:14:17 +04:00
def control_gfx_use_passwd ( self , x ) :
passwd_widget = self . widget ( " gfx-password " )
sensitive = self . widget ( " gfx-use-password " ) . get_active ( )
if not sensitive :
passwd_widget . set_text ( " " )
passwd_widget . set_sensitive ( sensitive )
self . enable_apply ( x , EDIT_GFX_USE_PASSWD )
2010-12-09 19:22:35 +03:00
def control_vm_run ( self , src_ignore ) :
self . emit ( " action-run-domain " ,
2011-07-23 00:43:26 +04:00
self . vm . conn . get_uri ( ) , self . vm . get_uuid ( ) )
2006-06-14 18:59:40 +04:00
2010-12-09 19:22:35 +03:00
def control_vm_shutdown ( self , src_ignore ) :
self . emit ( " action-shutdown-domain " ,
2011-07-23 00:43:26 +04:00
self . vm . conn . get_uri ( ) , self . vm . get_uuid ( ) )
2006-09-01 19:18:49 +04:00
2010-12-09 19:22:35 +03:00
def control_vm_reboot ( self , src_ignore ) :
self . emit ( " action-reboot-domain " ,
2011-07-23 00:43:26 +04:00
self . vm . conn . get_uri ( ) , self . vm . get_uuid ( ) )
2008-04-08 22:30:47 +04:00
2010-12-09 19:22:35 +03:00
def control_vm_save ( self , src_ignore ) :
self . emit ( " action-save-domain " ,
2011-07-23 00:43:26 +04:00
self . vm . conn . get_uri ( ) , self . vm . get_uuid ( ) )
2006-06-14 18:59:40 +04:00
2013-03-17 01:59:32 +04:00
def control_vm_reset ( self , src_ignore ) :
self . emit ( " action-reset-domain " ,
self . vm . conn . get_uri ( ) , self . vm . get_uuid ( ) )
2010-12-09 19:22:35 +03:00
def control_vm_destroy ( self , src_ignore ) :
self . emit ( " action-destroy-domain " ,
2011-07-23 00:43:26 +04:00
self . vm . conn . get_uri ( ) , self . vm . get_uuid ( ) )
2006-11-15 20:27:36 +03:00
2010-12-09 19:22:35 +03:00
def control_vm_clone ( self , src_ignore ) :
self . emit ( " action-clone-domain " ,
2011-07-23 00:43:26 +04:00
self . vm . conn . get_uri ( ) , self . vm . get_uuid ( ) )
2009-07-26 23:54:14 +04:00
2010-12-09 19:22:35 +03:00
def control_vm_migrate ( self , src_ignore ) :
self . emit ( " action-migrate-domain " ,
2011-07-23 00:43:26 +04:00
self . vm . conn . get_uri ( ) , self . vm . get_uuid ( ) )
2008-10-30 23:38:13 +03:00
2013-06-18 00:29:51 +04:00
def control_vm_delete ( self , src_ignore ) :
self . emit ( " action-delete-domain " ,
self . vm . conn . get_uri ( ) , self . vm . get_uuid ( ) )
2013-06-13 04:21:01 +04:00
def control_vm_screenshot ( self , src ) :
ignore = src
try :
return self . _take_screenshot ( )
except Exception , e :
self . err . show_err ( _ ( " Error taking screenshot: %s " ) % str ( e ) )
2013-07-01 22:33:59 +04:00
def control_vm_usb_redirection ( self , src ) :
ignore = src
spice_usbdev_dialog = self . err
spice_usbdev_widget = self . console . viewer . get_usb_widget ( )
if not spice_usbdev_widget :
self . err . show_err ( _ ( " Error initializing spice USB device widget " ) )
return
spice_usbdev_widget . show ( )
spice_usbdev_dialog . show_info ( _ ( " Select USB devices for redirection " ) ,
widget = spice_usbdev_widget )
2013-06-13 04:21:01 +04:00
def _take_screenshot ( self ) :
2011-07-13 20:27:23 +04:00
image = self . console . viewer . get_pixbuf ( )
2013-06-13 04:21:01 +04:00
metadata = {
' tEXt::Hypervisor URI ' : self . vm . conn . get_uri ( ) ,
' tEXt::Domain Name ' : self . vm . get_name ( ) ,
' tEXt::Domain UUID ' : self . vm . get_uuid ( ) ,
' tEXt::Generator App ' : self . config . get_appname ( ) ,
' tEXt::Generator Version ' : self . config . get_appversion ( ) ,
}
ret = image . save_to_bufferv ( ' png ' , metadata . keys ( ) , metadata . values ( ) )
# On Fedora 19, ret is (bool, str)
# Someday the bindings might be fixed to just return the str, try
# and future proof it a bit
if type ( ret ) is tuple and len ( ret ) > = 2 :
ret = ret [ 1 ]
import datetime
now = str ( datetime . datetime . now ( ) ) . split ( " . " ) [ 0 ] . replace ( " " , " _ " )
default = " Screenshot_ %s _ %s .png " % ( self . vm . get_name ( ) , now )
2013-08-09 17:23:01 +04:00
path = uihelpers . browse_local (
2010-12-09 19:22:35 +03:00
self . topwin ,
_ ( " Save Virtual Machine Screenshot " ) ,
2011-07-23 00:43:26 +04:00
self . vm . conn ,
2010-12-10 19:47:07 +03:00
_type = ( " png " , " PNG files " ) ,
2012-05-14 17:24:56 +04:00
dialog_type = Gtk . FileChooserAction . SAVE ,
2013-06-13 04:21:01 +04:00
browse_reason = self . config . CONFIG_DIR_SCREENSHOT ,
default_name = default )
2009-10-30 20:25:27 +03:00
if not path :
2013-06-13 04:21:01 +04:00
logging . debug ( " No screenshot path given, skipping save. " )
2009-10-30 20:25:27 +03:00
return
filename = path
2011-07-13 20:27:23 +04:00
if not filename . endswith ( " .png " ) :
2009-10-30 20:25:27 +03:00
filename + = " .png "
2013-06-13 04:21:01 +04:00
file ( filename , " wb " ) . write ( ret )
2009-10-30 20:25:27 +03:00
2008-08-19 22:25:25 +04:00
2010-02-25 04:37:41 +03:00
############################
# Details/Hardware getters #
############################
def get_config_boot_devs ( self ) :
2011-07-14 21:13:13 +04:00
boot_model = self . widget ( " config-boot-list " ) . get_model ( )
2010-02-25 04:37:41 +03:00
devs = [ ]
for row in boot_model :
if row [ BOOT_ACTIVE ] :
devs . append ( row [ BOOT_DEV_TYPE ] )
return devs
2009-03-01 03:27:20 +03:00
2010-12-17 03:36:07 +03:00
def get_config_cpu_model ( self ) :
2011-07-14 21:13:13 +04:00
cpu_list = self . widget ( " cpu-model " )
2012-05-14 17:24:56 +04:00
model = cpu_list . get_child ( ) . get_text ( )
2010-12-17 03:36:07 +03:00
for row in cpu_list . get_model ( ) :
if model == row [ 0 ] :
return model , row [ 1 ] . vendor
return model , None
2011-03-18 00:41:29 +03:00
def get_config_cpu_features ( self ) :
2011-07-14 21:13:13 +04:00
feature_list = self . widget ( " cpu-features " )
2011-03-18 00:41:29 +03:00
ret = [ ]
for row in feature_list . get_model ( ) :
2011-07-13 22:35:34 +04:00
if row [ 1 ] in [ " off " , " model " ] :
continue
ret . append ( row )
2011-03-18 00:41:29 +03:00
return ret
2009-11-04 21:18:14 +03:00
##############################
# Details/Hardware listeners #
##############################
2011-01-13 21:32:19 +03:00
2010-12-12 07:00:19 +03:00
def _browse_file ( self , callback , is_media = False ) :
if is_media :
2011-07-23 03:12:48 +04:00
reason = self . config . CONFIG_DIR_ISO_MEDIA
2010-12-12 07:00:19 +03:00
else :
reason = self . config . CONFIG_DIR_IMAGE
2012-11-08 17:15:02 +04:00
if self . storage_browser is None :
2010-12-12 07:00:19 +03:00
self . storage_browser = vmmStorageBrowser ( self . conn )
self . storage_browser . set_finish_cb ( callback )
self . storage_browser . set_browse_reason ( reason )
2011-04-14 16:47:42 +04:00
self . storage_browser . show ( self . topwin , self . conn )
2010-12-12 07:00:19 +03:00
2013-08-18 20:25:20 +04:00
def boot_kernel_toggled ( self , src ) :
self . widget ( " boot-kernel-box " ) . set_sensitive ( src . get_active ( ) )
self . enable_apply ( EDIT_KERNEL )
2010-12-12 07:00:19 +03:00
def browse_kernel ( self , src_ignore ) :
def cb ( ignore , path ) :
2011-07-14 21:13:13 +04:00
self . widget ( " boot-kernel " ) . set_text ( path )
2010-12-12 07:00:19 +03:00
self . _browse_file ( cb )
def browse_initrd ( self , src_ignore ) :
def cb ( ignore , path ) :
2013-08-18 20:25:20 +04:00
self . widget ( " boot-initrd " ) . set_text ( path )
self . _browse_file ( cb )
def browse_dtb ( self , src_ignore ) :
def cb ( ignore , path ) :
self . widget ( " boot-dtb " ) . set_text ( path )
2010-12-12 07:00:19 +03:00
self . _browse_file ( cb )
2011-07-15 00:18:42 +04:00
def disable_apply ( self ) :
self . active_edits = [ ]
self . widget ( " config-apply " ) . set_sensitive ( False )
2011-07-19 22:51:16 +04:00
self . widget ( " config-cancel " ) . set_sensitive ( False )
2011-07-15 00:18:42 +04:00
def enable_apply ( self , * arglist ) :
edittype = arglist [ - 1 ]
2011-07-14 21:13:13 +04:00
self . widget ( " config-apply " ) . set_sensitive ( True )
2011-07-19 22:51:16 +04:00
self . widget ( " config-cancel " ) . set_sensitive ( True )
2011-07-15 00:18:42 +04:00
if edittype not in self . active_edits :
self . active_edits . append ( edittype )
2009-11-04 19:09:41 +03:00
2011-03-24 21:33:35 +03:00
# Overview -> Machine settings
def config_acpi_changed ( self , ignore ) :
2011-07-14 21:13:13 +04:00
widget = self . widget ( " overview-acpi " )
2011-03-24 21:33:35 +03:00
incon = widget . get_inconsistent ( )
widget . set_inconsistent ( False )
if incon :
widget . set_active ( True )
2011-07-15 00:18:42 +04:00
self . enable_apply ( EDIT_ACPI )
2011-03-24 21:33:35 +03:00
def config_apic_changed ( self , ignore ) :
2011-07-14 21:13:13 +04:00
widget = self . widget ( " overview-apic " )
2011-03-24 21:33:35 +03:00
incon = widget . get_inconsistent ( )
widget . set_inconsistent ( False )
if incon :
widget . set_active ( True )
2011-07-15 00:18:42 +04:00
self . enable_apply ( EDIT_APIC )
2011-03-24 21:33:35 +03:00
2009-11-04 21:18:14 +03:00
# Overview -> Security
2010-12-09 19:22:35 +03:00
def security_type_changed ( self , button ) :
2011-07-15 00:18:42 +04:00
self . enable_apply ( EDIT_SECURITY )
2011-07-14 21:36:17 +04:00
self . widget ( " security-label " ) . set_sensitive ( not button . get_active ( ) )
2013-02-05 15:28:06 +04:00
self . widget ( " security-relabel " ) . set_sensitive ( not button . get_active ( ) )
2009-07-09 22:35:44 +04:00
2009-11-04 21:18:14 +03:00
# Memory
def config_get_maxmem ( self ) :
2011-07-19 22:02:39 +04:00
return uihelpers . spin_get_helper ( self . widget ( " config-maxmem " ) )
2009-11-04 21:18:14 +03:00
def config_get_memory ( self ) :
2011-07-19 22:02:39 +04:00
return uihelpers . spin_get_helper ( self . widget ( " config-memory " ) )
2009-05-12 21:09:08 +04:00
2010-12-09 19:22:35 +03:00
def config_maxmem_changed ( self , src_ignore ) :
2011-07-15 00:18:42 +04:00
self . enable_apply ( EDIT_MEM )
2009-11-04 21:16:38 +03:00
2010-12-09 19:22:35 +03:00
def config_memory_changed ( self , src_ignore ) :
2011-07-15 00:18:42 +04:00
self . enable_apply ( EDIT_MEM )
2009-11-04 21:16:38 +03:00
2013-04-17 02:37:00 +04:00
maxadj = self . widget ( " config-maxmem " )
2009-11-04 21:16:38 +03:00
2009-11-04 21:18:14 +03:00
mem = self . config_get_memory ( )
2013-04-17 02:37:00 +04:00
if maxadj . get_value ( ) < mem :
maxadj . set_value ( mem )
2013-04-17 03:22:59 +04:00
ignore , upper = maxadj . get_range ( )
2013-04-17 02:37:00 +04:00
maxadj . set_range ( mem , upper )
2009-11-04 21:16:38 +03:00
2010-06-21 21:32:59 +04:00
def generate_cpuset ( self ) :
2013-07-14 07:07:01 +04:00
mem = int ( self . vm . get_memory ( ) ) / 1024
2013-08-09 23:05:37 +04:00
return virtinst . DomainNumatune . generate_cpuset ( self . conn . get_backend ( ) ,
mem )
2010-06-21 21:32:59 +04:00
2010-05-13 20:55:08 +04:00
# VCPUS
2011-01-13 21:32:19 +03:00
def config_get_vcpus ( self ) :
2011-07-19 22:02:39 +04:00
return uihelpers . spin_get_helper ( self . widget ( " config-vcpus " ) )
2011-01-13 21:32:19 +03:00
def config_get_maxvcpus ( self ) :
2011-07-19 22:02:39 +04:00
return uihelpers . spin_get_helper ( self . widget ( " config-maxvcpus " ) )
2011-01-13 21:32:19 +03:00
2010-06-21 21:32:59 +04:00
def config_vcpupin_generate ( self , ignore ) :
try :
pinstr = self . generate_cpuset ( )
except Exception , e :
return self . err . val_err (
2011-08-30 22:50:50 +04:00
_ ( " Error generating CPU configuration " ) , e )
2010-06-21 21:32:59 +04:00
2011-07-14 21:13:13 +04:00
self . widget ( " config-vcpupin " ) . set_text ( " " )
self . widget ( " config-vcpupin " ) . set_text ( pinstr )
2010-06-21 21:32:59 +04:00
2010-05-13 20:55:08 +04:00
def config_vcpus_changed ( self , ignore ) :
2011-07-15 00:18:42 +04:00
self . enable_apply ( EDIT_VCPUS )
2011-01-13 21:32:19 +03:00
2011-07-23 00:43:26 +04:00
conn = self . vm . conn
2010-05-13 20:55:08 +04:00
host_active_count = conn . host_active_processor_count ( )
2011-01-13 21:32:19 +03:00
cur = self . config_get_vcpus ( )
2010-05-13 20:55:08 +04:00
# Warn about overcommit
2011-01-13 21:32:19 +03:00
warn = bool ( cur > host_active_count )
2013-09-02 04:18:14 +04:00
self . widget ( " config-vcpus-warn-box " ) . set_visible ( warn )
2010-05-13 20:55:08 +04:00
2013-04-17 02:37:00 +04:00
maxadj = self . widget ( " config-maxvcpus " )
2011-01-13 21:32:19 +03:00
maxval = self . config_get_maxvcpus ( )
if maxval < cur :
2013-04-17 02:37:00 +04:00
maxadj . set_value ( cur )
2013-04-17 03:22:59 +04:00
ignore , upper = maxadj . get_range ( )
2013-04-17 02:37:00 +04:00
maxadj . set_range ( cur , upper )
2011-01-13 21:32:19 +03:00
def config_maxvcpus_changed ( self , ignore ) :
2011-07-15 00:18:42 +04:00
self . enable_apply ( EDIT_VCPUS )
2010-05-13 20:55:08 +04:00
2013-04-26 23:58:18 +04:00
def config_cpu_copy_host ( self , src_ignore ) :
# Update UI with output copied from host
try :
2013-07-05 16:59:58 +04:00
CPU = virtinst . CPU ( self . vm . conn . get_backend ( ) )
2013-04-26 23:58:18 +04:00
CPU . copy_host_cpu ( )
self . _refresh_cpu_config ( CPU )
self . _cpu_copy_host = True
except Exception , e :
self . err . show_err ( _ ( " Error copying host CPU: %s " ) % str ( e ) )
return
2010-12-17 00:05:55 +03:00
2013-12-03 06:46:47 +04:00
def config_cpu_clear ( self , src_ignore ) :
try :
CPU = virtinst . CPU ( self . vm . conn . get_backend ( ) )
CPU . clear ( )
self . _refresh_cpu_config ( CPU )
except Exception , e :
self . err . show_err ( _ ( " Error clear CPU config: %s " ) % str ( e ) )
return
2010-12-17 00:05:55 +03:00
def config_cpu_topology_enable ( self , src ) :
do_enable = src . get_active ( )
2011-07-14 21:13:13 +04:00
self . widget ( " cpu-topology-table " ) . set_sensitive ( do_enable )
2011-07-15 00:18:42 +04:00
self . enable_apply ( EDIT_TOPOLOGY )
2010-12-17 00:05:55 +03:00
2009-11-04 21:18:14 +03:00
# Boot device / Autostart
2010-02-25 04:37:41 +03:00
def config_bootdev_selected ( self , ignore ) :
boot_row = self . get_boot_selection ( )
boot_selection = boot_row and boot_row [ BOOT_DEV_TYPE ]
boot_devs = self . get_config_boot_devs ( )
2011-07-14 21:13:13 +04:00
up_widget = self . widget ( " config-boot-moveup " )
down_widget = self . widget ( " config-boot-movedown " )
2010-02-25 04:37:41 +03:00
down_widget . set_sensitive ( bool ( boot_devs and
boot_selection and
boot_selection in boot_devs and
boot_selection != boot_devs [ - 1 ] ) )
up_widget . set_sensitive ( bool ( boot_devs and boot_selection and
boot_selection in boot_devs and
boot_selection != boot_devs [ 0 ] ) )
def config_boot_toggled ( self , ignore , index ) :
2011-07-14 21:13:13 +04:00
boot_model = self . widget ( " config-boot-list " ) . get_model ( )
2010-02-25 04:37:41 +03:00
boot_row = boot_model [ index ]
is_active = boot_row [ BOOT_ACTIVE ]
boot_row [ BOOT_ACTIVE ] = not is_active
self . repopulate_boot_list ( self . get_config_boot_devs ( ) ,
boot_row [ BOOT_DEV_TYPE ] )
2011-07-15 00:18:42 +04:00
self . enable_apply ( EDIT_BOOTORDER )
2010-02-25 04:37:41 +03:00
2012-11-08 17:15:02 +04:00
def config_boot_move ( self , src , move_up ) :
ignore = src
2010-02-25 04:37:41 +03:00
boot_row = self . get_boot_selection ( )
if not boot_row :
return
boot_selection = boot_row [ BOOT_DEV_TYPE ]
boot_devs = self . get_config_boot_devs ( )
boot_idx = boot_devs . index ( boot_selection )
if move_up :
new_idx = boot_idx - 1
else :
new_idx = boot_idx + 1
if new_idx < 0 or new_idx > = len ( boot_devs ) :
# Somehow we got out of bounds
return
swap_dev = boot_devs [ new_idx ]
boot_devs [ new_idx ] = boot_selection
boot_devs [ boot_idx ] = swap_dev
self . repopulate_boot_list ( boot_devs , boot_selection )
2011-07-15 00:18:42 +04:00
self . enable_apply ( EDIT_BOOTORDER )
2009-07-07 20:16:03 +04:00
2013-02-17 17:40:37 +04:00
# IO Tuning
def iotune_changed ( self , ignore ) :
2013-04-17 02:18:03 +04:00
iotune_rbs = int ( self . get_text ( " disk-iotune-rbs " ) or 0 )
iotune_ris = int ( self . get_text ( " disk-iotune-ris " ) or 0 )
iotune_tbs = int ( self . get_text ( " disk-iotune-tbs " ) or 0 )
iotune_tis = int ( self . get_text ( " disk-iotune-tis " ) or 0 )
iotune_wbs = int ( self . get_text ( " disk-iotune-wbs " ) or 0 )
iotune_wis = int ( self . get_text ( " disk-iotune-wis " ) or 0 )
2013-02-17 17:40:37 +04:00
# libvirt doesn't support having read/write settings along side total
# settings, so disable the widgets accordingly.
2013-04-17 02:18:03 +04:00
have_rw_bytes = ( iotune_rbs > 0 or
iotune_wbs > 0 )
have_t_bytes = ( not have_rw_bytes and iotune_tbs > 0 )
self . widget ( " disk-iotune-rbs " ) . set_sensitive ( have_rw_bytes or not
have_t_bytes )
self . widget ( " disk-iotune-wbs " ) . set_sensitive ( have_rw_bytes or not
have_t_bytes )
self . widget ( " disk-iotune-tbs " ) . set_sensitive ( have_t_bytes or not
have_rw_bytes )
if have_rw_bytes :
2013-04-17 02:37:00 +04:00
self . widget ( " disk-iotune-tbs " ) . set_value ( 0 )
2013-04-17 02:18:03 +04:00
elif have_t_bytes :
2013-04-17 02:37:00 +04:00
self . widget ( " disk-iotune-rbs " ) . set_value ( 0 )
self . widget ( " disk-iotune-wbs " ) . set_value ( 0 )
2013-04-17 02:18:03 +04:00
have_rw_iops = ( iotune_ris > 0 or iotune_wis > 0 )
have_t_iops = ( not have_rw_iops and iotune_tis > 0 )
self . widget ( " disk-iotune-ris " ) . set_sensitive ( have_rw_iops or not
have_t_iops )
self . widget ( " disk-iotune-wis " ) . set_sensitive ( have_rw_iops or not
have_t_iops )
self . widget ( " disk-iotune-tis " ) . set_sensitive ( have_t_iops or not
have_rw_iops )
if have_rw_iops :
2013-04-17 02:37:00 +04:00
self . widget ( " disk-iotune-tis " ) . set_value ( 0 )
2013-04-17 02:18:03 +04:00
elif have_t_iops :
2013-04-17 02:37:00 +04:00
self . widget ( " disk-iotune-ris " ) . set_value ( 0 )
self . widget ( " disk-iotune-wis " ) . set_value ( 0 )
2013-02-17 17:40:37 +04:00
self . enable_apply ( EDIT_DISK_IOTUNE )
2013-04-17 02:18:03 +04:00
2009-11-04 00:15:18 +03:00
# CDROM Eject/Connect
2010-12-09 19:22:35 +03:00
def toggle_storage_media ( self , src_ignore ) :
2010-09-03 22:10:04 +04:00
disk = self . get_hw_selection ( HW_LIST_COL_DEVICE )
if not disk :
2009-11-04 00:15:18 +03:00
return
2010-09-08 02:38:01 +04:00
dev_id_info = disk
2010-09-03 22:10:04 +04:00
curpath = disk . path
devtype = disk . device
2009-12-11 03:18:24 +03:00
2011-08-30 22:29:51 +04:00
try :
if curpath :
# Disconnect cdrom
self . change_storage_media ( dev_id_info , None )
return
except Exception , e :
self . err . show_err ( ( _ ( " Error disconnecting media: %s " ) % e ) )
2010-09-09 01:53:51 +04:00
return
2009-11-04 00:15:18 +03:00
2011-08-30 22:29:51 +04:00
try :
def change_cdrom_wrapper ( src_ignore , dev_id_info , newpath ) :
return self . change_storage_media ( dev_id_info , newpath )
2009-11-04 00:15:18 +03:00
2011-08-30 22:29:51 +04:00
# Launch 'Choose CD' dialog
if self . media_choosers [ devtype ] is None :
ret = vmmChooseCD ( self . vm , dev_id_info )
2009-12-14 22:52:52 +03:00
2011-08-30 22:29:51 +04:00
ret . connect ( " cdrom-chosen " , change_cdrom_wrapper )
self . media_choosers [ devtype ] = ret
2009-12-14 22:52:52 +03:00
2011-08-30 22:29:51 +04:00
dialog = self . media_choosers [ devtype ]
dialog . dev_id_info = dev_id_info
dialog . show ( self . topwin )
except Exception , e :
self . err . show_err ( ( _ ( " Error launching media dialog: %s " ) % e ) )
return
2009-07-07 20:16:03 +04:00
2009-11-04 21:18:14 +03:00
##################################################
# Details/Hardware config changes (apply button) #
##################################################
2009-07-07 20:16:03 +04:00
2011-07-20 04:29:07 +04:00
def config_cancel ( self , ignore = None ) :
2011-07-19 22:51:16 +04:00
# Remove current changes and deactive 'apply' button
self . hw_selected ( )
2011-07-20 04:29:07 +04:00
def config_apply ( self , ignore = None , row = None ) :
pagetype = None
devobj = None
if not row :
row = self . get_hw_row ( )
if row :
pagetype = row [ HW_LIST_COL_TYPE ]
devobj = row [ HW_LIST_COL_DEVICE ]
2010-09-08 02:38:01 +04:00
key = devobj
2009-11-04 21:18:14 +03:00
ret = False
2011-06-01 19:17:19 +04:00
try :
if pagetype is HW_LIST_TYPE_GENERAL :
ret = self . config_overview_apply ( )
elif pagetype is HW_LIST_TYPE_CPU :
ret = self . config_vcpus_apply ( )
elif pagetype is HW_LIST_TYPE_MEMORY :
ret = self . config_memory_apply ( )
elif pagetype is HW_LIST_TYPE_BOOT :
ret = self . config_boot_options_apply ( )
elif pagetype is HW_LIST_TYPE_DISK :
ret = self . config_disk_apply ( key )
elif pagetype is HW_LIST_TYPE_NIC :
ret = self . config_network_apply ( key )
elif pagetype is HW_LIST_TYPE_GRAPHICS :
ret = self . config_graphics_apply ( key )
elif pagetype is HW_LIST_TYPE_SOUND :
ret = self . config_sound_apply ( key )
elif pagetype is HW_LIST_TYPE_VIDEO :
ret = self . config_video_apply ( key )
elif pagetype is HW_LIST_TYPE_WATCHDOG :
ret = self . config_watchdog_apply ( key )
2011-06-23 19:42:03 +04:00
elif pagetype is HW_LIST_TYPE_SMARTCARD :
ret = self . config_smartcard_apply ( key )
2011-09-23 19:14:15 +04:00
elif pagetype is HW_LIST_TYPE_CONTROLLER :
ret = self . config_controller_apply ( key )
2011-06-01 19:17:19 +04:00
else :
ret = False
except Exception , e :
2011-07-20 04:29:07 +04:00
return self . err . show_err ( _ ( " Error apply changes: %s " ) % e )
2009-07-07 20:16:03 +04:00
2009-11-04 21:18:14 +03:00
if ret is not False :
2011-07-15 00:18:42 +04:00
self . disable_apply ( )
2011-07-20 04:29:07 +04:00
return True
2009-07-07 20:16:03 +04:00
2013-08-18 20:25:20 +04:00
def get_text ( self , widgetname , strip = True , checksens = False ) :
widget = self . widget ( widgetname )
if ( checksens and
( not widget . is_sensitive ( ) or not widget . is_visible ( ) ) ) :
return " "
ret = widget . get_text ( )
2011-07-14 19:45:17 +04:00
if strip :
ret = ret . strip ( )
return ret
2013-08-18 19:11:15 +04:00
def edited ( self , pagetype ) :
2011-07-15 00:18:42 +04:00
return pagetype in self . active_edits
def make_apply_data ( self ) :
definefuncs = [ ]
defineargs = [ ]
hotplugfuncs = [ ]
hotplugargs = [ ]
def add_define ( func , * args ) :
definefuncs . append ( func )
defineargs . append ( args )
def add_hotplug ( func , * args ) :
hotplugfuncs . append ( func )
hotplugargs . append ( args )
return ( definefuncs , defineargs , add_define ,
hotplugfuncs , hotplugargs , add_hotplug )
2009-11-04 19:09:41 +03:00
# Overview section
def config_overview_apply ( self ) :
2011-07-15 00:18:42 +04:00
df , da , add_define , hf , ha , add_hotplug = self . make_apply_data ( )
ignore = add_hotplug
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_NAME ) :
2011-07-15 00:18:42 +04:00
name = self . widget ( " overview-name " ) . get_text ( )
add_define ( self . vm . define_name , name )
2013-09-24 15:02:27 +04:00
if self . edited ( EDIT_TITLE ) :
title = self . widget ( " overview-title " ) . get_text ( )
add_define ( self . vm . define_title , title )
add_hotplug ( self . vm . hotplug_title , title )
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_ACPI ) :
2011-07-15 00:18:42 +04:00
enable_acpi = self . widget ( " overview-acpi " ) . get_active ( )
if self . widget ( " overview-acpi " ) . get_inconsistent ( ) :
enable_acpi = None
add_define ( self . vm . define_acpi , enable_acpi )
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_APIC ) :
2011-07-15 00:18:42 +04:00
enable_apic = self . widget ( " overview-apic " ) . get_active ( )
if self . widget ( " overview-apic " ) . get_inconsistent ( ) :
enable_apic = None
add_define ( self . vm . define_apic , enable_apic )
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_CLOCK ) :
2013-09-28 20:21:35 +04:00
clock = self . get_combo_entry ( " overview-clock " )
2011-07-15 00:18:42 +04:00
add_define ( self . vm . define_clock , clock )
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_MACHTYPE ) :
2013-09-28 20:21:35 +04:00
machtype = self . get_combo_entry ( " machine-type " )
2012-01-05 13:35:40 +04:00
add_define ( self . vm . define_machtype , machtype )
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_SECURITY ) :
2011-07-15 00:18:42 +04:00
semodel = None
setype = " static "
selabel = self . get_text ( " security-label " )
2013-02-05 15:28:06 +04:00
relabel = self . widget ( " security-relabel " ) . get_active ( )
2011-07-15 00:18:42 +04:00
if self . widget ( " security-dynamic " ) . get_active ( ) :
setype = " dynamic "
2013-02-05 15:28:06 +04:00
relabel = True
2012-11-09 15:13:22 +04:00
if self . widget ( " security-type-box " ) . get_sensitive ( ) :
2011-07-15 00:18:42 +04:00
semodel = self . get_text ( " security-model " )
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 18:18:47 +04:00
add_define ( self . vm . define_seclabel ,
semodel , setype , selabel , relabel )
2011-07-15 00:18:42 +04:00
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_DESC ) :
2011-07-15 00:18:42 +04:00
desc_widget = self . widget ( " overview-description " )
desc = desc_widget . get_buffer ( ) . get_property ( " text " ) or " "
add_define ( self . vm . define_description , desc )
2012-10-17 01:26:06 +04:00
add_hotplug ( self . vm . hotplug_description , desc )
2012-10-14 22:55:24 +04:00
2011-07-15 00:18:42 +04:00
return self . _change_config_helper ( df , da , hf , ha )
2009-07-27 00:09:46 +04:00
2009-11-04 21:18:14 +03:00
# CPUs
def config_vcpus_apply ( self ) :
2011-07-15 00:18:42 +04:00
df , da , add_define , hf , ha , add_hotplug = self . make_apply_data ( )
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_VCPUS ) :
2011-07-15 00:18:42 +04:00
vcpus = self . config_get_vcpus ( )
maxv = self . config_get_maxvcpus ( )
add_define ( self . vm . define_vcpus , vcpus , maxv )
add_hotplug ( self . vm . hotplug_vcpus , vcpus )
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_CPUSET ) :
2011-07-15 00:18:42 +04:00
cpuset = self . get_text ( " config-vcpupin " )
print cpuset
add_define ( self . vm . define_cpuset , cpuset )
add_hotplug ( self . config_vcpu_pin_cpuset , cpuset )
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_CPU ) :
2011-07-15 00:18:42 +04:00
model , vendor = self . get_config_cpu_model ( )
features = self . get_config_cpu_features ( )
add_define ( self . vm . define_cpu ,
2013-04-26 23:58:18 +04:00
model , vendor , self . _cpu_copy_host , features )
2011-07-15 00:18:42 +04:00
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_TOPOLOGY ) :
2011-07-15 00:18:42 +04:00
do_top = self . widget ( " cpu-topology-enable " ) . get_active ( )
sockets = self . widget ( " cpu-sockets " ) . get_value ( )
cores = self . widget ( " cpu-cores " ) . get_value ( )
threads = self . widget ( " cpu-threads " ) . get_value ( )
if not do_top :
sockets = None
cores = None
threads = None
add_define ( self . vm . define_cpu_topology , sockets , cores , threads )
ret = self . _change_config_helper ( df , da , hf , ha )
2013-04-26 23:58:18 +04:00
if ret :
self . _cpu_copy_host = False
2011-07-15 00:18:42 +04:00
return ret
2006-06-14 18:59:40 +04:00
2010-12-09 19:22:35 +03:00
def config_vcpu_pin ( self , src_ignore , path , new_text ) :
2011-07-14 21:13:13 +04:00
vcpu_list = self . widget ( " config-vcpu-list " )
2009-11-16 19:36:13 +03:00
vcpu_model = vcpu_list . get_model ( )
row = vcpu_model [ path ]
2011-07-23 00:43:26 +04:00
conn = self . vm . conn
2009-11-16 19:36:13 +03:00
try :
2011-07-14 19:45:17 +04:00
new_text = new_text . strip ( )
2009-11-16 19:36:13 +03:00
vcpu_num = int ( row [ 0 ] )
2013-08-09 23:05:37 +04:00
pinlist = virtinst . DomainNumatune . cpuset_str_to_tuple (
2013-07-05 16:59:58 +04:00
conn . get_backend ( ) , new_text )
2009-11-16 19:36:13 +03:00
except Exception , e :
2011-08-30 22:50:50 +04:00
self . err . val_err ( _ ( " Error building pin list " ) , e )
2009-11-16 19:36:13 +03:00
return
try :
self . vm . pin_vcpu ( vcpu_num , pinlist )
except Exception , e :
2011-08-30 22:50:50 +04:00
self . err . show_err ( _ ( " Error pinning vcpus " ) , e )
2009-11-16 19:36:13 +03:00
return
2011-01-13 21:55:35 +03:00
self . _refresh_runtime_pinning ( )
2009-11-16 19:36:13 +03:00
2011-01-13 22:23:34 +03:00
def config_vcpu_pin_cpuset ( self , cpuset ) :
2011-07-23 00:43:26 +04:00
conn = self . vm . conn
2011-07-14 21:13:13 +04:00
vcpu_list = self . widget ( " config-vcpu-list " )
2011-01-13 22:23:34 +03:00
vcpu_model = vcpu_list . get_model ( )
if self . vm . vcpu_pinning ( ) == cpuset :
return
2013-08-09 23:05:37 +04:00
pinlist = virtinst . DomainNumatune . cpuset_str_to_tuple (
2013-07-05 16:59:58 +04:00
conn . get_backend ( ) , cpuset )
2011-01-13 22:23:34 +03:00
for row in vcpu_model :
vcpu_num = row [ 0 ]
self . vm . pin_vcpu ( int ( vcpu_num ) , pinlist )
2009-11-16 19:36:13 +03:00
2009-11-04 21:18:14 +03:00
# Memory
def config_memory_apply ( self ) :
2011-07-15 00:18:42 +04:00
df , da , add_define , hf , ha , add_hotplug = self . make_apply_data ( )
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_MEM ) :
2011-07-15 00:18:42 +04:00
curmem = None
maxmem = self . config_get_maxmem ( )
2012-11-09 15:13:22 +04:00
if self . widget ( " config-memory " ) . get_sensitive ( ) :
2011-07-15 00:18:42 +04:00
curmem = self . config_get_memory ( )
if curmem :
curmem = int ( curmem ) * 1024
if maxmem :
maxmem = int ( maxmem ) * 1024
2009-11-04 21:18:14 +03:00
2011-07-15 00:18:42 +04:00
add_define ( self . vm . define_both_mem , curmem , maxmem )
add_hotplug ( self . vm . hotplug_both_mem , curmem , maxmem )
2009-11-04 21:18:14 +03:00
2011-07-15 00:18:42 +04:00
return self . _change_config_helper ( df , da , hf , ha )
2009-11-04 21:18:14 +03:00
# Boot device / Autostart
def config_boot_options_apply ( self ) :
2011-07-15 00:18:42 +04:00
df , da , add_define , hf , ha , add_hotplug = self . make_apply_data ( )
ignore = add_hotplug
2009-11-04 21:23:22 +03:00
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_AUTOSTART ) :
2011-07-15 00:18:42 +04:00
auto = self . widget ( " config-autostart " )
2009-11-04 21:18:14 +03:00
try :
self . vm . set_autostart ( auto . get_active ( ) )
except Exception , e :
2011-07-15 00:18:42 +04:00
self . err . show_err (
( _ ( " Error changing autostart value: %s " ) % str ( e ) ) )
2009-11-04 21:18:14 +03:00
return False
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_BOOTORDER ) :
2011-07-15 00:18:42 +04:00
bootdevs = self . get_config_boot_devs ( )
add_define ( self . vm . set_boot_device , bootdevs )
2010-12-12 07:00:19 +03:00
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_BOOTMENU ) :
2011-07-15 00:18:42 +04:00
bootmenu = self . widget ( " boot-menu " ) . get_active ( )
add_define ( self . vm . set_boot_menu , bootmenu )
2010-12-12 07:00:19 +03:00
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_KERNEL ) :
2013-08-18 20:25:20 +04:00
kernel = self . get_text ( " boot-kernel " , checksens = True )
initrd = self . get_text ( " boot-initrd " , checksens = True )
dtb = self . get_text ( " boot-dtb " , checksens = True )
args = self . get_text ( " boot-kernel-args " , checksens = True )
2011-07-15 00:31:38 +04:00
if initrd and not kernel :
return self . err . val_err (
_ ( " Cannot set initrd without specifying a kernel path " ) )
if args and not kernel :
return self . err . val_err (
_ ( " Cannot set kernel arguments without specifying a kernel path " ) )
2013-08-18 20:25:20 +04:00
add_define ( self . vm . set_boot_kernel , kernel , initrd , dtb , args )
2011-05-26 20:38:48 +04:00
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_INIT ) :
2011-07-14 19:45:17 +04:00
init = self . get_text ( " boot-init-path " )
2011-05-26 20:38:48 +04:00
if not init :
return self . err . val_err ( _ ( " An init path must be specified " ) )
2011-07-15 00:18:42 +04:00
add_define ( self . vm . set_boot_init , init )
2011-05-26 20:38:48 +04:00
2011-07-15 00:18:42 +04:00
return self . _change_config_helper ( df , da , hf , ha )
2009-11-04 21:23:22 +03:00
2009-11-04 21:18:14 +03:00
# CDROM
2010-09-09 01:53:51 +04:00
def change_storage_media ( self , dev_id_info , newpath ) :
2009-12-11 03:18:24 +03:00
return self . _change_config_helper ( self . vm . define_storage_media ,
2010-09-09 01:53:51 +04:00
( dev_id_info , newpath ) ,
2009-12-11 03:18:24 +03:00
self . vm . hotplug_storage_media ,
2010-09-09 01:53:51 +04:00
( dev_id_info , newpath ) )
2009-11-04 21:18:14 +03:00
2009-11-05 00:30:51 +03:00
# Disk options
def config_disk_apply ( self , dev_id_info ) :
2011-07-15 00:18:42 +04:00
df , da , add_define , hf , ha , add_hotplug = self . make_apply_data ( )
ignore = add_hotplug
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_DISK_RO ) :
2011-07-15 00:18:42 +04:00
do_readonly = self . widget ( " disk-readonly " ) . get_active ( )
add_define ( self . vm . define_disk_readonly , dev_id_info , do_readonly )
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_DISK_SHARE ) :
2011-07-15 00:18:42 +04:00
do_shareable = self . widget ( " disk-shareable " ) . get_active ( )
add_define ( self . vm . define_disk_shareable ,
dev_id_info , do_shareable )
2013-10-04 05:39:01 +04:00
if self . edited ( EDIT_DISK_REMOVABLE ) :
do_removable = bool ( self . widget ( " disk-removable " ) . get_active ( ) )
add_define ( self . vm . define_disk_removable , dev_id_info , do_removable )
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_DISK_CACHE ) :
2013-09-28 20:21:35 +04:00
cache = self . get_combo_entry ( " disk-cache " )
2011-07-15 00:18:42 +04:00
add_define ( self . vm . define_disk_cache , dev_id_info , cache )
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_DISK_IO ) :
2013-09-28 20:21:35 +04:00
io = self . get_combo_entry ( " disk-io " )
2011-07-24 04:41:35 +04:00
add_define ( self . vm . define_disk_io , dev_id_info , io )
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_DISK_FORMAT ) :
2013-09-28 20:21:35 +04:00
fmt = self . get_combo_entry ( " disk-format " )
2011-07-15 00:18:42 +04:00
add_define ( self . vm . define_disk_driver_type , dev_id_info , fmt )
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_DISK_SERIAL ) :
2011-07-15 00:18:42 +04:00
serial = self . get_text ( " disk-serial " )
add_define ( self . vm . define_disk_serial , dev_id_info , serial )
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_DISK_IOTUNE ) :
2013-04-17 02:37:00 +04:00
iotune_rbs = int ( self . widget ( " disk-iotune-rbs " ) . get_value ( ) * 1024 )
iotune_ris = int ( self . widget ( " disk-iotune-ris " ) . get_value ( ) )
iotune_tbs = int ( self . widget ( " disk-iotune-tbs " ) . get_value ( ) * 1024 )
iotune_tis = int ( self . widget ( " disk-iotune-tis " ) . get_value ( ) )
iotune_wbs = int ( self . widget ( " disk-iotune-wbs " ) . get_value ( ) * 1024 )
iotune_wis = int ( self . widget ( " disk-iotune-wis " ) . get_value ( ) )
2013-04-17 02:18:03 +04:00
add_define ( self . vm . define_disk_iotune_rbs , dev_id_info , iotune_rbs )
add_define ( self . vm . define_disk_iotune_ris , dev_id_info , iotune_ris )
add_define ( self . vm . define_disk_iotune_tbs , dev_id_info , iotune_tbs )
add_define ( self . vm . define_disk_iotune_tis , dev_id_info , iotune_tis )
add_define ( self . vm . define_disk_iotune_wbs , dev_id_info , iotune_wbs )
add_define ( self . vm . define_disk_iotune_wis , dev_id_info , iotune_wis )
2013-02-17 17:40:37 +04:00
2011-07-15 00:18:42 +04:00
# Do this last since it can change uniqueness info of the dev
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_DISK_BUS ) :
2013-09-28 20:21:35 +04:00
bus = self . get_combo_entry ( " disk-bus " )
2012-02-29 12:48:18 +04:00
addr = None
if bus == " spapr-vscsi " :
bus = " scsi "
addr = " spapr-vio "
add_define ( self . vm . define_disk_bus , dev_id_info , bus , addr )
2011-07-15 00:18:42 +04:00
return self . _change_config_helper ( df , da , hf , ha )
2009-11-05 00:30:51 +03:00
2010-03-24 05:15:53 +03:00
# Audio options
def config_sound_apply ( self , dev_id_info ) :
2011-07-15 00:18:42 +04:00
df , da , add_define , hf , ha , add_hotplug = self . make_apply_data ( )
ignore = add_hotplug
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_SOUND_MODEL ) :
2013-09-28 20:21:35 +04:00
model = self . get_combo_entry ( " sound-model " )
2011-07-15 00:18:42 +04:00
if model :
add_define ( self . vm . define_sound_model , dev_id_info , model )
return self . _change_config_helper ( df , da , hf , ha )
2009-11-05 00:30:51 +03:00
2011-06-23 19:42:03 +04:00
# Smartcard options
def config_smartcard_apply ( self , dev_id_info ) :
2011-07-15 00:18:42 +04:00
df , da , add_define , hf , ha , add_hotplug = self . make_apply_data ( )
ignore = add_hotplug
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_SMARTCARD_MODE ) :
2013-09-28 20:21:35 +04:00
model = self . get_combo_entry ( " smartcard-mode " )
2011-07-15 00:18:42 +04:00
if model :
add_define ( self . vm . define_smartcard_mode , dev_id_info , model )
return self . _change_config_helper ( df , da , hf , ha )
2011-06-23 19:42:03 +04:00
2010-03-24 05:15:53 +03:00
# Network options
def config_network_apply ( self , dev_id_info ) :
2011-07-15 00:18:42 +04:00
df , da , add_define , hf , ha , add_hotplug = self . make_apply_data ( )
ignore = add_hotplug
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_NET_MODEL ) :
2013-09-28 20:21:35 +04:00
model = self . get_combo_entry ( " network-model " )
2012-03-05 12:10:15 +04:00
addr = None
if model == " spapr-vlan " :
addr = " spapr-vio "
add_define ( self . vm . define_network_model , dev_id_info , model , addr )
2011-07-15 00:18:42 +04:00
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_NET_SOURCE ) :
2011-07-15 00:18:42 +04:00
mode = None
2013-09-28 20:21:35 +04:00
net_list = self . widget ( " network-source " )
2011-07-15 00:18:42 +04:00
net_bridge = self . widget ( " network-bridge " )
nettype , source = uihelpers . get_network_selection ( net_list ,
net_bridge )
if nettype == " direct " :
2013-09-28 20:21:35 +04:00
mode = self . get_combo_entry ( " network-source-mode " )
2011-07-15 00:18:42 +04:00
add_define ( self . vm . define_network_source , dev_id_info ,
nettype , source , mode )
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_NET_VPORT ) :
2011-07-15 00:18:42 +04:00
vport_type = self . get_text ( " vport-type " )
vport_managerid = self . get_text ( " vport-managerid " )
vport_typeid = self . get_text ( " vport-typeid " )
vport_idver = self . get_text ( " vport-typeidversion " )
vport_instid = self . get_text ( " vport-instanceid " )
add_define ( self . vm . define_virtualport , dev_id_info ,
vport_type , vport_managerid , vport_typeid ,
vport_idver , vport_instid )
return self . _change_config_helper ( df , da , hf , ha )
2009-11-05 22:59:11 +03:00
2010-12-12 04:54:48 +03:00
# Graphics options
def config_graphics_apply ( self , dev_id_info ) :
2011-07-15 00:18:42 +04:00
df , da , add_define , hf , ha , add_hotplug = self . make_apply_data ( )
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_GFX_PASSWD ) or self . edited ( EDIT_GFX_USE_PASSWD ) :
2013-08-01 03:14:17 +04:00
use_passwd = self . widget ( " gfx-use-password " ) . get_active ( )
if use_passwd :
passwd = self . get_text ( " gfx-password " , strip = False ) or " "
else :
passwd = None
2011-07-15 00:18:42 +04:00
add_define ( self . vm . define_graphics_password , dev_id_info , passwd )
add_hotplug ( self . vm . hotplug_graphics_password , dev_id_info ,
passwd )
2010-12-12 04:54:48 +03:00
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_GFX_KEYMAP ) :
2013-09-28 20:21:35 +04:00
keymap = self . get_combo_entry ( " gfx-keymap " )
2011-07-15 00:18:42 +04:00
add_define ( self . vm . define_graphics_keymap , dev_id_info , keymap )
2011-04-05 03:35:34 +04:00
2011-07-15 00:18:42 +04:00
# Do this last since it can change graphics unique ID
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_GFX_TYPE ) :
2013-09-28 20:21:35 +04:00
gtype = self . get_combo_entry ( " gfx-type " )
2013-10-03 01:30:09 +04:00
add_define ( self . vm . define_graphics_type , dev_id_info , gtype )
2010-12-12 04:54:48 +03:00
2011-07-15 00:18:42 +04:00
return self . _change_config_helper ( df , da , hf , ha )
2010-12-12 04:54:48 +03:00
2010-03-24 05:15:53 +03:00
# Video options
def config_video_apply ( self , dev_id_info ) :
2011-07-15 00:18:42 +04:00
df , da , add_define , hf , ha , add_hotplug = self . make_apply_data ( )
ignore = add_hotplug
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_VIDEO_MODEL ) :
2013-09-28 20:21:35 +04:00
model = self . get_combo_entry ( " video-model " )
2011-07-15 00:18:42 +04:00
if model :
add_define ( self . vm . define_video_model , dev_id_info , model )
return self . _change_config_helper ( df , da , hf , ha )
2009-11-04 21:18:14 +03:00
2011-09-23 19:14:15 +04:00
# Controller options
def config_controller_apply ( self , dev_id_info ) :
df , da , add_define , hf , ha , add_hotplug = self . make_apply_data ( )
ignore = add_hotplug
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_CONTROLLER_MODEL ) :
2013-09-28 20:21:35 +04:00
model = self . get_combo_entry ( " controller-model " )
2011-09-23 19:14:15 +04:00
if model :
add_define ( self . vm . define_controller_model , dev_id_info , model )
return self . _change_config_helper ( df , da , hf , ha )
2010-03-24 07:22:17 +03:00
# Watchdog options
def config_watchdog_apply ( self , dev_id_info ) :
2011-07-15 00:18:42 +04:00
df , da , add_define , hf , ha , add_hotplug = self . make_apply_data ( )
ignore = add_hotplug
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_WATCHDOG_MODEL ) :
2013-09-28 20:21:35 +04:00
model = self . get_combo_entry ( " watchdog-model " )
2011-07-15 00:18:42 +04:00
add_define ( self . vm . define_watchdog_model , dev_id_info , model )
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_WATCHDOG_ACTION ) :
2013-09-28 20:21:35 +04:00
action = self . get_combo_entry ( " watchdog-action " )
2011-07-15 00:18:42 +04:00
add_define ( self . vm . define_watchdog_action , dev_id_info , action )
return self . _change_config_helper ( df , da , hf , ha )
2010-03-24 07:22:17 +03:00
2009-11-04 00:15:18 +03:00
# Device removal
2009-11-04 21:18:14 +03:00
def remove_device ( self , dev_type , dev_id_info ) :
2012-01-17 07:04:40 +04:00
logging . debug ( " Removing device: %s %s " , dev_type , dev_id_info )
2011-04-15 00:43:17 +04:00
2013-08-09 17:23:01 +04:00
if not uihelpers . chkbox_helper ( self , self . config . get_confirm_removedev ,
2011-04-15 00:43:17 +04:00
self . config . set_confirm_removedev ,
text1 = ( _ ( " Are you sure you want to remove this device? " ) ) ) :
return
2009-11-04 21:18:14 +03:00
2009-11-20 17:29:26 +03:00
# Define the change
try :
2010-09-09 01:53:51 +04:00
self . vm . remove_device ( dev_id_info )
2009-11-20 17:29:26 +03:00
except Exception , e :
2011-04-06 19:22:03 +04:00
self . err . show_err ( _ ( " Error Removing Device: %s " % str ( e ) ) )
2009-11-20 17:29:26 +03:00
return
# Try to hot remove
2009-11-04 21:18:14 +03:00
detach_err = False
try :
if self . vm . is_active ( ) :
2010-09-09 01:53:51 +04:00
self . vm . detach_device ( dev_id_info )
2009-11-04 21:18:14 +03:00
except Exception , e :
2012-01-17 07:04:40 +04:00
logging . debug ( " Device could not be hotUNplugged: %s " , str ( e ) )
2010-12-02 01:48:07 +03:00
detach_err = ( str ( e ) , " " . join ( traceback . format_exc ( ) ) )
2009-11-04 21:18:14 +03:00
2010-12-02 01:48:07 +03:00
if not detach_err :
2012-09-27 21:47:13 +04:00
self . disable_apply ( )
2010-12-02 01:48:07 +03:00
return
self . err . show_err (
_ ( " Device could not be removed from the running machine " ) ,
2011-04-06 19:22:03 +04:00
details = ( detach_err [ 0 ] + " \n \n " + detach_err [ 1 ] ) ,
2011-07-15 01:16:57 +04:00
text2 = _ ( " This change will take effect after the next guest "
" shutdown. " ) ,
2012-05-14 17:24:56 +04:00
buttons = Gtk . ButtonsType . OK ,
dialog_type = Gtk . MessageType . INFO )
2009-11-04 21:18:14 +03:00
2009-11-04 21:23:22 +03:00
# Generic config change helpers
def _change_config_helper ( self ,
define_funcs , define_funcs_args ,
hotplug_funcs = None , hotplug_funcs_args = None ) :
"""
Requires at least a ' define ' function and arglist to be specified
( a function where we change the inactive guest config ) .
Arguments can be a single arg or a list or appropriate arg type ( e . g .
a list of functions for define_funcs )
"""
2013-08-09 17:23:01 +04:00
define_funcs = util . listify ( define_funcs )
define_funcs_args = util . listify ( define_funcs_args )
hotplug_funcs = util . listify ( hotplug_funcs )
hotplug_funcs_args = util . listify ( hotplug_funcs_args )
2009-11-04 21:23:22 +03:00
2010-12-02 01:48:07 +03:00
hotplug_err = [ ]
2009-11-04 21:23:22 +03:00
active = self . vm . is_active ( )
# Hotplug change
func = None
if active and hotplug_funcs :
for idx in range ( len ( hotplug_funcs ) ) :
func = hotplug_funcs [ idx ]
args = hotplug_funcs_args [ idx ]
try :
func ( * args )
except Exception , e :
2012-01-17 07:04:40 +04:00
logging . debug ( " Hotplug failed: func= %s : %s " ,
func , str ( e ) )
2010-12-02 01:48:07 +03:00
hotplug_err . append ( ( str ( e ) ,
" " . join ( traceback . format_exc ( ) ) ) )
2009-11-04 21:23:22 +03:00
# Persistent config change
2010-09-09 01:53:51 +04:00
try :
for idx in range ( len ( define_funcs ) ) :
func = define_funcs [ idx ]
args = define_funcs_args [ idx ]
2009-11-04 21:23:22 +03:00
func ( * args )
2010-09-09 01:53:51 +04:00
if define_funcs :
self . vm . redefine_cached ( )
except Exception , e :
self . err . show_err ( ( _ ( " Error changing VM configuration: %s " ) %
2011-04-06 19:22:03 +04:00
str ( e ) ) )
2010-09-09 01:53:51 +04:00
# If we fail, make sure we flush the cache
self . vm . refresh_xml ( )
return False
2009-11-04 21:23:22 +03:00
if ( hotplug_err or
( active and not len ( hotplug_funcs ) == len ( define_funcs ) ) ) :
if len ( define_funcs ) > 1 :
2011-07-15 01:16:57 +04:00
msg = _ ( " Some changes may require a guest shutdown "
2010-12-02 01:48:07 +03:00
" to take effect. " )
2009-11-04 21:23:22 +03:00
else :
2010-12-02 01:48:07 +03:00
msg = _ ( " These changes will take effect after "
2011-07-15 01:16:57 +04:00
" the next guest shutdown. " )
2010-12-02 01:48:07 +03:00
2012-05-14 17:24:56 +04:00
dtype = hotplug_err and Gtk . MessageType . WARNING or Gtk . MessageType . INFO
2010-12-02 01:48:07 +03:00
hotplug_msg = " "
for err1 , tb in hotplug_err :
hotplug_msg + = ( err1 + " \n \n " + tb + " \n " )
2011-04-06 19:22:03 +04:00
self . err . show_err ( msg ,
details = hotplug_msg ,
2012-05-14 17:24:56 +04:00
buttons = Gtk . ButtonsType . OK ,
2010-12-02 01:48:07 +03:00
dialog_type = dtype )
2009-11-04 21:23:22 +03:00
return True
2009-11-04 21:18:14 +03:00
########################
# Details page refresh #
########################
def refresh_resources ( self , ignore ) :
2011-07-14 21:13:13 +04:00
details = self . widget ( " details-pages " )
2009-11-04 21:18:14 +03:00
page = details . get_current_page ( )
# If the dialog is visible, we want to make sure the XML is always
# up to date
2013-08-16 17:59:33 +04:00
try :
if self . is_visible ( ) :
self . vm . refresh_xml ( )
except libvirt . libvirtError , e :
if uihelpers . exception_is_libvirt_error ( e , " VIR_ERR_NO_DOMAIN " ) :
self . close ( )
return
raise
2009-11-04 21:18:14 +03:00
2009-11-16 19:36:13 +03:00
# Stats page needs to be refreshed every tick
2013-09-02 01:40:38 +04:00
if ( page == DETAILS_PAGE_DETAILS and
2009-11-04 21:18:14 +03:00
self . get_hw_selection ( HW_LIST_COL_TYPE ) == HW_LIST_TYPE_STATS ) :
self . refresh_stats_page ( )
def page_refresh ( self , page ) :
2013-09-02 01:40:38 +04:00
if page != DETAILS_PAGE_DETAILS :
2009-11-04 21:18:14 +03:00
return
# This function should only be called when the VM xml actually
# changes (not everytime it is refreshed). This saves us from blindly
# parsing the xml every tick
# Add / remove new devices
self . repopulate_hw_list ( )
pagetype = self . get_hw_selection ( HW_LIST_COL_TYPE )
if pagetype is None :
return
2012-11-09 15:13:22 +04:00
if self . widget ( " config-apply " ) . get_sensitive ( ) :
2010-02-25 04:46:25 +03:00
# Apply button sensitive means user is making changes, don't
# erase them
return
2009-11-04 21:18:14 +03:00
self . hw_selected ( page = pagetype )
def refresh_overview_page ( self ) :
# Basic details
2011-07-14 21:13:13 +04:00
self . widget ( " overview-name " ) . set_text ( self . vm . get_name ( ) )
self . widget ( " overview-uuid " ) . set_text ( self . vm . get_uuid ( ) )
2010-02-10 20:16:59 +03:00
desc = self . vm . get_description ( ) or " "
2011-07-14 21:13:13 +04:00
desc_widget = self . widget ( " overview-description " )
2010-02-10 20:16:59 +03:00
desc_widget . get_buffer ( ) . set_text ( desc )
2009-11-04 21:18:14 +03:00
2013-09-24 15:02:27 +04:00
title = self . vm . get_title ( )
self . widget ( " overview-title " ) . set_sensitive ( self . vm . title_supported )
self . widget ( " overview-title " ) . set_text ( title or " " )
2009-11-04 21:18:14 +03:00
# Hypervisor Details
2011-07-14 21:13:13 +04:00
self . widget ( " overview-hv " ) . set_text ( self . vm . get_pretty_hv_type ( ) )
2009-11-04 21:18:14 +03:00
arch = self . vm . get_arch ( ) or _ ( " Unknown " )
emu = self . vm . get_emulator ( ) or _ ( " None " )
2011-07-14 21:13:13 +04:00
self . widget ( " overview-arch " ) . set_text ( arch )
self . widget ( " overview-emulator " ) . set_text ( emu )
2009-11-04 21:18:14 +03:00
2013-11-25 19:10:03 +04:00
inspection_supported = self . config . support_inspection
uihelpers . set_grid_row_visible ( self . widget ( " details-overview-error " ) ,
self . vm . inspection . error )
if self . vm . inspection . error :
msg = _ ( " Error while inspecting the guest configuration " )
self . widget ( " details-overview-error " ) . set_text ( msg )
2011-07-18 22:53:57 +04:00
# Operating System (ie. inspection data)
2013-11-25 19:10:03 +04:00
self . widget ( " details-inspection-os " ) . set_visible ( inspection_supported )
if inspection_supported :
hostname = self . vm . inspection . hostname
if not hostname :
hostname = _ ( " unknown " )
self . widget ( " inspection-hostname " ) . set_text ( hostname )
product_name = self . vm . inspection . product_name
if not product_name :
product_name = _ ( " unknown " )
self . widget ( " inspection-product-name " ) . set_text ( product_name )
2011-07-18 22:53:57 +04:00
# Applications (also inspection data)
2013-11-25 19:10:03 +04:00
self . widget ( " details-inspection-apps " ) . set_visible ( inspection_supported )
if inspection_supported :
apps = self . vm . inspection . applications or [ ]
apps_list = self . widget ( " inspection-apps " )
apps_model = apps_list . get_model ( )
apps_model . clear ( )
for app in apps :
name = " "
if app [ " app_name " ] :
name = app [ " app_name " ]
if app [ " app_display_name " ] :
name = app [ " app_display_name " ]
version = " "
if app [ " app_version " ] :
version = app [ " app_version " ]
if app [ " app_release " ] :
version + = " - " + app [ " app_release " ]
summary = " "
if app [ " app_summary " ] :
summary = app [ " app_summary " ]
apps_model . append ( [ name , version , summary ] )
2011-07-18 22:53:57 +04:00
2009-11-04 21:18:14 +03:00
# Machine settings
acpi = self . vm . get_acpi ( )
apic = self . vm . get_apic ( )
clock = self . vm . get_clock ( )
2012-01-05 13:35:40 +04:00
machtype = self . vm . get_machtype ( )
2009-11-04 21:18:14 +03:00
2011-03-24 21:33:35 +03:00
# Hack in a way to represent 'default' acpi/apic for customize dialog
2011-07-14 21:13:13 +04:00
self . widget ( " overview-acpi " ) . set_active ( bool ( acpi ) )
self . widget ( " overview-acpi " ) . set_inconsistent (
2011-03-24 21:33:35 +03:00
acpi is None and self . is_customize_dialog )
2011-07-14 21:13:13 +04:00
self . widget ( " overview-apic " ) . set_active ( bool ( apic ) )
self . widget ( " overview-apic " ) . set_inconsistent (
2011-03-24 21:33:35 +03:00
apic is None and self . is_customize_dialog )
2010-03-24 05:15:53 +03:00
2009-11-04 21:18:14 +03:00
if not clock :
clock = _ ( " Same as host " )
2013-09-28 20:21:35 +04:00
self . set_combo_entry ( " overview-clock " , clock )
2009-11-04 21:18:14 +03:00
2012-01-05 13:35:40 +04:00
if not arch in [ " i686 " , " x86_64 " ] :
if machtype is not None :
2013-09-28 20:21:35 +04:00
self . set_combo_entry ( " machine-type " , machtype )
2012-01-05 13:35:40 +04:00
2009-11-04 21:18:14 +03:00
# Security details
2013-02-05 15:28:06 +04:00
semodel , sectype , vmlabel , relabel = self . vm . get_seclabel ( )
2013-07-06 22:12:13 +04:00
caps = self . vm . conn . caps
2009-11-04 21:18:14 +03:00
if caps . host . secmodel and caps . host . secmodel . model :
2011-01-13 19:57:26 +03:00
semodel = caps . host . secmodel . model
2011-03-01 05:22:48 +03:00
2011-07-14 21:13:13 +04:00
self . widget ( " security-model " ) . set_text ( semodel or _ ( " None " ) )
2009-11-04 21:18:14 +03:00
2011-03-01 05:22:48 +03:00
if not semodel or semodel == " apparmor " :
2011-07-14 21:13:13 +04:00
self . widget ( " security-type-box " ) . hide ( )
self . widget ( " security-type-label " ) . hide ( )
2009-11-04 21:18:14 +03:00
else :
2011-07-14 21:13:13 +04:00
self . widget ( " security-type-box " ) . set_sensitive ( bool ( semodel ) )
2011-03-01 05:22:48 +03:00
2013-02-05 15:28:06 +04:00
if sectype == " static " :
2011-07-14 21:13:13 +04:00
self . widget ( " security-static " ) . set_active ( True )
2013-02-05 15:28:06 +04:00
self . widget ( " security-relabel " ) . set_sensitive ( True )
# As "no" is default for relabel with 'static' label and
# 'dynamic' must have relabel='yes', this will work properly
# for both False (relabel='no') and None (relabel not
# specified)
self . widget ( " security-relabel " ) . set_active ( relabel )
2011-03-01 05:22:48 +03:00
else :
2011-07-14 21:13:13 +04:00
self . widget ( " security-dynamic " ) . set_active ( True )
2013-02-05 15:28:06 +04:00
# Dynamic label type must use resource labeling
self . widget ( " security-relabel " ) . set_active ( True )
self . widget ( " security-relabel " ) . set_sensitive ( False )
2011-07-14 21:13:13 +04:00
self . widget ( " security-label " ) . set_text ( vmlabel )
2009-11-04 21:18:14 +03:00
def refresh_stats_page ( self ) :
2010-08-22 03:27:45 +04:00
def _dsk_rx_tx_text ( rx , tx , unit ) :
2013-09-27 22:17:57 +04:00
return ( ' <span color= " #82003B " > %(rx)d %(unit)s read</span> '
2010-08-22 03:27:45 +04:00
' <span color= " #295C45 " > %(tx)d %(unit)s write</span> ' %
2010-12-09 19:22:35 +03:00
{ " rx " : rx , " tx " : tx , " unit " : unit } )
2010-08-22 03:27:45 +04:00
def _net_rx_tx_text ( rx , tx , unit ) :
2013-09-27 22:17:57 +04:00
return ( ' <span color= " #82003B " > %(rx)d %(unit)s in</span> '
2010-08-22 03:27:45 +04:00
' <span color= " #295C45 " > %(tx)d %(unit)s out</span> ' %
2010-12-09 19:22:35 +03:00
{ " rx " : rx , " tx " : tx , " unit " : unit } )
2009-11-04 21:18:14 +03:00
cpu_txt = _ ( " Disabled " )
mem_txt = _ ( " Disabled " )
dsk_txt = _ ( " Disabled " )
net_txt = _ ( " Disabled " )
2013-04-28 02:42:32 +04:00
cpu_txt = " %d %% " % self . vm . guest_cpu_time_percentage ( )
2009-11-04 21:18:14 +03:00
2013-04-28 02:42:32 +04:00
cur_vm_memory = self . vm . stats_memory ( )
vm_memory = self . vm . maximum_memory ( )
mem_txt = " %s of %s " % ( util . pretty_mem ( cur_vm_memory ) ,
util . pretty_mem ( vm_memory ) )
2009-11-04 21:18:14 +03:00
if self . config . get_stats_enable_disk_poll ( ) :
2010-08-22 03:27:45 +04:00
dsk_txt = _dsk_rx_tx_text ( self . vm . disk_read_rate ( ) ,
self . vm . disk_write_rate ( ) , " KB/s " )
2009-11-04 21:18:14 +03:00
if self . config . get_stats_enable_net_poll ( ) :
2010-08-22 03:27:45 +04:00
net_txt = _net_rx_tx_text ( self . vm . network_rx_rate ( ) ,
self . vm . network_tx_rate ( ) , " KB/s " )
2009-11-04 21:18:14 +03:00
2011-07-14 21:13:13 +04:00
self . widget ( " overview-cpu-usage-text " ) . set_text ( cpu_txt )
self . widget ( " overview-memory-usage-text " ) . set_text ( mem_txt )
self . widget ( " overview-network-traffic-text " ) . set_markup ( net_txt )
self . widget ( " overview-disk-usage-text " ) . set_markup ( dsk_txt )
2009-11-04 21:18:14 +03:00
self . cpu_usage_graph . set_property ( " data_array " ,
2013-04-28 02:42:32 +04:00
self . vm . guest_cpu_time_vector ( ) )
2009-11-04 21:18:14 +03:00
self . memory_usage_graph . set_property ( " data_array " ,
2011-04-10 07:03:01 +04:00
self . vm . stats_memory_vector ( ) )
2009-11-04 21:18:14 +03:00
self . disk_io_graph . set_property ( " data_array " ,
self . vm . disk_io_vector ( ) )
self . network_traffic_graph . set_property ( " data_array " ,
self . vm . network_traffic_vector ( ) )
2011-01-13 21:32:19 +03:00
def _refresh_cpu_count ( self ) :
2011-07-23 00:43:26 +04:00
conn = self . vm . conn
2009-11-11 20:56:58 +03:00
host_active_count = conn . host_active_processor_count ( )
2011-01-13 21:32:19 +03:00
maxvcpus = self . vm . vcpu_max_count ( )
2009-11-11 20:56:58 +03:00
curvcpus = self . vm . vcpu_count ( )
2013-04-17 02:37:00 +04:00
curadj = self . widget ( " config-vcpus " )
maxadj = self . widget ( " config-maxvcpus " )
curadj . set_value ( int ( curvcpus ) )
maxadj . set_value ( int ( maxvcpus ) )
2006-11-13 23:31:17 +03:00
2011-07-14 21:13:13 +04:00
self . widget ( " state-host-cpus " ) . set_text ( str ( host_active_count ) )
2009-11-11 20:56:58 +03:00
2010-05-13 20:55:08 +04:00
# Warn about overcommit
2011-01-13 21:32:19 +03:00
warn = bool ( self . config_get_vcpus ( ) > host_active_count )
2013-09-02 04:18:14 +04:00
self . widget ( " config-vcpus-warn-box " ) . set_visible ( warn )
2010-12-17 00:05:55 +03:00
def _refresh_cpu_pinning ( self ) :
2009-11-16 19:36:13 +03:00
# Populate VCPU pinning
2011-01-13 21:55:35 +03:00
vcpupin = self . vm . vcpu_pinning ( )
2011-07-14 21:13:13 +04:00
self . widget ( " config-vcpupin " ) . set_text ( vcpupin )
2006-11-13 23:31:17 +03:00
2011-01-13 21:55:35 +03:00
def _refresh_runtime_pinning ( self ) :
2011-07-23 00:43:26 +04:00
conn = self . vm . conn
2011-01-13 21:55:35 +03:00
host_active_count = conn . host_active_processor_count ( )
2011-07-14 21:13:13 +04:00
vcpu_list = self . widget ( " config-vcpu-list " )
2009-11-16 19:36:13 +03:00
vcpu_model = vcpu_list . get_model ( )
vcpu_model . clear ( )
reason = " "
if not self . vm . is_active ( ) :
reason = _ ( " VCPU info only available for running domain. " )
else :
try :
vcpu_info , vcpu_pinning = self . vm . vcpu_info ( )
except Exception , e :
reason = _ ( " Error getting VCPU info: %s " ) % str ( e )
2011-07-13 05:53:01 +04:00
if not self . vm . getvcpus_supported :
reason = _ ( " Virtual machine does not support runtime "
" VPCU info. " )
2009-11-16 19:36:13 +03:00
vcpu_list . set_sensitive ( not bool ( reason ) )
2012-05-14 17:24:56 +04:00
vcpu_list . set_tooltip_text ( reason or " " )
2009-11-16 19:36:13 +03:00
if reason :
return
def build_cpuset_str ( pin_info ) :
pinstr = " "
for i in range ( host_active_count ) :
if i < len ( pin_info ) and pin_info [ i ] :
pinstr + = ( " , %s " % str ( i ) )
return pinstr . strip ( " , " )
for idx in range ( len ( vcpu_info ) ) :
2011-02-03 18:49:08 +03:00
vcpu = str ( vcpu_info [ idx ] [ 0 ] )
vcpucur = str ( vcpu_info [ idx ] [ 3 ] )
2009-11-16 19:36:13 +03:00
vcpupin = build_cpuset_str ( vcpu_pinning [ idx ] )
vcpu_model . append ( [ vcpu , vcpucur , vcpupin ] )
2010-12-17 00:05:55 +03:00
def _refresh_cpu_config ( self , cpu ) :
2011-07-14 21:13:13 +04:00
feature_ui = self . widget ( " cpu-features " )
2010-12-17 00:05:55 +03:00
model = cpu . model or " "
2013-07-06 22:12:13 +04:00
caps = self . vm . conn . caps
2011-07-13 22:35:34 +04:00
capscpu = None
try :
2012-01-29 22:07:16 +04:00
arch = self . vm . get_arch ( )
if arch :
cpu_values = caps . get_cpu_values ( arch )
for c in cpu_values . cpus :
if model and c . model == model :
capscpu = c
break
2011-07-13 22:35:34 +04:00
except :
pass
2010-12-17 00:05:55 +03:00
show_top = bool ( cpu . sockets or cpu . cores or cpu . threads )
sockets = cpu . sockets or 1
cores = cpu . cores or 1
threads = cpu . threads or 1
2011-07-14 21:13:13 +04:00
self . widget ( " cpu-topology-enable " ) . set_active ( show_top )
2012-05-14 17:24:56 +04:00
self . widget ( " cpu-model " ) . get_child ( ) . set_text ( model )
2011-07-14 21:13:13 +04:00
self . widget ( " cpu-sockets " ) . set_value ( sockets )
self . widget ( " cpu-cores " ) . set_value ( cores )
self . widget ( " cpu-threads " ) . set_value ( threads )
2010-12-17 00:05:55 +03:00
2011-07-13 22:35:34 +04:00
def get_feature_policy ( name ) :
2011-03-18 00:41:29 +03:00
for f in cpu . features :
if f . name == name :
2011-07-13 22:35:34 +04:00
return f . policy
if capscpu :
for f in capscpu . features :
if f == name :
return " model "
return " off "
2011-03-18 00:41:29 +03:00
for row in feature_ui . get_model ( ) :
2011-07-13 22:35:34 +04:00
row [ 1 ] = get_feature_policy ( row [ 0 ] )
2011-03-18 00:41:29 +03:00
2010-12-17 00:05:55 +03:00
def refresh_config_cpu ( self ) :
2013-04-26 23:58:18 +04:00
self . _cpu_copy_host = False
2010-12-17 00:05:55 +03:00
cpu = self . vm . get_cpu_config ( )
2011-01-13 21:32:19 +03:00
self . _refresh_cpu_count ( )
2010-12-17 00:05:55 +03:00
self . _refresh_cpu_pinning ( )
2011-01-13 21:55:35 +03:00
self . _refresh_runtime_pinning ( )
2010-12-17 00:05:55 +03:00
self . _refresh_cpu_config ( cpu )
2006-11-13 23:31:17 +03:00
def refresh_config_memory ( self ) :
2011-07-14 21:13:13 +04:00
host_mem_widget = self . widget ( " state-host-memory " )
2011-07-23 00:43:26 +04:00
host_mem = self . vm . conn . host_memory_size ( ) / 1024
2010-12-10 19:47:07 +03:00
vm_cur_mem = self . vm . get_memory ( ) / 1024.0
vm_max_mem = self . vm . maximum_memory ( ) / 1024.0
2009-11-11 20:56:58 +03:00
host_mem_widget . set_text ( " %d MB " % ( int ( round ( host_mem ) ) ) )
2008-03-18 21:37:22 +03:00
2013-04-17 02:37:00 +04:00
curmem = self . widget ( " config-memory " )
maxmem = self . widget ( " config-maxmem " )
curmem . set_value ( int ( round ( vm_cur_mem ) ) )
maxmem . set_value ( int ( round ( vm_max_mem ) ) )
2006-09-22 20:31:51 +04:00
2012-11-09 15:13:22 +04:00
if not self . widget ( " config-memory " ) . get_sensitive ( ) :
2013-04-17 03:22:59 +04:00
ignore , upper = maxmem . get_range ( )
2013-04-17 02:37:00 +04:00
maxmem . set_range ( curmem . get_value ( ) , upper )
2009-11-11 20:56:58 +03:00
2006-07-27 02:19:33 +04:00
2009-01-15 19:23:23 +03:00
def refresh_disk_page ( self ) :
2010-09-03 22:10:04 +04:00
disk = self . get_hw_selection ( HW_LIST_COL_DEVICE )
if not disk :
2009-01-15 19:23:23 +03:00
return
2010-09-03 22:10:04 +04:00
path = disk . path
devtype = disk . device
ro = disk . read_only
share = disk . shareable
bus = disk . bus
2013-10-04 05:39:01 +04:00
removable = disk . removable
2012-02-29 12:48:18 +04:00
addr = disk . address . type
2010-09-03 22:10:04 +04:00
idx = disk . disk_bus_index
cache = disk . driver_cache
2011-07-24 04:41:35 +04:00
io = disk . driver_io
2010-12-11 03:20:14 +03:00
driver_type = disk . driver_type or " "
2011-07-13 21:16:19 +04:00
serial = disk . serial
2013-02-17 17:40:37 +04:00
2013-04-17 21:23:27 +04:00
iotune_rbs = ( disk . iotune_rbs or 0 ) / 1024
iotune_ris = ( disk . iotune_ris or 0 )
iotune_tbs = ( disk . iotune_tbs or 0 ) / 1024
iotune_tis = ( disk . iotune_tis or 0 )
iotune_wbs = ( disk . iotune_wbs or 0 ) / 1024
iotune_wis = ( disk . iotune_wis or 0 )
2013-02-17 17:40:37 +04:00
2011-03-09 18:37:51 +03:00
show_format = ( not self . is_customize_dialog or
disk . path_exists ( disk . conn , disk . path ) )
2009-11-04 23:41:18 +03:00
2010-03-04 02:43:48 +03:00
size = _ ( " Unknown " )
if not path :
size = " - "
else :
vol = self . conn . get_vol_by_path ( path )
if vol :
size = vol . get_pretty_capacity ( )
elif not self . conn . is_remote ( ) :
2010-03-04 23:36:29 +03:00
ignore , val = virtinst . VirtualDisk . stat_local_path ( path )
if val != 0 :
size = prettyify_bytes ( val )
2010-03-04 02:43:48 +03:00
2009-11-05 00:30:51 +03:00
is_cdrom = ( devtype == virtinst . VirtualDisk . DEVICE_CDROM )
2009-12-11 03:18:24 +03:00
is_floppy = ( devtype == virtinst . VirtualDisk . DEVICE_FLOPPY )
2013-10-04 05:39:01 +04:00
is_usb = ( bus == " usb " )
can_set_removable = ( is_usb and ( self . conn . is_qemu ( ) or
self . conn . is_test_conn ( ) ) )
if removable is None :
removable = False
2013-10-04 05:39:02 +04:00
else :
can_set_removable = True
2009-11-05 00:30:51 +03:00
2012-02-29 12:48:18 +04:00
if addr == " spapr-vio " :
bus = " spapr-vscsi "
2009-12-02 05:34:29 +03:00
pretty_name = prettyify_disk ( devtype , bus , idx )
2009-11-04 23:41:18 +03:00
2011-07-14 21:13:13 +04:00
self . widget ( " disk-source-path " ) . set_text ( path or " - " )
self . widget ( " disk-target-type " ) . set_text ( pretty_name )
2009-11-04 23:41:18 +03:00
2011-07-14 21:13:13 +04:00
self . widget ( " disk-readonly " ) . set_active ( ro )
self . widget ( " disk-readonly " ) . set_sensitive ( not is_cdrom )
self . widget ( " disk-shareable " ) . set_active ( share )
2013-10-04 05:39:01 +04:00
self . widget ( " disk-removable " ) . set_active ( removable )
uihelpers . set_grid_row_visible ( self . widget ( " disk-removable " ) ,
can_set_removable )
2011-07-14 21:13:13 +04:00
self . widget ( " disk-size " ) . set_text ( size )
2013-09-28 20:21:35 +04:00
self . set_combo_entry ( " disk-cache " , cache )
self . set_combo_entry ( " disk-io " , io )
2011-03-09 18:36:21 +03:00
2011-07-14 21:13:13 +04:00
self . widget ( " disk-format " ) . set_sensitive ( show_format )
2012-05-14 17:24:56 +04:00
self . widget ( " disk-format " ) . get_child ( ) . set_text ( driver_type )
2009-11-04 23:41:18 +03:00
2010-12-11 04:33:41 +03:00
no_default = not self . is_customize_dialog
self . populate_disk_bus_combo ( devtype , no_default )
2013-09-28 20:21:35 +04:00
self . set_combo_entry ( " disk-bus " , bus )
2011-07-14 21:13:13 +04:00
self . widget ( " disk-serial " ) . set_text ( serial or " " )
2010-12-11 04:33:41 +03:00
2013-04-17 02:37:00 +04:00
self . widget ( " disk-iotune-rbs " ) . set_value ( iotune_rbs )
self . widget ( " disk-iotune-ris " ) . set_value ( iotune_ris )
self . widget ( " disk-iotune-tbs " ) . set_value ( iotune_tbs )
self . widget ( " disk-iotune-tis " ) . set_value ( iotune_tis )
self . widget ( " disk-iotune-wbs " ) . set_value ( iotune_wbs )
self . widget ( " disk-iotune-wis " ) . set_value ( iotune_wis )
2013-02-17 17:40:37 +04:00
2011-07-14 21:13:13 +04:00
button = self . widget ( " config-cdrom-connect " )
2009-12-11 03:18:24 +03:00
if is_cdrom or is_floppy :
2009-11-04 23:41:18 +03:00
if not path :
2009-01-15 19:23:23 +03:00
# source device not connected
2012-05-14 17:24:56 +04:00
button . set_label ( Gtk . STOCK_CONNECT )
2007-09-22 00:28:31 +04:00
else :
2012-05-14 17:24:56 +04:00
button . set_label ( Gtk . STOCK_DISCONNECT )
2009-01-15 19:23:23 +03:00
button . show ( )
else :
button . hide ( )
2007-04-11 22:48:36 +04:00
def refresh_network_page ( self ) :
2010-09-03 23:19:54 +04:00
net = self . get_hw_selection ( HW_LIST_COL_DEVICE )
if not net :
2009-01-15 19:23:23 +03:00
return
2010-09-03 23:19:54 +04:00
nettype = net . type
2013-09-24 18:00:01 +04:00
source = net . source
2011-04-19 15:08:15 +04:00
source_mode = net . source_mode
2010-09-03 23:19:54 +04:00
model = net . model
2009-12-02 17:54:29 +03:00
netobj = None
if nettype == virtinst . VirtualNetworkInterface . TYPE_VIRTUAL :
name_dict = { }
for uuid in self . conn . list_net_uuids ( ) :
2010-09-03 23:19:54 +04:00
vnet = self . conn . get_net ( uuid )
name = vnet . get_name ( )
name_dict [ name ] = vnet
2009-12-02 17:54:29 +03:00
2010-12-10 19:47:07 +03:00
if source and source in name_dict :
2009-12-02 17:54:29 +03:00
netobj = name_dict [ source ]
desc = uihelpers . pretty_network_desc ( nettype , source , netobj )
2011-07-14 21:13:13 +04:00
self . widget ( " network-mac-address " ) . set_text ( net . macaddr )
2011-03-17 23:33:40 +03:00
uihelpers . populate_network_list (
2013-09-28 20:21:35 +04:00
self . widget ( " network-source " ) ,
2011-03-17 23:33:40 +03:00
self . conn )
2013-09-28 20:21:35 +04:00
self . widget ( " network-source " ) . set_active ( - 1 )
2011-03-17 23:33:40 +03:00
2011-07-14 21:13:13 +04:00
self . widget ( " network-bridge " ) . set_text ( " " )
2011-03-17 23:33:40 +03:00
def compare_network ( model , info ) :
for idx in range ( len ( model ) ) :
row = model [ idx ]
if row [ 0 ] == info [ 0 ] and row [ 1 ] == info [ 1 ] :
return True , idx
if info [ 0 ] == virtinst . VirtualNetworkInterface . TYPE_BRIDGE :
idx = ( len ( model ) - 1 )
2011-07-14 21:13:13 +04:00
self . widget ( " network-bridge " ) . set_text ( str ( info [ 1 ] ) )
2011-03-17 23:33:40 +03:00
return True , idx
return False , 0
2013-09-28 20:21:35 +04:00
self . set_combo_entry ( " network-source " ,
2011-03-17 23:33:40 +03:00
( nettype , source ) , label = desc ,
comparefunc = compare_network )
2009-01-15 19:23:23 +03:00
2013-09-28 20:21:35 +04:00
is_direct = ( nettype == " direct " )
uihelpers . set_grid_row_visible ( self . widget ( " network-source-mode " ) ,
is_direct )
self . widget ( " vport-expander " ) . set_visible ( is_direct )
2011-04-19 15:08:15 +04:00
# source mode
uihelpers . populate_source_mode_combo ( self . vm ,
2013-09-28 20:21:35 +04:00
self . widget ( " network-source-mode " ) )
self . set_combo_entry ( " network-source-mode " , source_mode )
2011-04-19 15:08:15 +04:00
2011-03-17 22:36:36 +03:00
# Virtualport config
vport = net . virtualport
2011-07-14 21:13:13 +04:00
self . widget ( " vport-type " ) . set_text ( vport . type or " " )
2013-07-15 21:08:58 +04:00
self . widget ( " vport-managerid " ) . set_text ( str ( vport . managerid ) or " " )
self . widget ( " vport-typeid " ) . set_text ( str ( vport . typeid ) or " " )
self . widget ( " vport-typeidversion " ) . set_text (
str ( vport . typeidversion ) or " " )
2011-07-14 21:13:13 +04:00
self . widget ( " vport-instanceid " ) . set_text ( vport . instanceid or " " )
2011-03-16 19:43:28 +03:00
2010-03-24 05:15:53 +03:00
uihelpers . populate_netmodel_combo ( self . vm ,
2013-09-28 20:21:35 +04:00
self . widget ( " network-model " ) )
self . set_combo_entry ( " network-model " , model )
2007-04-12 23:36:04 +04:00
2007-09-26 04:05:45 +04:00
def refresh_input_page ( self ) :
2010-09-03 23:59:33 +04:00
inp = self . get_hw_selection ( HW_LIST_COL_DEVICE )
if not inp :
2009-01-15 19:23:23 +03:00
return
2007-09-26 04:05:45 +04:00
2010-09-03 23:59:33 +04:00
ident = " %s : %s " % ( inp . type , inp . bus )
2013-04-13 22:34:52 +04:00
if ident == " tablet:usb " :
2009-11-11 20:56:58 +03:00
dev = _ ( " EvTouch USB Graphics Tablet " )
2010-09-03 23:59:33 +04:00
elif ident == " mouse:usb " :
2009-11-11 20:56:58 +03:00
dev = _ ( " Generic USB Mouse " )
2010-09-03 23:59:33 +04:00
elif ident == " mouse:xen " :
2009-11-11 20:56:58 +03:00
dev = _ ( " Xen Mouse " )
2010-09-03 23:59:33 +04:00
elif ident == " mouse:ps2 " :
2009-11-11 20:56:58 +03:00
dev = _ ( " PS/2 Mouse " )
2009-01-15 19:23:23 +03:00
else :
2010-09-03 23:59:33 +04:00
dev = inp . bus + " " + inp . type
2007-09-26 04:05:45 +04:00
2010-09-03 23:59:33 +04:00
if inp . type == " tablet " :
2009-11-11 20:56:58 +03:00
mode = _ ( " Absolute Movement " )
2009-01-15 19:23:23 +03:00
else :
2009-11-11 20:56:58 +03:00
mode = _ ( " Relative Movement " )
2011-07-14 21:13:13 +04:00
self . widget ( " input-dev-type " ) . set_text ( dev )
self . widget ( " input-dev-mode " ) . set_text ( mode )
2009-01-15 19:23:23 +03:00
# Can't remove primary Xen or PS/2 mice
2010-09-03 23:59:33 +04:00
if inp . type == " mouse " and inp . bus in ( " xen " , " ps2 " ) :
2011-07-14 21:13:13 +04:00
self . widget ( " config-remove " ) . set_sensitive ( False )
2009-01-15 19:23:23 +03:00
else :
2011-07-14 21:13:13 +04:00
self . widget ( " config-remove " ) . set_sensitive ( True )
2007-09-26 04:05:45 +04:00
2007-09-27 03:39:11 +04:00
def refresh_graphics_page ( self ) :
2010-09-03 23:59:33 +04:00
gfx = self . get_hw_selection ( HW_LIST_COL_DEVICE )
if not gfx :
2009-01-15 19:23:23 +03:00
return
2007-09-27 03:39:11 +04:00
2011-07-14 21:13:13 +04:00
table = self . widget ( " graphics-table " )
2010-12-20 20:34:32 +03:00
table . foreach ( lambda w , ignore : w . hide ( ) , ( ) )
2013-09-28 20:21:35 +04:00
def show_row ( name ) :
uihelpers . set_grid_row_visible ( self . widget ( name ) , True )
2013-08-01 03:14:17 +04:00
2010-12-20 20:48:14 +03:00
def port_to_string ( port ) :
if port is None :
return " - "
return ( port == - 1 and _ ( " Automatically allocated " ) or str ( port ) )
2010-12-12 04:54:48 +03:00
gtype = gfx . type
is_vnc = ( gtype == " vnc " )
is_sdl = ( gtype == " sdl " )
2010-12-20 20:48:14 +03:00
is_spice = ( gtype == " spice " )
2011-02-15 19:38:35 +03:00
is_other = not ( True in [ is_vnc , is_sdl , is_spice ] )
2009-11-11 20:56:58 +03:00
2013-09-28 20:21:35 +04:00
title = ( _ ( " %(graphicstype)s Server " ) %
2011-03-24 17:09:42 +03:00
{ " graphicstype " : gfx . pretty_type_simple ( gtype ) } )
2010-12-20 20:34:32 +03:00
2011-03-17 21:24:36 +03:00
settype = " "
2010-12-20 20:48:14 +03:00
if is_vnc or is_spice :
2013-08-01 03:14:17 +04:00
use_passwd = gfx . passwd is not None
2010-12-12 04:54:48 +03:00
2013-09-28 20:21:35 +04:00
show_row ( " gfx-password-box " )
show_row ( " gfx-address " )
show_row ( " gfx-port " )
show_row ( " gfx-keymap " )
self . widget ( " gfx-port " ) . set_text ( port_to_string ( gfx . port ) )
self . widget ( " gfx-address " ) . set_text ( gfx . listen or " 127.0.0.1 " )
self . set_combo_entry ( " gfx-keymap " , gfx . keymap or None )
self . widget ( " gfx-password " ) . set_text ( gfx . passwd or " " )
self . widget ( " gfx-use-password " ) . set_active ( use_passwd )
self . widget ( " gfx-password " ) . set_sensitive ( use_passwd )
2010-12-20 20:34:32 +03:00
2011-03-17 21:24:36 +03:00
settype = gtype
2010-12-20 20:34:32 +03:00
2010-12-20 20:48:14 +03:00
if is_spice :
2013-09-28 20:21:35 +04:00
show_row ( " gfx-tlsport " )
self . widget ( " gfx-tlsport " ) . set_text ( port_to_string ( gfx . tlsPort ) )
2010-12-20 20:48:14 +03:00
if is_sdl :
2013-09-28 20:21:35 +04:00
title = _ ( " Local SDL Window " )
2009-01-15 19:23:23 +03:00
2013-09-28 20:21:35 +04:00
show_row ( " gfx-display " )
show_row ( " gfx-xauth " )
self . widget ( " gfx-display " ) . set_text ( gfx . display or _ ( " Unknown " ) )
self . widget ( " gfx-xauth " ) . set_text ( gfx . xauth or _ ( " Unknown " ) )
2009-11-11 20:56:58 +03:00
2010-12-20 20:48:14 +03:00
if is_other :
2011-03-24 17:09:42 +03:00
settype = gfx . pretty_type_simple ( gtype )
2011-03-17 21:24:36 +03:00
if settype :
2013-09-28 20:21:35 +04:00
show_row ( " gfx-type " )
self . set_combo_entry ( " gfx-type " , gtype , label = settype )
self . widget ( " graphics-title " ) . set_markup ( " <b> %s </b> " % title )
2009-01-15 19:23:23 +03:00
2008-07-31 03:52:39 +04:00
def refresh_sound_page ( self ) :
2010-09-03 23:59:33 +04:00
sound = self . get_hw_selection ( HW_LIST_COL_DEVICE )
if not sound :
2008-07-31 03:52:39 +04:00
return
2009-01-15 19:23:23 +03:00
2013-09-28 20:21:35 +04:00
self . set_combo_entry ( " sound-model " , sound . model )
2008-07-31 03:52:39 +04:00
2011-06-23 19:42:03 +04:00
def refresh_smartcard_page ( self ) :
sc = self . get_hw_selection ( HW_LIST_COL_DEVICE )
if not sc :
return
2013-09-28 20:21:35 +04:00
self . set_combo_entry ( " smartcard-mode " , sc . mode )
2011-06-23 19:42:03 +04:00
2011-09-02 05:23:27 +04:00
def refresh_redir_page ( self ) :
rd = self . get_hw_selection ( HW_LIST_COL_DEVICE )
if not rd :
return
address = build_redir_label ( rd ) [ 0 ] or " - "
devlabel = " <b>Redirected %s Device</b> " % rd . bus . upper ( )
self . widget ( " redir-title " ) . set_markup ( devlabel )
self . widget ( " redir-address " ) . set_text ( address )
2013-09-28 20:21:35 +04:00
self . widget ( " redir-type " ) . set_text ( rd . type )
2011-09-02 05:23:27 +04:00
2013-06-26 05:45:08 +04:00
def refresh_tpm_page ( self ) :
tpmdev = self . get_hw_selection ( HW_LIST_COL_DEVICE )
if not tpmdev :
return
def show_ui ( param , val = None ) :
widgetname = " tpm- " + param . replace ( " _ " , " - " )
doshow = tpmdev . supports_property ( param )
if not val and doshow :
val = getattr ( tpmdev , param )
2013-09-24 02:43:50 +04:00
uihelpers . set_grid_row_visible ( self . widget ( widgetname ) , doshow )
2013-06-26 05:45:08 +04:00
self . widget ( widgetname ) . set_text ( val or " - " )
dev_type = tpmdev . type
2013-07-15 20:18:23 +04:00
self . widget ( " tpm-dev-type " ) . set_text (
virtinst . VirtualTPMDevice . get_pretty_type ( dev_type ) )
2013-06-26 05:45:08 +04:00
# Device type specific properties, only show if apply to the cur dev
show_ui ( " device_path " )
2014-01-10 13:37:55 +04:00
def refresh_panic_page ( self ) :
dev = self . get_hw_selection ( HW_LIST_COL_DEVICE )
if not dev :
return
def show_ui ( param , val = None ) :
widgetname = " panic- " + param . replace ( " _ " , " - " )
if not val :
val = getattr ( dev , param )
uihelpers . set_grid_row_visible ( self . widget ( widgetname ) , True )
self . widget ( widgetname ) . set_text ( val or " - " )
2014-01-12 00:08:00 +04:00
ptyp = virtinst . VirtualPanicDevice . get_pretty_type ( dev . type )
show_ui ( " type " , ptyp )
2014-01-10 13:37:55 +04:00
show_ui ( " iobase " )
2013-09-23 17:39:56 +04:00
def refresh_rng_page ( self ) :
dev = self . get_hw_selection ( HW_LIST_COL_DEVICE )
values = {
2013-10-25 19:13:29 +04:00
" rng-bind-host " : " bind_host " ,
" rng-bind-service " : " bind_service " ,
" rng-connect-host " : " connect_host " ,
" rng-connect-service " : " connect_service " ,
2013-09-23 17:39:56 +04:00
" rng-type " : " type " ,
" rng-device " : " device " ,
" rng-backend-type " : " backend_type " ,
" rng-rate-bytes " : " rate_bytes " ,
" rng-rate-period " : " rate_period "
}
rewriter = {
" rng-type " : lambda x :
2013-10-25 19:13:29 +04:00
VirtualRNGDevice . get_pretty_type ( x ) ,
2013-09-23 17:39:56 +04:00
" rng-backend-type " : lambda x :
2013-10-25 19:13:29 +04:00
VirtualRNGDevice . get_pretty_backend_type ( x ) ,
2013-09-23 17:39:56 +04:00
}
2013-10-25 19:13:29 +04:00
def set_visible ( widget , v ) :
uihelpers . set_grid_row_visible ( self . widget ( widget ) , v )
is_egd = dev . type == VirtualRNGDevice . TYPE_EGD
udp = dev . backend_type == VirtualRNGDevice . BACKEND_TYPE_UDP
bind = VirtualRNGDevice . BACKEND_MODE_BIND in dev . backend_mode ( )
set_visible ( " rng-device " , not is_egd )
set_visible ( " rng-mode " , is_egd and not udp )
set_visible ( " rng-backend-type " , is_egd )
set_visible ( " rng-connect-host " , is_egd and ( udp or not bind ) )
set_visible ( " rng-connect-service " , is_egd and ( udp or not bind ) )
set_visible ( " rng-bind-host " , is_egd and ( udp or bind ) )
set_visible ( " rng-bind-service " , is_egd and ( udp or bind ) )
2013-09-23 17:39:56 +04:00
for k , prop in values . items ( ) :
val = " - "
if dev . supports_property ( prop ) :
val = getattr ( dev , prop ) or " - "
r = rewriter . get ( k )
if r :
val = r ( val )
self . widget ( k ) . set_text ( val )
2013-10-25 19:13:29 +04:00
if is_egd and not udp :
mode = VirtualRNGDevice . get_pretty_mode ( dev . backend_mode ( ) [ 0 ] )
self . widget ( " rng-mode " ) . set_text ( mode )
2008-07-31 04:38:09 +04:00
def refresh_char_page ( self ) :
2010-09-04 01:56:40 +04:00
chardev = self . get_hw_selection ( HW_LIST_COL_DEVICE )
if not chardev :
2009-11-04 21:18:14 +03:00
return
2009-06-17 02:04:29 +04:00
2013-07-16 17:14:37 +04:00
show_target_type = not ( chardev . virtual_device_type in
[ " serial " , " parallel " ] )
2013-10-05 21:33:55 +04:00
show_target_name = chardev . virtual_device_type == " channel "
2011-04-06 01:29:44 +04:00
def show_ui ( param , val = None ) :
widgetname = " char- " + param . replace ( " _ " , " - " )
2012-07-09 04:57:17 +04:00
doshow = chardev . supports_property ( param , ro = True )
2011-04-06 01:29:44 +04:00
# Exception: don't show target type for serial/parallel
if ( param == " target_type " and not show_target_type ) :
doshow = False
2013-10-05 21:33:55 +04:00
if ( param == " target_name " and not show_target_name ) :
doshow = False
2011-04-06 01:29:44 +04:00
if not val and doshow :
val = getattr ( chardev , param )
2013-09-28 20:21:35 +04:00
uihelpers . set_grid_row_visible ( self . widget ( widgetname ) , doshow )
2011-07-14 21:13:13 +04:00
self . widget ( widgetname ) . set_text ( val or " - " )
2011-04-06 01:29:44 +04:00
def build_host_str ( base ) :
if ( not chardev . supports_property ( base + " _host " ) or
not chardev . supports_property ( base + " _port " ) ) :
return " "
host = getattr ( chardev , base + " _host " ) or " "
port = getattr ( chardev , base + " _port " ) or " "
ret = str ( host )
if port :
ret + = " : %s " % str ( port )
return ret
2010-09-04 01:56:40 +04:00
char_type = chardev . virtual_device_type . capitalize ( )
2010-09-09 01:53:51 +04:00
target_port = chardev . target_port
2013-07-16 17:14:37 +04:00
dev_type = chardev . type or " pty "
2010-09-08 02:38:01 +04:00
primary = hasattr ( chardev , " virtmanager_console_dup " )
2009-12-03 18:37:57 +03:00
2010-09-13 17:31:32 +04:00
typelabel = " "
if char_type == " serial " :
typelabel = _ ( " Serial Device " )
elif char_type == " parallel " :
typelabel = _ ( " Parallel Device " )
elif char_type == " console " :
typelabel = _ ( " Console Device " )
elif char_type == " channel " :
typelabel = _ ( " Channel Device " )
else :
typelabel = _ ( " %s Device " ) % char_type . capitalize ( )
2011-04-06 01:29:44 +04:00
if target_port is not None and not show_target_type :
2010-09-04 01:56:40 +04:00
typelabel + = " %s " % ( int ( target_port ) + 1 )
2009-12-03 18:37:57 +03:00
if primary :
typelabel + = " ( %s ) " % _ ( " Primary Console " )
typelabel = " <b> %s </b> " % typelabel
2011-07-14 21:13:13 +04:00
self . widget ( " char-type " ) . set_markup ( typelabel )
self . widget ( " char-dev-type " ) . set_text ( dev_type )
2011-04-06 01:29:44 +04:00
# Device type specific properties, only show if apply to the cur dev
show_ui ( " source_host " , build_host_str ( " source " ) )
show_ui ( " bind_host " , build_host_str ( " bind " ) )
show_ui ( " source_path " )
show_ui ( " target_type " )
show_ui ( " target_name " )
2009-06-17 02:04:29 +04:00
2009-11-04 21:18:14 +03:00
def refresh_hostdev_page ( self ) :
2010-09-07 20:09:48 +04:00
hostdev = self . get_hw_selection ( HW_LIST_COL_DEVICE )
if not hostdev :
2009-11-04 21:18:14 +03:00
return
2009-06-17 02:04:29 +04:00
2010-09-07 20:09:48 +04:00
devtype = hostdev . type
pretty_name = None
2011-07-23 00:43:26 +04:00
nodedev = lookup_nodedev ( self . vm . conn , hostdev )
2010-09-07 20:09:48 +04:00
if nodedev :
pretty_name = nodedev . pretty_name ( )
2008-03-07 00:43:46 +03:00
2010-09-07 20:09:48 +04:00
if not pretty_name :
pretty_name = build_hostdev_label ( hostdev ) [ 0 ] or " - "
2008-03-07 00:43:46 +03:00
2010-09-07 20:09:48 +04:00
devlabel = " <b>Physical %s Device</b> " % devtype . upper ( )
2011-07-14 21:13:13 +04:00
self . widget ( " hostdev-title " ) . set_markup ( devlabel )
self . widget ( " hostdev-source " ) . set_text ( pretty_name )
2006-11-13 23:31:17 +03:00
2009-11-04 21:18:14 +03:00
def refresh_video_page ( self ) :
2010-09-03 23:59:33 +04:00
vid = self . get_hw_selection ( HW_LIST_COL_DEVICE )
if not vid :
2008-07-31 04:38:09 +04:00
return
2011-07-22 21:00:36 +04:00
no_default = not self . is_customize_dialog
uihelpers . populate_video_combo ( self . vm ,
2013-09-28 20:21:35 +04:00
self . widget ( " video-model " ) ,
2011-07-22 21:00:36 +04:00
no_default = no_default )
2013-07-15 19:07:40 +04:00
model = vid . model
2010-09-03 23:59:33 +04:00
ram = vid . vram
heads = vid . heads
2009-11-04 21:18:14 +03:00
try :
ramlabel = ram and " %d MB " % ( int ( ram ) / 1024 ) or " - "
except :
ramlabel = " - "
2008-07-31 04:38:09 +04:00
2011-07-14 21:13:13 +04:00
self . widget ( " video-ram " ) . set_text ( ramlabel )
2013-07-15 19:07:40 +04:00
self . widget ( " video-heads " ) . set_text ( heads and str ( heads ) or " - " )
2007-04-11 22:48:36 +04:00
2013-09-28 20:21:35 +04:00
self . set_combo_entry ( " video-model " , model ,
2012-10-29 00:32:23 +04:00
label = vid . pretty_model ( model ) )
2009-11-05 22:59:11 +03:00
2010-03-24 07:22:17 +03:00
def refresh_watchdog_page ( self ) :
2010-09-03 23:59:33 +04:00
watch = self . get_hw_selection ( HW_LIST_COL_DEVICE )
if not watch :
2010-03-24 07:22:17 +03:00
return
2010-09-03 23:59:33 +04:00
model = watch . model
action = watch . action
2010-03-24 07:22:17 +03:00
2013-09-28 20:21:35 +04:00
self . set_combo_entry ( " watchdog-model " , model )
self . set_combo_entry ( " watchdog-action " , action )
2010-03-24 07:22:17 +03:00
2010-12-16 20:41:47 +03:00
def refresh_controller_page ( self ) :
dev = self . get_hw_selection ( HW_LIST_COL_DEVICE )
if not dev :
return
type_label = virtinst . VirtualController . pretty_type ( dev . type )
2011-09-02 05:23:26 +04:00
model_label = dev . model
2013-10-04 00:34:28 +04:00
is_usb = dev . type == virtinst . VirtualController . TYPE_USB
2011-09-02 05:23:26 +04:00
if not model_label :
2011-09-23 19:14:15 +04:00
model_label = _ ( " Default " )
2011-09-02 05:23:26 +04:00
2011-07-14 21:13:13 +04:00
self . widget ( " controller-type " ) . set_text ( type_label )
2013-09-28 20:21:35 +04:00
combo = self . widget ( " controller-model " )
2013-10-04 00:34:28 +04:00
uihelpers . set_grid_row_visible ( combo , is_usb )
2011-09-23 19:14:15 +04:00
model = combo . get_model ( )
model . clear ( )
2013-07-16 05:52:18 +04:00
if dev . type == virtinst . VirtualController . TYPE_USB :
2013-10-04 00:34:28 +04:00
model . append ( [ " default " , " Default " ] )
2011-09-23 19:14:15 +04:00
model . append ( [ " ich9-ehci1 " , " USB 2 " ] )
2013-10-04 00:34:28 +04:00
model . append ( [ " nec-xhci " , " USB 3 " ] )
2011-09-23 19:14:15 +04:00
self . widget ( " config-remove " ) . set_sensitive ( False )
else :
self . widget ( " config-remove " ) . set_sensitive ( True )
2013-10-04 00:34:28 +04:00
self . set_combo_entry ( " controller-model " , dev . model or " default " )
2010-12-16 20:41:47 +03:00
2011-05-19 23:18:33 +04:00
def refresh_filesystem_page ( self ) :
dev = self . get_hw_selection ( HW_LIST_COL_DEVICE )
if not dev :
return
2011-07-14 21:13:13 +04:00
self . widget ( " fs-type " ) . set_text ( dev . type )
2012-01-13 05:28:26 +04:00
# mode can be irrelevant depending on the fs driver type
# selected.
if dev . mode :
self . show_pair ( " fs-mode " , True )
self . widget ( " fs-mode " ) . set_text ( dev . mode )
else :
self . show_pair ( " fs-mode " , False )
self . widget ( " fs-driver " ) . set_text ( dev . driver or _ ( " Default " ) )
2012-01-18 22:52:02 +04:00
self . widget ( " fs-wrpolicy " ) . set_text ( dev . wrpolicy or _ ( " Default " ) )
2013-12-02 05:48:07 +04:00
self . widget ( " fs-source " ) . set_text ( dev . source or _ ( " RAM " ) )
2011-07-14 21:13:13 +04:00
self . widget ( " fs-target " ) . set_text ( dev . target )
2011-12-22 22:10:17 +04:00
if dev . readonly :
self . widget ( " fs-readonly " ) . set_text ( " Yes " )
else :
self . widget ( " fs-readonly " ) . set_text ( " No " )
2011-05-19 23:18:33 +04:00
2009-11-04 21:18:14 +03:00
def refresh_boot_page ( self ) :
# Refresh autostart
try :
2009-12-03 18:37:57 +03:00
# Older libvirt versions return None if not supported
2009-11-04 21:18:14 +03:00
autoval = self . vm . get_autostart ( )
2009-12-03 18:37:57 +03:00
except libvirt . libvirtError :
autoval = None
2011-05-26 20:38:48 +04:00
# Autostart
2011-07-14 21:13:13 +04:00
autostart_chk = self . widget ( " config-autostart " )
2010-12-12 06:00:52 +03:00
enable_autostart = ( autoval is not None )
autostart_chk . set_sensitive ( enable_autostart )
autostart_chk . set_active ( enable_autostart and autoval or False )
2011-05-26 20:38:48 +04:00
show_kernel = not self . vm . is_container ( )
show_init = self . vm . is_container ( )
show_boot = ( not self . vm . is_container ( ) and not self . vm . is_xenpv ( ) )
2009-11-04 21:18:14 +03:00
2013-09-02 04:18:14 +04:00
self . widget ( " boot-order-align " ) . set_visible ( show_boot )
self . widget ( " boot-kernel-align " ) . set_visible ( show_kernel )
self . widget ( " boot-init-align " ) . set_visible ( show_init )
2011-05-26 20:38:48 +04:00
# Kernel/initrd boot
2013-08-18 20:25:20 +04:00
kernel , initrd , dtb , args = self . vm . get_boot_kernel_info ( )
expand = bool ( kernel or dtb or initrd or args )
def keep_text ( wname , guestval ) :
# If the user unsets kernel/initrd by unchecking the
# 'enable kernel boot' box, we keep the previous values cached
# in the text fields to allow easy switching back and forth.
guestval = guestval or " "
if self . get_text ( wname ) and not guestval :
return
self . widget ( wname ) . set_text ( guestval )
keep_text ( " boot-kernel " , kernel )
keep_text ( " boot-initrd " , initrd )
keep_text ( " boot-dtb " , dtb )
keep_text ( " boot-kernel-args " , args )
2010-12-12 07:00:19 +03:00
if expand :
2013-08-18 20:25:20 +04:00
# Only 'expand' if requested, so a refresh doesn't
# magically unexpand the UI the user just touched
2011-07-14 21:13:13 +04:00
self . widget ( " boot-kernel-expander " ) . set_expanded ( True )
2013-08-18 20:25:20 +04:00
self . widget ( " boot-kernel-enable " ) . set_active ( expand )
self . widget ( " boot-kernel-enable " ) . toggled ( )
# Only show dtb if it's supported
arch = self . vm . get_arch ( ) or " "
show_dtb = ( self . get_text ( " boot-dtb " ) or
self . vm . get_hv_type ( ) == " test " or
" arm " in arch or " microblaze " in arch or " ppc " in arch )
self . widget ( " boot-dtb-label " ) . set_visible ( show_dtb )
self . widget ( " boot-dtb-box " ) . set_visible ( show_dtb )
2010-12-12 07:00:19 +03:00
2011-05-26 20:38:48 +04:00
# <init> populate
init = self . vm . get_init ( )
2011-07-14 21:13:13 +04:00
self . widget ( " boot-init-path " ) . set_text ( init or " " )
2011-05-26 20:38:48 +04:00
# Boot menu populate
menu = self . vm . get_boot_menu ( ) or False
2011-07-14 21:13:13 +04:00
self . widget ( " boot-menu " ) . set_active ( menu )
2008-03-07 00:43:46 +03:00
self . repopulate_boot_list ( )
2007-04-12 23:36:04 +04:00
2009-11-04 21:18:14 +03:00
############################
# Hardware list population #
############################
2009-07-20 23:09:32 +04:00
2010-12-11 04:33:41 +03:00
def populate_disk_bus_combo ( self , devtype , no_default ) :
2013-09-28 20:21:35 +04:00
buslist = self . widget ( " disk-bus " )
2010-12-11 04:33:41 +03:00
busmodel = buslist . get_model ( )
busmodel . clear ( )
buses = [ ]
if devtype == virtinst . VirtualDisk . DEVICE_FLOPPY :
buses . append ( [ " fdc " , " Floppy " ] )
elif devtype == virtinst . VirtualDisk . DEVICE_CDROM :
buses . append ( [ " ide " , " IDE " ] )
2011-08-29 19:06:19 +04:00
if self . vm . rhel6_defaults ( ) :
buses . append ( [ " scsi " , " SCSI " ] )
2010-12-11 04:33:41 +03:00
else :
if self . vm . is_hvm ( ) :
buses . append ( [ " ide " , " IDE " ] )
2011-08-29 19:06:19 +04:00
if self . vm . rhel6_defaults ( ) :
buses . append ( [ " scsi " , " SCSI " ] )
buses . append ( [ " usb " , " USB " ] )
2012-01-30 00:30:41 +04:00
if self . vm . get_hv_type ( ) in [ " kvm " , " test " ] :
2011-12-22 22:18:40 +04:00
buses . append ( [ " sata " , " SATA " ] )
2010-12-11 04:33:41 +03:00
buses . append ( [ " virtio " , " Virtio " ] )
2012-02-29 12:48:18 +04:00
if ( self . vm . get_hv_type ( ) == " kvm " and
self . vm . get_machtype ( ) == " pseries " ) :
buses . append ( [ " spapr-vscsi " , " sPAPR-vSCSI " ] )
2012-01-30 00:30:41 +04:00
if self . vm . conn . is_xen ( ) or self . vm . get_hv_type ( ) == " test " :
2010-12-11 04:33:41 +03:00
buses . append ( [ " xen " , " Xen " ] )
for row in buses :
busmodel . append ( row )
if not no_default :
busmodel . append ( [ None , " default " ] )
2007-04-11 22:48:36 +04:00
def populate_hw_list ( self ) :
2011-07-14 21:13:13 +04:00
hw_list_model = self . widget ( " hw-list " ) . get_model ( )
2007-04-11 22:48:36 +04:00
hw_list_model . clear ( )
2009-07-20 23:09:32 +04:00
2013-04-17 03:17:47 +04:00
def add_hw_list_option ( title , page_id , icon_name ) :
2009-11-04 21:18:14 +03:00
hw_list_model . append ( [ title , icon_name ,
2012-05-14 17:24:56 +04:00
Gtk . IconSize . LARGE_TOOLBAR ,
2013-04-17 03:17:47 +04:00
page_id , title ] )
2009-07-20 23:09:32 +04:00
2013-04-17 03:17:47 +04:00
add_hw_list_option ( " Overview " , HW_LIST_TYPE_GENERAL , " computer " )
2010-02-07 20:18:28 +03:00
if not self . is_customize_dialog :
2013-04-17 03:17:47 +04:00
add_hw_list_option ( " Performance " , HW_LIST_TYPE_STATS ,
2010-02-07 20:18:28 +03:00
" utilities-system-monitor " )
2013-04-17 03:17:47 +04:00
add_hw_list_option ( " Processor " , HW_LIST_TYPE_CPU , " device_cpu " )
add_hw_list_option ( " Memory " , HW_LIST_TYPE_MEMORY , " device_mem " )
add_hw_list_option ( " Boot Options " , HW_LIST_TYPE_BOOT , " system-run " )
2007-04-11 22:48:36 +04:00
2009-11-04 21:18:14 +03:00
self . repopulate_hw_list ( )
2009-07-20 23:09:32 +04:00
2007-04-12 23:36:04 +04:00
def repopulate_hw_list ( self ) :
2011-07-14 21:13:13 +04:00
hw_list = self . widget ( " hw-list " )
2007-04-13 02:54:33 +04:00
hw_list_model = hw_list . get_model ( )
2007-04-11 22:48:36 +04:00
2010-09-08 02:38:01 +04:00
currentDevices = [ ]
def dev_cmp ( origdev , newdev ) :
2013-04-17 03:17:47 +04:00
if isinstance ( origdev , str ) :
2010-09-08 02:38:01 +04:00
return False
if origdev == newdev :
return True
2013-07-25 19:02:56 +04:00
if not origdev . get_root_xpath ( ) :
2010-09-08 02:38:01 +04:00
return False
2013-07-25 19:02:56 +04:00
return origdev . get_root_xpath ( ) == newdev . get_root_xpath ( )
2010-09-08 02:38:01 +04:00
def add_hw_list_option ( idx , name , page_id , info , icon_name ) :
2009-07-20 23:09:32 +04:00
hw_list_model . insert ( idx , [ name , icon_name ,
2012-05-14 17:24:56 +04:00
Gtk . IconSize . LARGE_TOOLBAR ,
2010-09-08 02:38:01 +04:00
page_id , info ] )
2009-07-20 23:09:32 +04:00
2010-09-08 02:38:01 +04:00
def update_hwlist ( hwtype , info , name , icon_name ) :
2009-07-20 23:09:32 +04:00
"""
See if passed hw is already in list , and if so , update info .
If not in list , add it !
2009-01-15 19:17:30 +03:00
"""
2010-09-08 02:38:01 +04:00
currentDevices . append ( info )
2007-04-12 23:36:04 +04:00
insertAt = 0
for row in hw_list_model :
2010-09-08 02:38:01 +04:00
rowdev = row [ HW_LIST_COL_DEVICE ]
if dev_cmp ( rowdev , info ) :
2009-07-20 23:09:32 +04:00
# Update existing HW info
2009-01-15 19:17:30 +03:00
row [ HW_LIST_COL_DEVICE ] = info
2009-12-14 01:17:56 +03:00
row [ HW_LIST_COL_LABEL ] = name
2010-09-08 02:38:01 +04:00
row [ HW_LIST_COL_ICON_NAME ] = icon_name
2009-07-20 23:09:32 +04:00
return
2007-09-26 04:05:45 +04:00
2009-01-15 19:17:30 +03:00
if row [ HW_LIST_COL_TYPE ] < = hwtype :
insertAt + = 1
2009-07-20 23:09:32 +04:00
# Add the new HW row
2010-09-08 02:38:01 +04:00
add_hw_list_option ( insertAt , name , hwtype , info , icon_name )
2009-01-15 19:17:30 +03:00
# Populate list of disks
2010-09-03 22:10:04 +04:00
for disk in self . vm . get_disk_devices ( ) :
devtype = disk . device
bus = disk . bus
idx = disk . disk_bus_index
2010-09-03 22:05:29 +04:00
2009-07-20 23:09:32 +04:00
icon = " drive-harddisk "
2010-09-03 22:05:29 +04:00
if devtype == " cdrom " :
2009-07-20 23:09:32 +04:00
icon = " media-optical "
2010-09-03 22:05:29 +04:00
elif devtype == " floppy " :
2009-07-20 23:09:32 +04:00
icon = " media-floppy "
2012-02-29 12:48:18 +04:00
if disk . address . type == " spapr-vio " :
bus = " spapr-vscsi "
2009-12-02 05:34:29 +03:00
label = prettyify_disk ( devtype , bus , idx )
2010-09-08 02:38:01 +04:00
update_hwlist ( HW_LIST_TYPE_DISK , disk , label , icon )
2007-04-12 23:36:04 +04:00
# Populate list of NICs
2010-09-03 23:19:54 +04:00
for net in self . vm . get_network_devices ( ) :
mac = net . macaddr
2010-09-03 22:05:29 +04:00
2010-09-03 23:19:54 +04:00
update_hwlist ( HW_LIST_TYPE_NIC , net ,
2010-09-08 02:38:01 +04:00
" NIC %s " % mac [ - 9 : ] , " network-idle " )
2007-04-12 23:36:04 +04:00
2007-09-26 04:05:45 +04:00
# Populate list of input devices
2010-09-03 23:59:33 +04:00
for inp in self . vm . get_input_devices ( ) :
inptype = inp . type
2010-09-03 22:05:29 +04:00
2009-07-20 23:09:32 +04:00
icon = " input-mouse "
2010-09-03 22:05:29 +04:00
if inptype == " tablet " :
2009-07-20 23:09:32 +04:00
label = _ ( " Tablet " )
icon = " input-tablet "
2010-09-03 22:05:29 +04:00
elif inptype == " mouse " :
2009-07-20 23:09:32 +04:00
label = _ ( " Mouse " )
else :
label = _ ( " Input " )
2010-09-08 02:38:01 +04:00
update_hwlist ( HW_LIST_TYPE_INPUT , inp , label , icon )
2007-09-26 04:05:45 +04:00
2007-09-27 03:39:11 +04:00
# Populate list of graphics devices
2010-09-03 23:59:33 +04:00
for gfx in self . vm . get_graphics_devices ( ) :
update_hwlist ( HW_LIST_TYPE_GRAPHICS , gfx ,
2011-03-24 17:09:42 +03:00
_ ( " Display %s " ) % gfx . pretty_type_simple ( gfx . type ) ,
2010-09-08 02:38:01 +04:00
" video-display " )
2007-09-27 03:39:11 +04:00
2008-07-31 03:52:39 +04:00
# Populate list of sound devices
2010-09-03 23:59:33 +04:00
for sound in self . vm . get_sound_devices ( ) :
update_hwlist ( HW_LIST_TYPE_SOUND , sound ,
2010-09-08 02:38:01 +04:00
_ ( " Sound: %s " % sound . model ) , " audio-card " )
2008-07-31 03:52:39 +04:00
2008-07-31 04:38:09 +04:00
# Populate list of char devices
2010-09-04 01:56:40 +04:00
for chardev in self . vm . get_char_devices ( ) :
devtype = chardev . virtual_device_type
2010-09-09 01:53:51 +04:00
port = chardev . target_port
2010-09-04 01:56:40 +04:00
2010-09-03 22:05:29 +04:00
label = devtype . capitalize ( )
2013-10-05 22:04:49 +04:00
if devtype in [ " serial " , " parallel " ] :
2010-09-03 22:05:29 +04:00
label + = " %s " % ( int ( port ) + 1 )
2013-10-05 22:04:49 +04:00
elif devtype == " channel " :
name = chardev . pretty_channel_name ( chardev . target_name )
if name :
label + = " %s " % name
2009-01-15 19:17:30 +03:00
2010-09-04 01:56:40 +04:00
update_hwlist ( HW_LIST_TYPE_CHAR , chardev , label ,
2010-09-08 02:38:01 +04:00
" device_serial " )
2008-07-31 04:38:09 +04:00
2009-01-23 01:00:38 +03:00
# Populate host devices
2010-09-07 20:09:48 +04:00
for hostdev in self . vm . get_hostdev_devices ( ) :
devtype = hostdev . type
label = build_hostdev_label ( hostdev ) [ 1 ]
2010-09-03 22:05:29 +04:00
if devtype == " usb " :
2009-07-22 20:38:56 +04:00
icon = " device_usb "
else :
icon = " device_pci "
2010-09-08 02:38:01 +04:00
update_hwlist ( HW_LIST_TYPE_HOSTDEV , hostdev , label , icon )
2009-01-23 01:00:38 +03:00
2011-09-02 05:23:27 +04:00
# Populate redir devices
for redirdev in self . vm . get_redirdev_devices ( ) :
bus = redirdev . bus
label = build_redir_label ( redirdev ) [ 1 ]
if bus == " usb " :
icon = " device_usb "
else :
icon = " device_pci "
update_hwlist ( HW_LIST_TYPE_REDIRDEV , redirdev , label , icon )
2009-07-09 22:35:55 +04:00
# Populate video devices
2010-09-03 23:59:33 +04:00
for vid in self . vm . get_video_devices ( ) :
2012-10-29 00:32:23 +04:00
update_hwlist ( HW_LIST_TYPE_VIDEO , vid ,
2013-07-15 19:07:40 +04:00
_ ( " Video %s " ) % vid . pretty_model ( vid . model ) ,
2012-10-29 00:32:23 +04:00
" video-display " )
2008-07-31 04:38:09 +04:00
2011-05-19 23:18:33 +04:00
# Populate watchdog devices
2010-09-03 23:59:33 +04:00
for watch in self . vm . get_watchdog_devices ( ) :
update_hwlist ( HW_LIST_TYPE_WATCHDOG , watch , _ ( " Watchdog " ) ,
2010-09-08 02:38:01 +04:00
" device_pci " )
2010-03-24 07:22:17 +03:00
2011-05-19 23:18:33 +04:00
# Populate controller devices
2010-12-16 20:41:47 +03:00
for cont in self . vm . get_controller_devices ( ) :
2011-09-23 19:14:15 +04:00
# skip USB2 ICH9 companion controllers
if cont . model in [ " ich9-uhci1 " , " ich9-uhci2 " , " ich9-uhci3 " ] :
continue
2010-12-16 20:41:47 +03:00
pretty_type = virtinst . VirtualController . pretty_type ( cont . type )
update_hwlist ( HW_LIST_TYPE_CONTROLLER , cont ,
_ ( " Controller %s " ) % pretty_type ,
" device_pci " )
2011-05-19 23:18:33 +04:00
# Populate filesystem devices
for fs in self . vm . get_filesystem_devices ( ) :
target = fs . target [ : 8 ]
update_hwlist ( HW_LIST_TYPE_FILESYSTEM , fs ,
_ ( " Filesystem %s " ) % target ,
2012-05-14 17:24:56 +04:00
Gtk . STOCK_DIRECTORY )
2011-05-19 23:18:33 +04:00
2011-06-23 19:42:03 +04:00
# Populate list of smartcard devices
for sc in self . vm . get_smartcard_devices ( ) :
update_hwlist ( HW_LIST_TYPE_SMARTCARD , sc ,
_ ( " Smartcard " ) , " device_serial " )
2013-06-26 05:45:08 +04:00
# Populate list of TPM devices
for tpm in self . vm . get_tpm_devices ( ) :
update_hwlist ( HW_LIST_TYPE_TPM , tpm ,
_ ( " TPM " ) , " device_cpu " )
2013-09-23 17:39:56 +04:00
# Populate list of RNG devices
for rng in self . vm . get_rng_devices ( ) :
update_hwlist ( HW_LIST_TYPE_RNG , rng ,
_ ( " RNG " ) , " system-run " )
2014-01-10 13:37:55 +04:00
# Populate list of Panic devices
for rng in self . vm . get_panic_devices ( ) :
update_hwlist ( HW_LIST_TYPE_PANIC , rng ,
_ ( " Panic Notifier " ) , " system-run " )
2007-04-13 02:54:33 +04:00
devs = range ( len ( hw_list_model ) )
devs . reverse ( )
for i in devs :
2008-11-19 01:01:22 +03:00
_iter = hw_list_model . iter_nth_child ( None , i )
2010-09-08 02:38:01 +04:00
olddev = hw_list_model [ i ] [ HW_LIST_COL_DEVICE ]
# Existing device, don't remove it
2013-04-17 21:01:30 +04:00
if type ( olddev ) is str or olddev in currentDevices :
2010-09-08 02:38:01 +04:00
continue
hw_list_model . remove ( _iter )
2007-04-13 02:54:33 +04:00
2010-02-25 04:37:41 +03:00
def repopulate_boot_list ( self , bootdevs = None , dev_select = None ) :
2011-07-14 21:13:13 +04:00
boot_list = self . widget ( " config-boot-list " )
2010-02-25 04:37:41 +03:00
boot_model = boot_list . get_model ( )
2013-04-12 00:32:00 +04:00
old_order = [ x [ BOOT_DEV_TYPE ] for x in boot_model ]
2008-03-07 00:43:46 +03:00
boot_model . clear ( )
2010-02-25 04:37:41 +03:00
2012-11-08 17:15:02 +04:00
if bootdevs is None :
2010-02-25 04:37:41 +03:00
bootdevs = self . vm . get_boot_device ( )
boot_rows = {
" hd " : [ " hd " , " Hard Disk " , " drive-harddisk " , False ] ,
" cdrom " : [ " cdrom " , " CDROM " , " media-optical " , False ] ,
" network " : [ " network " , " Network (PXE) " , " network-idle " , False ] ,
" fd " : [ " fd " , " Floppy " , " media-floppy " , False ] ,
}
for dev in bootdevs :
foundrow = None
for key , row in boot_rows . items ( ) :
if key == dev :
foundrow = row
del ( boot_rows [ key ] )
break
if not foundrow :
# Some boot device listed that we don't know about.
foundrow = [ dev , " Boot type ' %s ' " % dev ,
" drive-harddisk " , True ]
foundrow [ BOOT_ACTIVE ] = True
boot_model . append ( foundrow )
# Append all remaining boot_rows that aren't enabled
for dev in old_order :
2010-12-10 19:47:07 +03:00
if dev in boot_rows :
2010-02-25 04:37:41 +03:00
boot_model . append ( boot_rows [ dev ] )
del ( boot_rows [ dev ] )
for row in boot_rows . values ( ) :
boot_model . append ( row )
boot_list . set_model ( boot_model )
selection = boot_list . get_selection ( )
if dev_select :
idx = 0
for row in boot_model :
if row [ BOOT_DEV_TYPE ] == dev_select :
break
idx + = 1
boot_list . get_selection ( ) . select_path ( str ( idx ) )
elif not selection . get_selected ( ) [ 1 ] :
# Set a default selection
selection . select_path ( " 0 " )
2012-01-13 05:28:26 +04:00
def show_pair ( self , basename , show ) :
combo = self . widget ( basename )
label = self . widget ( basename + " -title " )
2013-09-02 04:18:14 +04:00
combo . set_visible ( show )
label . set_visible ( show )