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
2018-03-15 12:53:58 +03:00
from gi . repository import Gdk
2012-05-14 17:24:56 +04:00
from gi . repository import Gtk
2011-04-29 00:17:44 +04:00
import libvirt
2016-12-13 20:36:49 +03:00
import virtinst
from virtinst import util
from virtinst import VirtualRNGDevice
2014-09-13 00:10:45 +04:00
from . import vmmenu
from . import uiutil
from . baseclass import vmmGObjectUI
from . addhardware import vmmAddHardware
from . choosecd import vmmChooseCD
2018-03-15 01:58:22 +03:00
from . engine import vmmEngine
2014-09-13 00:10:45 +04:00
from . fsdetails import vmmFSDetails
from . gfxdetails import vmmGraphicsDetails
from . netlist import vmmNetworkList
from . snapshots import vmmSnapshotPage
from . storagebrowse import vmmStorageBrowser
from . graphwidgets import Sparkline
2007-04-11 03:07:53 +04:00
2012-02-02 20:32:29 +04:00
2014-02-04 16:03:52 +04:00
# Parameters that can be edited in the details window
2011-07-15 00:18:42 +04:00
( EDIT_NAME ,
2017-09-07 12:03:04 +03:00
EDIT_TITLE ,
EDIT_MACHTYPE ,
EDIT_FIRMWARE ,
EDIT_DESC ,
EDIT_IDMAP ,
EDIT_VCPUS ,
EDIT_MAXVCPUS ,
EDIT_CPU ,
EDIT_TOPOLOGY ,
EDIT_MEM ,
EDIT_AUTOSTART ,
EDIT_BOOTORDER ,
EDIT_BOOTMENU ,
EDIT_KERNEL ,
EDIT_INIT ,
EDIT_DISK_RO ,
EDIT_DISK_SHARE ,
EDIT_DISK_REMOVABLE ,
EDIT_DISK_CACHE ,
EDIT_DISK_IO ,
EDIT_DISK_BUS ,
EDIT_DISK_SERIAL ,
EDIT_DISK_FORMAT ,
EDIT_DISK_SGIO ,
EDIT_SOUND_MODEL ,
EDIT_SMARTCARD_MODE ,
EDIT_NET_MODEL ,
EDIT_NET_VPORT ,
EDIT_NET_SOURCE ,
EDIT_NET_MAC ,
EDIT_GFX_PASSWD ,
EDIT_GFX_TYPE ,
EDIT_GFX_KEYMAP ,
EDIT_GFX_LISTEN ,
EDIT_GFX_ADDRESS ,
EDIT_GFX_TLSPORT ,
EDIT_GFX_PORT ,
EDIT_GFX_OPENGL ,
EDIT_GFX_RENDERNODE ,
EDIT_VIDEO_MODEL ,
EDIT_VIDEO_3D ,
EDIT_WATCHDOG_MODEL ,
EDIT_WATCHDOG_ACTION ,
EDIT_CONTROLLER_MODEL ,
EDIT_TPM_TYPE ,
EDIT_FS ,
EDIT_HOSTDEV_ROMBAR ) = range ( 1 , 49 )
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 ,
2014-01-26 23:07:35 +04:00
HW_LIST_TYPE_INSPECTION ,
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_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 ,
2014-01-26 23:07:35 +04:00
HW_LIST_TYPE_PANIC ) = range ( 22 )
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
2014-02-10 01:21:26 +04:00
( BOOT_KEY ,
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_LABEL ,
BOOT_ICON ,
2014-02-10 01:21:26 +04:00
BOOT_ACTIVE ,
BOOT_CAN_SELECT ) = range ( 5 )
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
2015-04-09 20:11:20 +03:00
_remove_tooltip = _ ( " Remove this device from the virtual machine " )
2013-04-13 22:34:52 +04:00
2015-08-03 19:52:07 +03:00
def _label_for_device ( dev ) :
2014-02-10 00:20:41 +04:00
devtype = dev . virtual_device_type
if devtype == " disk " :
2015-08-03 19:52:07 +03:00
busstr = virtinst . VirtualDisk . pretty_disk_bus ( dev . bus ) or " "
2015-04-05 03:01:03 +03:00
2014-02-10 00:20:41 +04:00
if dev . device == " floppy " :
2015-09-22 02:16:31 +03:00
devstr = _ ( " Floppy " )
2014-02-10 00:20:41 +04:00
busstr = " "
elif dev . device == " cdrom " :
2015-09-22 02:16:31 +03:00
devstr = _ ( " CDROM " )
elif dev . device == " disk " :
devstr = _ ( " Disk " )
2014-02-10 00:20:41 +04:00
else :
devstr = dev . device . capitalize ( )
if busstr :
ret = " %s %s " % ( busstr , devstr )
else :
ret = devstr
return " %s %s " % ( ret , dev . disk_bus_index )
if devtype == " interface " :
details: do not show MAC address if not set
Fixes this exception:
Traceback (most recent call last):
File "virt-manager/virtManager/create.py", line 1780, in finish
self.customize(guest)
File "virt-manager/virtManager/create.py", line 1812, in customize
self.config_window = vmmDetails(virtinst_guest, self.topwin)
File "virt-manager/virtManager/details.py", line 560, in __init__
self.populate_hw_list()
File "virt-manager/virtManager/details.py", line 3165, in populate_hw_list
self.repopulate_hw_list()
File "virt-manager/virtManager/details.py", line 3220, in repopulate_hw_list
update_hwlist(HW_LIST_TYPE_NIC, dev)
File "virt-manager/virtManager/details.py", line 3195, in update_hwlist
label = _label_for_device(dev)
File "virt-manager/virtManager/details.py", line 188, in _label_for_device
return "NIC %s" % dev.macaddr[-9:]
TypeError: 'NoneType' object has no attribute '__getitem__'
Closes: https://bugzilla.redhat.com/show_bug.cgi?id=1164123
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
2014-11-14 11:45:07 +03:00
if dev . macaddr :
return " NIC %s " % dev . macaddr [ - 9 : ]
else :
return " NIC "
2014-02-10 00:20:41 +04:00
if devtype == " input " :
if dev . type == " tablet " :
return _ ( " Tablet " )
elif dev . type == " mouse " :
return _ ( " Mouse " )
2014-05-04 21:23:54 +04:00
elif dev . type == " keyboard " :
return _ ( " Keyboard " )
2014-02-10 00:20:41 +04:00
return _ ( " Input " )
if devtype in [ " serial " , " parallel " , " console " ] :
2015-09-22 02:16:31 +03:00
if devtype == " serial " :
label = _ ( " Serial " )
elif devtype == " parallel " :
label = _ ( " Parallel " )
elif devtype == " console " :
label = _ ( " Console " )
2014-02-10 00:20:41 +04:00
if dev . target_port is not None :
label + = " %s " % ( int ( dev . target_port ) + 1 )
return label
if devtype == " channel " :
2015-09-22 02:16:31 +03:00
label = _ ( " Channel " )
2014-02-10 00:20:41 +04:00
name = dev . pretty_channel_name ( dev . target_name )
2015-11-11 14:41:36 +03:00
if not name :
name = dev . pretty_type ( dev . type )
2014-02-10 00:20:41 +04:00
if name :
label + = " %s " % name
return label
if devtype == " graphics " :
return _ ( " Display %s " ) % dev . pretty_type_simple ( dev . type )
if devtype == " redirdev " :
2014-09-20 18:23:19 +04:00
return _ ( " %s Redirector %s " ) % ( dev . bus . upper ( ) , dev . vmmindex + 1 )
2014-02-10 00:20:41 +04:00
if devtype == " hostdev " :
2014-09-20 22:56:57 +04:00
return dev . pretty_name ( )
2014-02-10 00:20:41 +04:00
if devtype == " sound " :
2018-01-21 01:25:40 +03:00
return _ ( " Sound %s " ) % dev . model
2014-02-10 00:20:41 +04:00
if devtype == " video " :
return _ ( " Video %s " ) % dev . pretty_model ( dev . model )
if devtype == " filesystem " :
return _ ( " Filesystem %s " ) % dev . target [ : 8 ]
if devtype == " controller " :
2017-11-06 15:52:04 +03:00
return _ ( " Controller %s %s " ) % ( dev . pretty_desc ( ) , dev . index )
2017-03-09 01:48:26 +03:00
if devtype == " rng " :
label = _ ( " RNG " )
if dev . device :
label + = ( " %s " % dev . device )
return label
if devtype == " tpm " :
label = _ ( " TPM " )
if dev . device_path :
label + = ( " %s " % dev . device_path )
return label
2014-02-10 00:20:41 +04:00
devmap = {
" panic " : _ ( " Panic Notifier " ) ,
" smartcard " : _ ( " Smartcard " ) ,
" watchdog " : _ ( " Watchdog " ) ,
}
return devmap [ devtype ]
def _icon_for_device ( dev ) :
devtype = dev . virtual_device_type
if devtype == " disk " :
if dev . device == " cdrom " :
return " media-optical "
elif dev . device == " floppy " :
return " media-floppy "
return " drive-harddisk "
if devtype == " input " :
2015-04-09 20:36:40 +03:00
if dev . type == " keyboard " :
return " input-keyboard "
2014-02-10 00:20:41 +04:00
if dev . type == " tablet " :
return " input-tablet "
return " input-mouse "
if devtype == " redirdev " :
if dev . bus == " usb " :
return " device_usb "
return " device_pci "
if devtype == " hostdev " :
if dev . type == " usb " :
return " device_usb "
return " device_pci "
typemap = {
" interface " : " network-idle " ,
" graphics " : " video-display " ,
" serial " : " device_serial " ,
" parallel " : " device_serial " ,
" console " : " device_serial " ,
" channel " : " device_serial " ,
" video " : " video-display " ,
" watchdog " : " device_pci " ,
" sound " : " audio-card " ,
" rng " : " system-run " ,
" tpm " : " device_cpu " ,
" smartcard " : " device_serial " ,
2014-10-04 15:45:50 +04:00
" filesystem " : " folder " ,
2014-02-10 00:20:41 +04:00
" controller " : " device_pci " ,
" panic " : " system-run " ,
}
return typemap [ devtype ]
2014-06-01 04:13:08 +04:00
def _chipset_label_from_machine ( machine ) :
if machine and " q35 " in machine :
return " Q35 "
return " i440FX "
2014-10-27 19:04:57 +03:00
def _warn_cpu_thread_topo ( threads , cpu_model ) :
if ( threads < 2 ) :
return False
2014-10-28 02:20:20 +03:00
2014-10-27 19:04:57 +03:00
non_ht_cpus = [ " athlon " , " phenom " , " opteron " ]
for cpu in non_ht_cpus :
if ( cpu in cpu_model . lower ( ) ) :
return True
return False
2014-10-28 02:20:20 +03:00
2017-02-08 18:55:34 +03:00
def _label_for_os_type ( os_type ) :
typemap = {
" dos " : _ ( " MS-DOS/FreeDOS " ) ,
" freebsd " : _ ( " FreeBSD " ) ,
" hurd " : _ ( " GNU/Hurd " ) ,
" linux " : _ ( " Linux " ) ,
" minix " : _ ( " MINIX " ) ,
" netbsd " : _ ( " NetBSD " ) ,
" openbsd " : _ ( " OpenBSD " ) ,
" windows " : _ ( " Microsoft Windows " ) ,
}
try :
return typemap [ os_type ]
except KeyError :
return _ ( " unknown " )
2010-12-09 01:26:19 +03:00
class vmmDetails ( vmmGObjectUI ) :
2012-05-14 17:24:56 +04:00
__gsignals__ = {
2018-03-15 15:10:09 +03:00
" customize-finished " : ( vmmGObjectUI . RUN_FIRST , None , [ ] ) ,
2018-03-16 03:54:45 +03:00
" closed " : ( vmmGObjectUI . RUN_FIRST , None , [ ] ) ,
2012-05-14 17:24:56 +04:00
}
2018-03-15 12:53:58 +03:00
@classmethod
def get_instance ( cls , parentobj , vm ) :
try :
# Maintain one dialog per VM
connkey = vm . get_connkey ( )
if connkey not in cls . _instances :
cls . _instances [ connkey ] = cls ( vm )
return cls . _instances [ connkey ]
except Exception as e :
2018-03-17 01:58:11 +03:00
if not parentobj :
raise
2018-03-15 12:53:58 +03:00
parentobj . err . show_err (
_ ( " Error launching details: %s " ) % str ( e ) )
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
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 )
2018-03-15 14:43:56 +03:00
else :
self . conn . connect ( " vm-removed " , self . _vm_removed )
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 . ignoreDetails = False
2006-06-14 18:59:40 +04:00
2014-09-13 00:10:45 +04:00
from . 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
2014-01-27 20:03:59 +04:00
self . fsDetails = vmmFSDetails ( self . vm , self . builder , self . topwin )
self . widget ( " fs-alignment " ) . add ( self . fsDetails . top_box )
self . fsDetails . connect ( " changed " ,
lambda * x : self . enable_apply ( x , EDIT_FS ) )
2014-01-29 03:44:40 +04:00
self . gfxdetails = vmmGraphicsDetails (
self . vm , self . builder , self . topwin )
self . widget ( " graphics-align " ) . add ( self . gfxdetails . top_box )
self . gfxdetails . connect ( " changed-type " ,
lambda * x : self . enable_apply ( x , EDIT_GFX_TYPE ) )
self . gfxdetails . connect ( " changed-port " ,
lambda * x : self . enable_apply ( x , EDIT_GFX_PORT ) )
2017-02-21 16:00:56 +03:00
self . gfxdetails . connect ( " changed-opengl " ,
lambda * x : self . enable_apply ( x , EDIT_GFX_OPENGL ) )
2017-02-21 16:01:01 +03:00
self . gfxdetails . connect ( " changed-rendernode " ,
lambda * x : self . enable_apply ( x , EDIT_GFX_RENDERNODE ) )
2014-01-29 03:44:40 +04:00
self . gfxdetails . connect ( " changed-tlsport " ,
lambda * x : self . enable_apply ( x , EDIT_GFX_TLSPORT ) )
2017-02-21 16:00:59 +03:00
self . gfxdetails . connect ( " changed-listen " ,
lambda * x : self . enable_apply ( x , EDIT_GFX_LISTEN ) )
2014-01-29 03:44:40 +04:00
self . gfxdetails . connect ( " changed-address " ,
lambda * x : self . enable_apply ( x , EDIT_GFX_ADDRESS ) )
self . gfxdetails . connect ( " changed-keymap " ,
lambda * x : self . enable_apply ( x , EDIT_GFX_KEYMAP ) )
self . gfxdetails . connect ( " changed-password " ,
lambda * x : self . enable_apply ( x , EDIT_GFX_PASSWD ) )
2014-01-28 01:58:45 +04:00
self . netlist = vmmNetworkList ( self . conn , self . builder , self . topwin )
self . widget ( " network-source-label-align " ) . add ( self . netlist . top_label )
self . widget ( " network-source-ui-align " ) . add ( self . netlist . top_box )
self . widget ( " network-vport-align " ) . add ( self . netlist . top_vport )
self . netlist . connect ( " changed " ,
lambda x : self . enable_apply ( x , EDIT_NET_SOURCE ) )
self . netlist . connect ( " changed-vport " ,
lambda x : self . enable_apply ( x , EDIT_NET_VPORT ) )
2009-11-29 04:07:01 +03:00
# Set default window size
w , h = self . vm . get_details_window_size ( )
2014-02-28 23:36:13 +04:00
if w < = 0 :
w = 800
if h < = 0 :
h = 600
self . topwin . set_default_size ( w , h )
2015-09-13 21:07:43 +03:00
self . _window_size = None
2009-11-29 04:07:01 +03:00
2013-04-17 03:17:47 +04:00
self . oldhwkey = None
2010-02-12 22:01:59 +03:00
self . addhwmenu = None
2014-03-27 15:40:42 +04:00
self . _addhwmenuitems = None
2018-03-15 14:43:56 +03:00
self . _shutdownmenu = None
self . _vmmenu = 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 ,
2015-05-03 23:53:43 +03:00
" on_vmm_details_delete_event " : self . _window_delete_event ,
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 ,
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 ,
2015-05-03 23:53:43 +03:00
" on_details_cancel_customize_clicked " : self . _customize_cancel_clicked ,
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 ,
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 ) ,
2012-05-14 17:24:56 +04:00
" on_machine_type_changed " : lambda * x : self . enable_apply ( x , EDIT_MACHTYPE ) ,
2014-09-18 01:25:03 +04:00
" on_overview_firmware_changed " : lambda * x : self . enable_apply ( x , EDIT_FIRMWARE ) ,
2014-06-01 04:13:08 +04:00
" on_overview_chipset_changed " : lambda * x : self . enable_apply ( x , EDIT_MACHTYPE ) ,
2014-02-21 14:13:11 +04:00
" on_idmap_uid_target_changed " : lambda * x : self . enable_apply ( x , EDIT_IDMAP ) ,
" on_idmap_uid_count_changed " : lambda * x : self . enable_apply ( x , EDIT_IDMAP ) ,
" on_idmap_gid_target_changed " : lambda * x : self . enable_apply ( x , EDIT_IDMAP ) ,
" on_idmap_gid_count_changed " : lambda * x : self . enable_apply ( x , EDIT_IDMAP ) ,
2015-09-14 01:01:39 +03:00
" on_idmap_check_toggled " : self . config_idmap_enable ,
2010-02-25 04:37:41 +03:00
2017-02-23 13:22:27 +03:00
" on_details_inspection_refresh_clicked " : self . inspection_refresh ,
2015-09-14 01:01:39 +03:00
" on_cpu_vcpus_changed " : self . config_vcpus_changed ,
" on_cpu_maxvcpus_changed " : self . config_maxvcpus_changed ,
2014-10-27 19:04:57 +03:00
" on_cpu_model_changed " : lambda * x : self . config_cpu_model_changed ( x ) ,
2014-01-31 22:40:09 +04:00
" on_cpu_copy_host_clicked " : self . on_cpu_copy_host_clicked ,
2014-02-01 18:14:55 +04:00
" on_cpu_cores_changed " : self . config_cpu_topology_changed ,
" on_cpu_sockets_changed " : self . config_cpu_topology_changed ,
" on_cpu_threads_changed " : self . config_cpu_topology_changed ,
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
2015-09-14 01:01:39 +03:00
" on_mem_memory_changed " : self . config_memory_changed ,
" on_mem_maxmem_changed " : self . config_maxmem_changed ,
2010-02-25 04:37:41 +03:00
2013-08-18 20:25:20 +04:00
2015-09-14 01:01:39 +03:00
" on_boot_list_changed " : self . config_bootdev_selected ,
2017-08-05 09:39:32 +03:00
" on_boot_moveup_clicked " : lambda * x : self . config_boot_move ( x , True ) ,
" on_boot_movedown_clicked " : lambda * x : self . config_boot_move ( x , False ) ,
2015-09-14 01:01:39 +03:00
" on_boot_autostart_changed " : lambda * x : self . enable_apply ( x , x , EDIT_AUTOSTART ) ,
2012-05-14 17:24:56 +04:00
" 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 ) ,
2014-06-01 01:34:23 +04:00
" on_boot_init_args_changed " : lambda * x : self . enable_apply ( x , EDIT_INIT ) ,
2012-05-14 17:24:56 +04:00
2015-09-14 01:01:39 +03:00
" on_disk_cdrom_connect_clicked " : self . toggle_storage_media ,
2012-05-14 17:24:56 +04:00
" 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 ) ,
2014-04-22 01:04:33 +04:00
" on_disk_format_changed " : self . disk_format_changed ,
2012-05-14 17:24:56 +04:00
" on_disk_serial_changed " : lambda * x : self . enable_apply ( x , EDIT_DISK_SERIAL ) ,
2015-03-13 16:39:47 +03:00
" on_disk_sgio_entry_changed " : lambda * x : self . enable_apply ( x , EDIT_DISK_SGIO ) ,
2013-02-17 17:40:37 +04:00
2012-05-14 17:24:56 +04:00
" on_network_model_combo_changed " : lambda * x : self . enable_apply ( x , EDIT_NET_MODEL ) ,
2015-04-08 01:52:35 +03:00
" on_network_mac_entry_changed " : lambda * x : self . enable_apply ( x ,
EDIT_NET_MAC ) ,
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 ) ,
2017-02-21 16:01:02 +03:00
" on_video_model_combo_changed " : self . video_model_changed ,
" on_video_3d_toggled " : self . video_3d_toggled ,
2011-07-15 00:18:42 +04:00
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
2014-02-10 23:24:22 +04:00
" on_hostdev_rombar_toggled " : lambda * x : self . enable_apply (
x , EDIT_HOSTDEV_ROMBAR ) ,
2015-04-04 04:34:03 +03:00
" on_controller_model_combo_changed " : ( lambda * x :
self . enable_apply ( x , EDIT_CONTROLLER_MODEL ) ) ,
2014-02-10 23:24:22 +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
" 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
2015-04-04 04:34:03 +03:00
" on_details_menu_view_fullscreen_activate " : (
self . console . details_toggle_fullscreen ) ,
" on_details_menu_view_size_to_vm_activate " : (
self . console . details_size_to_vm ) ,
" on_details_menu_view_scale_always_toggled " : (
self . console . details_scaling_ui_changed_cb ) ,
" on_details_menu_view_scale_fullscreen_toggled " : (
self . console . details_scaling_ui_changed_cb ) ,
" on_details_menu_view_scale_never_toggled " : (
self . console . details_scaling_ui_changed_cb ) ,
" on_details_menu_view_resizeguest_toggled " : (
self . console . details_resizeguest_ui_changed_cb ) ,
" on_console_pages_switch_page " : (
self . console . details_page_changed ) ,
" on_console_auth_password_activate " : (
self . console . details_auth_login ) ,
" on_console_auth_login_clicked " : (
self . console . details_auth_login ) ,
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
2015-04-10 01:02:42 +03:00
self . vm . connect ( " state-changed " , self . refresh_vm_state )
2006-06-15 02:42:04 +04:00
self . vm . connect ( " resources-sampled " , self . refresh_resources )
2017-02-23 13:22:26 +03:00
self . vm . connect ( " inspection-changed " , lambda * x : self . refresh_inspection_page ( ) )
2007-04-11 22:48:36 +04:00
2009-11-04 21:18:14 +03:00
self . populate_hw_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
2018-03-15 14:43:56 +03:00
@property
def conn ( self ) :
return self . vm . conn
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
2018-03-15 14:43:56 +03:00
self . _shutdownmenu . destroy ( )
self . _shutdownmenu = None
self . _vmmenu . destroy ( )
self . _vmmenu = None
2011-06-20 04:49:41 +04:00
2015-09-13 21:07:43 +03:00
if self . _window_size :
self . vm . set_details_window_size ( * self . _window_size )
2018-03-15 14:43:56 +03:00
self . conn . disconnect_by_obj ( self )
2011-07-24 05:16:54 +04:00
self . vm = None
self . addhwmenu = None
2014-03-27 15:40:42 +04:00
self . _addhwmenuitems = None
2008-04-08 22:30:47 +04:00
2014-01-29 03:44:40 +04:00
self . gfxdetails . cleanup ( )
self . gfxdetails = None
2014-01-21 13:05:31 +04:00
self . fsDetails . cleanup ( )
2014-01-28 01:58:45 +04:00
self . fsDetails = None
self . netlist . cleanup ( )
self . netlist = None
2014-01-21 13:05:31 +04:00
2018-03-15 14:43:56 +03:00
def show ( self , default_page = False ) :
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 ( )
2018-03-15 14:43:56 +03:00
if not vis and default_page :
2018-03-15 12:53:58 +03:00
self . activate_default_page ( )
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
2018-03-15 02:06:30 +03:00
vmmEngine . get_instance ( ) . increment_window_counter ( )
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
2015-11-22 03:25:02 +03:00
self . emit ( " customize-finished " )
2011-07-19 05:31:06 +04:00
2018-03-15 14:43:56 +03:00
def _vm_removed ( self , _conn , connkey ) :
if self . vm . get_connkey ( ) == connkey :
self . cleanup ( )
2015-05-03 23:53:43 +03:00
def _customize_cancel ( self ) :
logging . debug ( " Asking to cancel customization " )
result = self . err . yes_no (
_ ( " This will abort the installation. Are you sure? " ) )
if not result :
logging . debug ( " Customize cancel aborted " )
return
logging . debug ( " Canceling customization " )
return self . _close ( )
def _customize_cancel_clicked ( self , src ) :
ignore = src
return self . _customize_cancel ( )
def _window_delete_event ( self , ignore1 = None , ignore2 = None ) :
2015-11-22 03:25:02 +03:00
return self . close ( )
2015-05-03 23:53:43 +03:00
2010-02-07 20:18:28 +03:00
def close ( self , ignore1 = None , ignore2 = None ) :
2015-11-22 03:25:02 +03:00
if self . is_visible ( ) :
logging . debug ( " Closing VM details: %s " , self . vm )
2011-07-19 05:31:06 +04:00
return self . _close ( )
2015-11-22 03:25:02 +03:00
def _close ( self ) :
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 ( )
2015-04-04 04:34:03 +03:00
if self . console . details_viewer_is_visible ( ) :
2009-11-04 21:18:14 +03:00
try :
2015-04-04 04:34:03 +03:00
self . console . details_close_viewer ( )
2017-07-24 11:26:48 +03:00
except Exception :
2010-12-22 04:13:11 +03:00
logging . error ( " Failure when disconnecting from desktop server " )
2010-02-07 20:18:28 +03:00
2018-03-16 03:54:45 +03:00
self . emit ( " closed " )
2018-03-15 02:06:30 +03:00
vmmEngine . get_instance ( ) . decrement_window_counter ( )
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
2018-03-15 14:43:56 +03:00
self . _shutdownmenu = vmmenu . VMShutdownMenu ( self , lambda : self . vm )
self . widget ( " control-shutdown " ) . set_menu ( self . _shutdownmenu )
2013-09-22 21:24:59 +04:00
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 ( )
2018-03-15 14:43:56 +03:00
self . _vmmenu = vmmenu . VMActionMenu (
self , lambda : self . vm , show_open = False )
2013-09-22 23:44:58 +04:00
for child in submenu . get_children ( ) :
submenu . remove ( child )
2018-03-15 14:43:56 +03:00
self . _vmmenu . add ( child )
topmenu . set_submenu ( self . _vmmenu )
2013-09-22 23:44:58 +04:00
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
2014-02-26 00:57:38 +04:00
addHW = Gtk . ImageMenuItem . new_with_label ( _ ( " _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
2014-02-26 00:57:38 +04:00
rmHW = Gtk . ImageMenuItem . new_with_label ( _ ( " _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 )
2017-08-05 09:39:32 +03:00
self . _addhwmenuitems = { " add " : addHW , " remove " : rmHW }
2017-10-11 14:35:46 +03:00
for i in list ( self . _addhwmenuitems . values ( ) ) :
2014-03-27 15:40:42 +04:00
self . addhwmenu . add ( i )
2010-02-12 22:01:59 +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 ( " details-menu-view-toolbar " ) . set_active (
self . config . get_details_show_toolbar ( ) )
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
2016-02-05 18:18:16 +03: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 )
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 )
2015-04-10 20:04:02 +03:00
uiutil . init_combo_text_column ( machtype_combo , 0 )
2013-09-02 03:21:21 +04:00
machtype_model . set_sort_column_id ( 0 , Gtk . SortType . ASCENDING )
2012-01-05 13:35:40 +04:00
2014-06-01 04:13:08 +04:00
machines = [ ]
try :
2015-04-04 00:24:32 +03:00
capsinfo = caps . guest_lookup (
2014-06-01 04:13:08 +04:00
os_type = self . vm . get_abi_type ( ) ,
arch = self . vm . get_arch ( ) ,
typ = self . vm . get_hv_type ( ) ,
machine = self . vm . get_machtype ( ) )
2015-04-04 00:24:32 +03:00
machines = capsinfo . machines [ : ]
2017-07-24 11:26:48 +03:00
except Exception :
2014-06-01 04:13:08 +04:00
logging . exception ( " Error determining machine list " )
2015-09-06 00:32:03 +03:00
show_machine = ( arch not in [ " i686 " , " x86_64 " ] )
2015-02-22 01:54:15 +03:00
uiutil . set_grid_row_visible ( self . widget ( " machine-type-title " ) ,
show_machine )
2013-09-28 20:21:35 +04:00
if show_machine :
2013-09-02 03:21:21 +04:00
for machine in machines :
if machine == " none " :
continue
machtype_model . append ( [ machine ] )
2012-01-05 13:35:40 +04:00
2015-02-22 01:54:15 +03:00
self . widget ( " machine-type " ) . set_visible ( self . is_customize_dialog )
self . widget ( " machine-type-label " ) . set_visible (
not self . is_customize_dialog )
2014-09-18 01:25:03 +04:00
# Firmware
combo = self . widget ( " overview-firmware " )
2015-02-22 19:13:21 +03:00
# [label, path, is_sensitive]
2014-09-18 01:25:03 +04:00
model = Gtk . ListStore ( str , str , bool )
combo . set_model ( model )
text = Gtk . CellRendererText ( )
combo . pack_start ( text , True )
combo . add_attribute ( text , " text " , 0 )
combo . add_attribute ( text , " sensitive " , 2 )
domcaps = self . vm . get_domain_capabilities ( )
2015-02-22 19:13:21 +03:00
uefipaths = [ v . value for v in domcaps . os . loader . values ]
2014-09-18 01:25:03 +04:00
warn_icon = self . widget ( " overview-firmware-warn " )
2015-02-18 23:16:48 +03:00
hv_supports_uefi = domcaps . supports_uefi_xml ( )
2014-09-18 01:25:03 +04:00
if not hv_supports_uefi :
warn_icon . set_tooltip_text (
_ ( " Libvirt or hypervisor does not support UEFI. " ) )
2015-02-22 19:13:21 +03:00
elif not uefipaths :
2014-09-18 01:25:03 +04:00
warn_icon . set_tooltip_text (
_ ( " Libvirt did not detect any UEFI/OVMF firmware image "
" installed on the host. " ) )
2015-02-22 19:13:21 +03:00
model . append ( [ domcaps . label_for_firmware_path ( None ) , None , True ] )
if not uefipaths :
model . append ( [ _ ( " UEFI not found " ) , None , False ] )
else :
for path in uefipaths :
model . append ( [ domcaps . label_for_firmware_path ( path ) ,
path , True ] )
2014-09-18 01:25:03 +04:00
combo . set_active ( 0 )
self . widget ( " overview-firmware-warn " ) . set_visible (
2015-02-22 19:13:21 +03:00
not ( uefipaths and hv_supports_uefi ) and self . is_customize_dialog )
2014-09-18 01:25:03 +04:00
self . widget ( " overview-firmware " ) . set_visible ( self . is_customize_dialog )
self . widget ( " overview-firmware-label " ) . set_visible (
not self . is_customize_dialog )
2016-06-16 13:03:42 +03:00
show_firmware = ( ( self . conn . is_qemu ( ) or
2017-06-27 21:13:36 +03:00
self . conn . is_test ( ) or
2016-06-16 13:03:42 +03:00
self . conn . is_xen ( ) ) and
domcaps . arch_can_uefi ( ) )
2014-09-18 01:25:03 +04:00
uiutil . set_grid_row_visible (
self . widget ( " overview-firmware-title " ) , show_firmware )
2014-06-01 04:13:08 +04:00
# Chipset
combo = self . widget ( " overview-chipset " )
model = Gtk . ListStore ( str , str )
combo . set_model ( model )
model . append ( [ _chipset_label_from_machine ( " pc " ) , " pc " ] )
if " q35 " in machines :
model . append ( [ _chipset_label_from_machine ( " q35 " ) , " q35 " ] )
combo . set_active ( 0 )
self . widget ( " overview-chipset " ) . set_visible ( self . is_customize_dialog )
self . widget ( " overview-chipset-label " ) . set_visible (
not self . is_customize_dialog )
2017-06-27 21:13:36 +03:00
show_chipset = ( ( self . conn . is_qemu ( ) or self . conn . is_test ( ) ) and
2015-09-06 00:32:03 +03:00
arch in [ " i686 " , " x86_64 " ] )
2014-06-01 04:13:08 +04:00
uiutil . set_grid_row_visible (
self . widget ( " overview-chipset-title " ) , show_chipset )
2014-01-26 23:07:35 +04:00
# Inspection page
apps_list = self . widget ( " inspection-apps " )
apps_model = Gtk . ListStore ( str , str , str )
apps_list . set_model ( apps_model )
name_col = Gtk . TreeViewColumn ( _ ( " Name " ) )
version_col = Gtk . TreeViewColumn ( _ ( " Version " ) )
summary_col = Gtk . TreeViewColumn ( )
apps_list . append_column ( name_col )
apps_list . append_column ( version_col )
apps_list . append_column ( summary_col )
name_text = Gtk . CellRendererText ( )
name_col . pack_start ( name_text , True )
name_col . add_attribute ( name_text , ' text ' , 0 )
name_col . set_sort_column_id ( 0 )
version_text = Gtk . CellRendererText ( )
version_col . pack_start ( version_text , True )
version_col . add_attribute ( version_text , ' text ' , 1 )
version_col . set_sort_column_id ( 1 )
summary_text = Gtk . CellRendererText ( )
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:18:14 +03:00
# Boot device list
2015-09-14 01:01:39 +03:00
boot_list = self . widget ( " boot-list " )
2014-02-10 01:21:26 +04:00
# [XML boot type, display name, icon name, enabled, can select]
boot_list_model = Gtk . ListStore ( str , str , str , bool , 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 )
2014-02-10 01:21:26 +04:00
chkCol . add_attribute ( chk , ' visible ' , BOOT_CAN_SELECT )
2010-02-25 04:37:41 +03:00
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
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
2014-01-31 22:40:09 +04:00
def sep_func ( model , it , ignore ) :
return model [ it ] [ 3 ]
# [label, sortkey, idstring, is sep]
model = Gtk . ListStore ( str , str , str , bool )
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 )
2014-01-31 22:40:09 +04:00
cpu_model . set_row_separator_func ( sep_func , None )
2014-02-02 01:36:40 +04:00
model . set_sort_column_id ( 1 , Gtk . SortType . ASCENDING )
2014-01-31 22:40:09 +04:00
model . append ( [ _ ( " Application Default " ) , " 1 " , " appdefault " , False ] )
2014-02-05 22:51:53 +04:00
model . append ( [ _ ( " Hypervisor Default " ) , " 2 " ,
virtinst . CPU . SPECIAL_MODE_HV_DEFAULT , False ] )
model . append ( [ _ ( " Clear CPU configuration " ) , " 3 " ,
virtinst . CPU . SPECIAL_MODE_CLEAR , False ] )
2014-01-31 22:40:09 +04:00
model . append ( [ None , None , None , True ] )
2017-07-17 18:29:54 +03:00
for name in caps . get_cpu_values ( self . vm . get_arch ( ) ) :
2014-01-31 22:40:09 +04:00
model . append ( [ name , name , name , False ] )
2010-12-17 03:36:07 +03:00
2015-04-09 20:11:20 +03:00
# Remove button tooltip
self . widget ( " config-remove " ) . set_tooltip_text ( _remove_tooltip )
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 " )
2014-01-27 02:09:07 +04:00
vmmAddHardware . build_disk_cache_combo ( self . vm , disk_cache )
2010-05-20 16:34:32 +04:00
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 " )
2014-01-27 02:09:07 +04:00
vmmAddHardware . build_disk_io_combo ( self . vm , disk_io )
2011-07-24 04:41:35 +04: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 " )
2014-01-27 02:09:07 +04:00
vmmAddHardware . build_disk_bus_combo ( self . vm , disk_bus )
2010-12-11 04:33:41 +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 " )
2014-01-27 02:09:07 +04:00
vmmAddHardware . build_network_model_combo ( self . vm , net_model )
2010-03-24 05:15:53 +03:00
2015-04-08 01:52:35 +03:00
# Network mac
self . widget ( " network-mac-label " ) . set_visible (
not self . is_customize_dialog )
self . widget ( " network-mac-entry " ) . set_visible ( self . is_customize_dialog )
2010-03-24 05:15:53 +03:00
# Sound model
2013-09-28 20:21:35 +04:00
sound_dev = self . widget ( " sound-model " )
2015-05-19 23:44:08 +03:00
vmmAddHardware . build_sound_combo ( self . vm , sound_dev )
2010-03-24 05:15:53 +03:00
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 " )
2015-05-19 23:44:08 +03:00
vmmAddHardware . build_video_combo ( self . vm , video_dev )
2010-03-24 05:15:53 +03:00
2010-03-24 07:22:17 +03:00
# Watchdog model combo
2013-09-28 20:21:35 +04:00
combo = self . widget ( " watchdog-model " )
2015-05-19 23:44:08 +03:00
vmmAddHardware . build_watchdogmodel_combo ( self . vm , combo )
2010-03-24 07:22:17 +03:00
# Watchdog action combo
2013-09-28 20:21:35 +04:00
combo = self . widget ( " watchdog-action " )
2015-05-19 23:44:08 +03:00
vmmAddHardware . build_watchdogaction_combo ( self . vm , combo )
2010-03-24 07:22:17 +03:00
2011-06-23 19:42:03 +04:00
# Smartcard mode
2013-09-28 20:21:35 +04:00
sc_mode = self . widget ( " smartcard-mode " )
2014-01-27 02:09:07 +04:00
vmmAddHardware . build_smartcard_mode_combo ( self . vm , sc_mode )
2011-06-23 19:42:03 +04:00
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 )
2015-04-10 20:04:02 +03:00
uiutil . init_combo_text_column ( combo , 1 )
2011-09-23 19:14:15 +04:00
combo . set_active ( - 1 )
2017-11-23 12:32:48 +03:00
combo = self . widget ( " controller-device-list " )
model = Gtk . ListStore ( str )
combo . set_model ( model )
combo . set_headers_visible ( False )
col = Gtk . TreeViewColumn ( )
text = Gtk . CellRendererText ( )
col . pack_start ( text , True )
col . add_attribute ( text , ' text ' , 0 )
combo . append_column ( col )
2011-09-23 19:14:15 +04:00
2009-11-04 21:18:14 +03:00
##########################
# Window state listeners #
##########################
2006-09-01 19:18:49 +04:00
2016-12-13 21:27:06 +03:00
def window_resized ( self , ignore , ignore2 ) :
2009-11-29 04:07:01 +03:00
if not self . is_visible ( ) :
return
2016-12-13 21:27:06 +03:00
self . _window_size = self . topwin . get_size ( )
2009-11-29 04:07:01 +03:00
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
2014-03-27 15:40:42 +04:00
devobj = self . get_hw_selection ( HW_LIST_COL_DEVICE )
if not devobj :
return
2014-04-26 18:45:50 +04:00
# force select the list entry before showing popup_menu
path_tuple = widget . get_path_at_pos ( int ( event . x ) , int ( event . y ) )
if path_tuple is None :
return False
path = path_tuple [ 0 ]
_iter = widget . get_model ( ) . get_iter ( path )
widget . get_selection ( ) . select_iter ( _iter )
2014-03-27 15:40:42 +04:00
rmdev = self . _addhwmenuitems [ " remove " ]
2014-04-22 03:31:18 +04:00
rmdev . set_visible ( self . widget ( " config-remove " ) . get_visible ( ) )
rmdev . set_sensitive ( self . widget ( " config-remove " ) . get_sensitive ( ) )
2014-03-27 15:40:42 +04:00
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_boot_selection ( self ) :
2015-09-14 01:01:39 +03:00
return uiutil . get_list_selected_row ( self . widget ( " boot-list " ) )
2011-07-20 04:29:07 +04:00
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 ( )
2015-05-20 01:13:33 +03:00
uiutil . set_list_selection_by_number ( self . widget ( " hw-list " ) , page )
2010-11-24 22:19:44 +03:00
2011-07-20 04:29:07 +04:00
def get_hw_row ( self ) :
2015-05-20 00:17:53 +03:00
return uiutil . get_list_selected_row ( self . widget ( " hw-list " ) )
2011-07-20 04:29:07 +04:00
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
2014-01-27 02:42:24 +04:00
if not self . err . chkbox_helper (
2017-09-20 10:36:27 +03: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. " ) ,
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 ( )
2014-01-17 23:21:59 +04:00
if not newrow or 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
2016-04-18 23:42:12 +03:00
for idx , row in enumerate ( model ) :
if row [ 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 ( )
2014-01-26 23:07:35 +04:00
elif pagetype == HW_LIST_TYPE_INSPECTION :
self . refresh_inspection_page ( )
2010-03-04 02:47:59 +03:00
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
2017-05-05 19:47:21 +03:00
except Exception as e :
2011-04-06 19:22:03 +04:00
self . err . show_err ( _ ( " Error refreshing hardware page: %s " ) % str ( e ) )
2014-01-26 23:11:06 +04:00
# Don't return, we want the rest of the bits to run regardless
2009-03-01 03:27:20 +03:00
2011-07-20 04:29:07 +04:00
self . disable_apply ( )
2014-01-26 23:11:06 +04:00
rem = pagetype in remove_pages
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
2014-02-28 22:35:49 +04:00
def switch_page ( self , notebook = None , ignore2 = None , newpage = None ) :
for i in range ( notebook . get_n_pages ( ) ) :
2014-03-01 07:23:42 +04:00
w = notebook . get_nth_page ( i )
w . set_visible ( i == newpage )
2014-02-28 22:35:49 +04:00
2009-11-04 21:18:14 +03:00
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 )
2015-04-04 04:34:03 +03:00
self . console . details_refresh_can_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
2015-04-09 23:07:09 +03:00
def refresh_vm_state ( self , ignore = None ) :
2010-11-30 19:49:47 +03:00
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 ( )
2009-11-04 21:18:14 +03:00
2010-05-12 20:57:32 +04:00
if vm . managedsave_supported :
2014-09-12 02:01:41 +04:00
self . change_run_text ( vm . has_managed_save ( ) )
2010-05-12 20:57:32 +04:00
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
2015-11-12 15:13:19 +03:00
if paused :
pauseTooltip = _ ( " Resume the virtual machine " )
else :
pauseTooltip = _ ( " Pause the virtual machine " )
self . widget ( " control-pause " ) . set_tooltip_text ( pauseTooltip )
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
2015-04-12 20:04:32 +03:00
self . console . details_update_widget_states ( )
2011-06-21 22:06:11 +04:00
if not run :
self . activate_default_console_page ( )
2009-11-04 21:18:14 +03:00
2014-03-18 18:13:57 +04:00
reason = self . vm . run_status_reason ( )
if reason :
status = " %s ( %s ) " % ( self . vm . run_status ( ) , reason )
else :
status = self . vm . run_status ( )
self . widget ( " overview-status-text " ) . set_text ( status )
2011-07-14 21:13:13 +04:00
self . widget ( " overview-status-icon " ) . set_from_icon_name (
2014-01-12 23:36:03 +04:00
self . vm . run_status_icon_name ( ) , Gtk . IconSize . BUTTON )
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
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 #
#############################
2018-03-15 12:53:58 +03:00
def view_manager ( self , _src ) :
from . manager import vmmManager
vmmManager . get_instance ( self ) . show ( )
2009-11-04 21:18:14 +03:00
2018-03-15 01:58:22 +03:00
def exit_app ( self , _src ) :
vmmEngine . get_instance ( ) . exit_app ( )
2009-11-04 21:18:14 +03:00
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 " )
2015-01-27 21:39:23 +03:00
# console.activate_default_console_page() will as a side effect
# switch to DETAILS_PAGE_CONSOLE. However this code path is triggered
# when the user runs a VM while they are focused on the details page,
# and we don't want to switch pages out from under them.
origpage = pages . get_current_page ( )
2015-04-04 04:34:03 +03:00
self . console . details_activate_default_console_page ( )
2015-01-27 21:39:23 +03:00
pages . set_current_page ( origpage )
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 )
2014-11-25 13:40:31 +03:00
index = 0
model = self . widget ( " hw-list " ) . get_model ( )
2016-04-18 23:42:12 +03:00
for idx , row in enumerate ( model ) :
if row [ HW_LIST_COL_TYPE ] == HW_LIST_TYPE_STATS :
index = idx
2014-11-25 13:40:31 +03:00
break
self . set_hw_selection ( index )
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 )
2017-05-05 19:47:21 +03:00
except Exception as e :
2011-03-23 17:06:59 +03:00
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 ) :
2014-03-22 22:34:23 +04:00
devobj = self . get_hw_selection ( HW_LIST_COL_DEVICE )
if not devobj :
2009-11-04 21:18:14 +03:00
return
2014-03-22 22:34:23 +04:00
self . remove_device ( devobj )
2009-11-04 21:18:14 +03:00
2015-11-11 02:30:31 +03:00
def set_pause_state ( self , state ) :
src = self . widget ( " control-pause " )
2011-04-14 20:25:51 +04:00
try :
2015-11-11 02:30:31 +03:00
src . handler_block_by_func ( self . control_vm_pause )
src . set_active ( state )
2011-04-14 20:25:51 +04:00
finally :
2015-11-11 02:30:31 +03:00
src . handler_unblock_by_func ( self . control_vm_pause )
2011-04-14 20:25:51 +04:00
2006-06-14 18:59:40 +04:00
def control_vm_pause ( self , src ) :
2015-11-11 02:30:31 +03:00
do_pause = src . get_active ( )
2006-06-15 02:42:04 +04:00
2015-11-11 02:30:31 +03:00
# Set button state back to original value: just let the status
# update function fix things for us
self . set_pause_state ( not do_pause )
2011-04-15 22:49:58 +04:00
2015-11-11 02:30:31 +03:00
if do_pause :
2018-03-08 21:42:45 +03:00
vmmenu . VMActionUI . suspend ( self , self . vm )
2006-06-14 18:59:40 +04:00
else :
2018-03-08 21:42:45 +03:00
vmmenu . VMActionUI . resume ( self , self . vm )
2007-11-27 19:31:30 +03:00
2013-07-01 22:33:59 +04:00
def control_vm_menu ( self , src_ignore ) :
2015-04-04 04:34:03 +03:00
can_usb = bool ( self . console . details_viewer_has_usb_redirection ( ) and
2013-07-09 03:13:52 +04:00
self . vm . has_spicevmc_type_redirdev ( ) )
self . widget ( " details-menu-usb-redirection " ) . set_sensitive ( can_usb )
2011-04-14 20:25:51 +04:00
2010-12-09 19:22:35 +03:00
def control_vm_run ( self , src_ignore ) :
2016-02-22 00:08:02 +03:00
if self . has_unapplied_changes ( self . get_hw_row ( ) ) :
return
2018-03-08 21:42:45 +03:00
vmmenu . VMActionUI . run ( self , self . vm )
2006-06-14 18:59:40 +04:00
2010-12-09 19:22:35 +03:00
def control_vm_shutdown ( self , src_ignore ) :
2018-03-08 21:42:45 +03:00
vmmenu . VMActionUI . shutdown ( self , self . vm )
2013-06-18 00:29:51 +04:00
2013-06-13 04:21:01 +04:00
def control_vm_screenshot ( self , src ) :
ignore = src
try :
return self . _take_screenshot ( )
2017-05-05 19:47:21 +03:00
except Exception as e :
2013-06-13 04:21:01 +04:00
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
2015-04-04 04:34:03 +03:00
spice_usbdev_widget = self . console . details_viewer_get_usb_widget ( )
2013-07-01 22:33:59 +04:00
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 " ) ,
2017-07-17 22:46:12 +03:00
widget = spice_usbdev_widget ,
buttons = Gtk . ButtonsType . CLOSE )
2013-07-01 22:33:59 +04:00
2013-06-13 04:21:01 +04:00
def _take_screenshot ( self ) :
2015-04-04 04:34:03 +03:00
image = self . console . details_viewer_get_pixbuf ( )
2011-07-13 20:27:23 +04:00
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 ( ) ,
}
2017-10-11 14:35:46 +03:00
ret = image . save_to_bufferv (
' png ' , list ( metadata . keys ( ) ) , list ( metadata . values ( ) )
)
2013-06-13 04:21:01 +04:00
# 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
2017-10-11 14:35:41 +03:00
if isinstance ( ret , tuple ) and len ( ret ) > = 2 :
2013-06-13 04:21:01 +04:00
ret = ret [ 1 ]
2016-01-15 23:07:58 +03:00
# F24 rawhide, ret[1] is a named tuple with a 'buffer' element...
if hasattr ( ret , " buffer " ) :
ret = ret . buffer
2013-06-13 04:21:01 +04:00
import datetime
now = str ( datetime . datetime . now ( ) ) . split ( " . " ) [ 0 ] . replace ( " " , " _ " )
default = " Screenshot_ %s _ %s .png " % ( self . vm . get_name ( ) , now )
2014-01-27 02:59:09 +04:00
path = self . err . browse_local (
self . vm . conn , _ ( " Save Virtual Machine Screenshot " ) ,
2016-02-05 18:18:16 +03:00
_type = ( " png " , _ ( " PNG files " ) ) ,
2014-01-27 02:59:09 +04:00
dialog_type = Gtk . FileChooserAction . SAVE ,
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 "
2017-05-05 21:19:54 +03:00
open ( 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 #
############################
2014-02-10 01:21:26 +04:00
def get_config_boot_order ( self ) :
2015-09-14 01:01:39 +03:00
boot_model = self . widget ( " boot-list " ) . get_model ( )
2010-02-25 04:37:41 +03:00
devs = [ ]
for row in boot_model :
if row [ BOOT_ACTIVE ] :
2014-02-10 01:21:26 +04:00
devs . append ( row [ BOOT_KEY ] )
2010-02-25 04:37:41 +03:00
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 " )
2014-01-31 22:40:09 +04:00
text = cpu_list . get_child ( ) . get_text ( )
2014-02-05 22:51:53 +04:00
if self . widget ( " cpu-copy-host " ) . get_active ( ) :
2014-09-21 04:40:05 +04:00
return virtinst . CPU . SPECIAL_MODE_HOST_MODEL
2014-02-05 22:51:53 +04:00
key = None
for row in cpu_list . get_model ( ) :
if text == row [ 0 ] :
key = row [ 2 ]
2014-01-31 22:40:09 +04:00
break
2014-02-05 22:51:53 +04:00
if not key :
return text
2010-12-17 03:36:07 +03:00
2014-02-05 22:51:53 +04:00
if key == " appdefault " :
return self . config . get_default_cpu_setting ( for_cpu = True )
return key
2010-12-17 03:36:07 +03:00
2018-03-15 00:18:42 +03:00
def inspection_refresh ( self , _src ) :
from . inspection import vmmInspection
inspection = vmmInspection . get_instance ( )
if inspection :
inspection . vm_refresh ( self . vm )
2017-02-23 13:22:27 +03:00
2010-12-17 03:36:07 +03:00
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 )
2015-04-09 01:29:48 +03:00
self . storage_browser . show ( self . topwin )
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
2014-02-21 14:13:11 +04:00
# Idmap
def config_idmap_enable ( self , src ) :
do_enable = src . get_active ( )
self . widget ( " idmap-spin-grid " ) . set_sensitive ( do_enable )
self . enable_apply ( EDIT_IDMAP )
2009-11-04 21:18:14 +03:00
# Memory
def config_get_maxmem ( self ) :
2015-09-14 01:01:39 +03:00
return uiutil . spin_get_helper ( self . widget ( " mem-maxmem " ) )
2009-11-04 21:18:14 +03:00
def config_get_memory ( self ) :
2015-09-14 01:01:39 +03:00
return uiutil . spin_get_helper ( self . widget ( " mem-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
2015-09-14 01:01:39 +03:00
maxadj = self . widget ( " mem-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
2010-05-13 20:55:08 +04:00
# VCPUS
2011-01-13 21:32:19 +03:00
def config_get_vcpus ( self ) :
2015-09-14 01:01:39 +03:00
return uiutil . spin_get_helper ( self . widget ( " cpu-vcpus " ) )
2011-01-13 21:32:19 +03:00
def config_get_maxvcpus ( self ) :
2015-09-14 01:01:39 +03:00
return uiutil . spin_get_helper ( self . widget ( " cpu-maxvcpus " ) )
2011-01-13 21:32:19 +03:00
2014-02-01 18:14:55 +04:00
def config_vcpus_changed ( self , src ) :
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 )
2015-09-14 01:01:39 +03:00
self . widget ( " cpu-vcpus-warn-box " ) . set_visible ( warn )
2010-05-13 20:55:08 +04:00
2015-09-14 01:01:39 +03:00
maxadj = self . widget ( " cpu-maxvcpus " )
2011-01-13 21:32:19 +03:00
maxval = self . config_get_maxvcpus ( )
if maxval < cur :
2014-02-01 18:14:55 +04:00
if maxadj . get_sensitive ( ) :
maxadj . set_value ( cur )
else :
src . set_value ( maxval )
cur = maxval
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 ) :
2015-09-14 01:01:39 +03:00
if self . widget ( " cpu-maxvcpus " ) . get_sensitive ( ) :
2014-02-01 18:14:55 +04:00
self . config_cpu_topology_changed ( )
2014-06-17 16:13:30 +04:00
# As this callback can be triggered by other events, set EDIT_MAXVCPUS
# only when the value is changed.
if self . config_get_maxvcpus ( ) != self . vm . vcpu_max_count ( ) :
self . enable_apply ( EDIT_MAXVCPUS )
2010-05-13 20:55:08 +04:00
2014-01-31 22:40:09 +04:00
def on_cpu_copy_host_clicked ( self , src ) :
uiutil . set_grid_row_visible (
self . widget ( " cpu-model " ) , not src . get_active ( ) )
self . enable_apply ( EDIT_CPU )
2013-12-03 06:46:47 +04:00
2014-10-28 02:20:20 +03:00
def config_cpu_model_changed ( self , ignore ) :
2014-10-27 19:04:57 +03:00
# Warn about hyper-threading setting
cpu_model = self . get_config_cpu_model ( )
threads = self . widget ( " cpu-threads " ) . get_value ( )
warn_ht = _warn_cpu_thread_topo ( threads , cpu_model )
2015-09-14 01:01:39 +03:00
self . widget ( " cpu-topology-warn-box " ) . set_visible ( warn_ht )
2014-10-27 19:04:57 +03:00
self . enable_apply ( EDIT_CPU )
2014-02-01 18:14:55 +04:00
def config_cpu_topology_changed ( self , ignore = None ) :
manual_top = self . widget ( " cpu-topology-table " ) . is_sensitive ( )
2015-09-14 01:01:39 +03:00
self . widget ( " cpu-maxvcpus " ) . set_sensitive ( not manual_top )
2014-02-01 18:14:55 +04:00
if manual_top :
cores = uiutil . spin_get_helper ( self . widget ( " cpu-cores " ) ) or 1
sockets = uiutil . spin_get_helper ( self . widget ( " cpu-sockets " ) ) or 1
threads = uiutil . spin_get_helper ( self . widget ( " cpu-threads " ) ) or 1
total = cores * sockets * threads
2015-09-14 01:01:39 +03:00
if uiutil . spin_get_helper ( self . widget ( " cpu-vcpus " ) ) > total :
self . widget ( " cpu-vcpus " ) . set_value ( total )
self . widget ( " cpu-maxvcpus " ) . set_value ( total )
2014-10-27 19:04:57 +03:00
# Warn about hyper-threading setting
cpu_model = self . get_config_cpu_model ( )
warn_ht = _warn_cpu_thread_topo ( threads , cpu_model )
2015-09-14 01:01:39 +03:00
self . widget ( " cpu-topology-warn-box " ) . set_visible ( warn_ht )
2014-10-27 19:04:57 +03:00
2014-02-01 18:14:55 +04:00
else :
2015-09-14 01:01:39 +03:00
maxvcpus = uiutil . spin_get_helper ( self . widget ( " cpu-maxvcpus " ) )
2014-02-01 18:14:55 +04:00
self . widget ( " cpu-sockets " ) . set_value ( maxvcpus or 1 )
self . widget ( " cpu-cores " ) . set_value ( 1 )
self . widget ( " cpu-threads " ) . set_value ( 1 )
self . enable_apply ( EDIT_TOPOLOGY )
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 )
2014-02-01 18:14:55 +04:00
self . config_cpu_topology_changed ( )
2010-12-17 00:05:55 +03:00
2017-02-21 16:01:02 +03:00
def video_model_changed ( self , ignore ) :
model = uiutil . get_list_selection ( self . widget ( " video-model " ) )
uiutil . set_grid_row_visible (
self . widget ( " video-3d " ) , model == " virtio " )
self . enable_apply ( EDIT_VIDEO_MODEL )
def video_3d_toggled ( self , ignore ) :
self . widget ( " video-3d " ) . set_inconsistent ( False )
self . enable_apply ( EDIT_VIDEO_3D )
2009-11-04 21:18:14 +03:00
# Boot device / Autostart
2015-04-08 02:43:09 +03:00
def config_bootdev_selected ( self , ignore = None ) :
2010-02-25 04:37:41 +03:00
boot_row = self . get_boot_selection ( )
2014-02-10 01:21:26 +04:00
boot_selection = boot_row and boot_row [ BOOT_KEY ]
boot_devs = self . get_config_boot_order ( )
2015-09-14 01:01:39 +03:00
up_widget = self . widget ( " boot-moveup " )
down_widget = self . widget ( " 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 ) :
2015-09-14 01:01:39 +03:00
model = self . widget ( " boot-list " ) . get_model ( )
2014-02-10 01:21:26 +04:00
row = model [ index ]
2010-02-25 04:37:41 +03:00
2014-02-10 01:21:26 +04:00
row [ BOOT_ACTIVE ] = not row [ BOOT_ACTIVE ]
2015-04-08 02:43:09 +03:00
self . config_bootdev_selected ( )
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
2014-02-10 01:21:26 +04:00
row = self . get_boot_selection ( )
if not row :
2010-02-25 04:37:41 +03:00
return
2014-02-10 01:21:26 +04:00
row_key = row [ BOOT_KEY ]
boot_order = self . get_config_boot_order ( )
key_idx = boot_order . index ( row_key )
2010-02-25 04:37:41 +03:00
if move_up :
2014-02-10 01:21:26 +04:00
new_idx = key_idx - 1
2010-02-25 04:37:41 +03:00
else :
2014-02-10 01:21:26 +04:00
new_idx = key_idx + 1
2010-02-25 04:37:41 +03:00
2014-02-10 01:21:26 +04:00
if new_idx < 0 or new_idx > = len ( boot_order ) :
# Somehow we went out of bounds
2010-02-25 04:37:41 +03:00
return
2015-09-14 01:01:39 +03:00
boot_list = self . widget ( " boot-list " )
2014-02-10 01:21:26 +04:00
model = boot_list . get_model ( )
prev_row = None
for row in model :
2016-04-18 23:42:12 +03:00
# pylint: disable=unsubscriptable-object
2014-02-10 01:21:26 +04:00
if prev_row and prev_row [ BOOT_KEY ] == row_key :
model . swap ( prev_row . iter , row . iter )
break
if row [ BOOT_KEY ] == row_key and prev_row and move_up :
model . swap ( prev_row . iter , row . iter )
break
2010-02-25 04:37:41 +03:00
2014-02-10 01:21:26 +04:00
prev_row = row
boot_list . get_selection ( ) . emit ( " changed " )
2011-07-15 00:18:42 +04:00
self . enable_apply ( EDIT_BOOTORDER )
2009-07-07 20:16:03 +04:00
2014-04-22 01:04:33 +04:00
def disk_format_changed ( self , ignore ) :
self . widget ( " disk-format-warn " ) . show ( )
self . enable_apply ( EDIT_DISK_FORMAT )
2013-04-17 02:18:03 +04:00
2009-11-04 00:15:18 +03:00
# CDROM Eject/Connect
2015-05-19 20:57:53 +03:00
def _change_storage_media ( self , devobj , newpath ) :
kwargs = { " path " : newpath }
return vmmAddHardware . change_config_helper ( self . vm . define_disk ,
kwargs , self . vm , self . err , devobj = devobj )
2009-12-11 03:18:24 +03:00
2015-05-19 20:57:53 +03:00
def _eject_media ( self , disk ) :
2011-08-30 22:29:51 +04:00
try :
2015-05-19 20:57:53 +03:00
self . _change_storage_media ( disk , None )
2017-05-05 19:47:21 +03:00
except Exception as e :
2011-08-30 22:29:51 +04:00
self . err . show_err ( ( _ ( " Error disconnecting media: %s " ) % e ) )
2009-11-04 00:15:18 +03:00
2015-05-19 20:57:53 +03:00
def _insert_media ( self , disk ) :
2011-08-30 22:29:51 +04:00
try :
2015-05-19 20:57:53 +03:00
devtype = disk . device
def change_cdrom_wrapper ( src_ignore , devobj , newpath ) :
return self . _change_storage_media ( devobj , 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 :
2014-01-15 02:18:02 +04:00
ret = vmmChooseCD ( self . vm , disk )
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 ]
2014-01-15 02:18:02 +04:00
dialog . disk = disk
2011-08-30 22:29:51 +04:00
dialog . show ( self . topwin )
2017-05-05 19:47:21 +03:00
except Exception as e :
2011-08-30 22:29:51 +04:00
self . err . show_err ( ( _ ( " Error launching media dialog: %s " ) % e ) )
return
2009-07-07 20:16:03 +04:00
2015-05-19 20:57:53 +03:00
def toggle_storage_media ( self , src_ignore ) :
disk = self . get_hw_selection ( HW_LIST_COL_DEVICE )
if not disk :
return
if disk . path :
return self . _eject_media ( disk )
return self . _insert_media ( disk )
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 )
2014-01-21 13:05:31 +04:00
elif pagetype is HW_LIST_TYPE_FILESYSTEM :
ret = self . config_filesystem_apply ( key )
2014-02-10 23:24:22 +04:00
elif pagetype is HW_LIST_TYPE_HOSTDEV :
ret = self . config_hostdev_apply ( key )
2011-06-01 19:17:19 +04:00
else :
ret = False
2017-05-05 19:47:21 +03:00
except Exception as 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
2009-11-04 19:09:41 +03:00
def config_overview_apply ( self ) :
2014-03-22 22:34:23 +04:00
kwargs = { }
hotplug_args = { }
2011-07-15 00:18:42 +04:00
2013-09-24 15:02:27 +04:00
if self . edited ( EDIT_TITLE ) :
2014-03-22 22:34:23 +04:00
kwargs [ " title " ] = self . widget ( " overview-title " ) . get_text ( )
hotplug_args [ " title " ] = kwargs [ " title " ]
2013-09-24 15:02:27 +04:00
2014-09-18 01:25:03 +04:00
if self . edited ( EDIT_FIRMWARE ) :
kwargs [ " loader " ] = uiutil . get_list_selection (
2015-05-20 00:17:53 +03:00
self . widget ( " overview-firmware " ) , column = 1 )
2014-09-18 01:25:03 +04:00
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_MACHTYPE ) :
2014-06-01 04:13:08 +04:00
if self . widget ( " overview-chipset " ) . is_visible ( ) :
kwargs [ " machine " ] = uiutil . get_list_selection (
2015-05-20 00:17:53 +03:00
self . widget ( " overview-chipset " ) , column = 1 )
2014-06-01 04:13:08 +04:00
else :
2015-05-20 00:54:53 +03:00
kwargs [ " machine " ] = uiutil . get_list_selection (
2014-06-01 04:13:08 +04:00
self . widget ( " machine-type " ) )
2012-01-05 13:35:40 +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 " )
2014-03-22 22:34:23 +04:00
kwargs [ " description " ] = (
desc_widget . get_buffer ( ) . get_property ( " text " ) or " " )
hotplug_args [ " description " ] = kwargs [ " description " ]
2012-10-14 22:55:24 +04:00
2014-02-21 14:13:11 +04:00
if self . edited ( EDIT_IDMAP ) :
2015-09-14 01:01:39 +03:00
enable_idmap = self . widget ( " idmap-checkbutton " ) . get_active ( )
2014-02-21 14:13:11 +04:00
if enable_idmap :
uid_target = self . widget ( " uid-target " ) . get_text ( ) . strip ( )
uid_count = self . widget ( " uid-count " ) . get_text ( ) . strip ( )
gid_target = self . widget ( " gid-target " ) . get_text ( ) . strip ( )
gid_count = self . widget ( " gid-count " ) . get_text ( ) . strip ( )
2014-02-27 06:01:29 +04:00
idmap_list = [ uid_target , uid_count , gid_target , gid_count ]
2014-02-21 14:13:11 +04:00
else :
idmap_list = None
2014-03-22 22:34:23 +04:00
kwargs [ " idmap_list " ] = idmap_list
2014-02-21 14:13:11 +04:00
2014-09-21 00:18:10 +04:00
# This needs to be last
if self . edited ( EDIT_NAME ) :
# Renaming is pretty convoluted, so do it here synchronously
2017-03-06 11:43:10 +03:00
self . vm . rename_domain ( self . widget ( " overview-name " ) . get_text ( ) )
2014-09-21 00:18:10 +04:00
if not kwargs and not hotplug_args :
# Saves some useless redefine attempts
return
2014-06-16 07:47:19 +04:00
return vmmAddHardware . change_config_helper ( self . vm . define_overview ,
kwargs , self . vm , self . err ,
2014-03-22 22:34:23 +04:00
hotplug_args = hotplug_args )
2014-02-21 14:13:11 +04:00
2009-11-04 21:18:14 +03:00
def config_vcpus_apply ( self ) :
2014-03-22 22:34:23 +04:00
kwargs = { }
hotplug_args = { }
2011-07-15 00:18:42 +04:00
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_VCPUS ) :
2014-03-22 22:34:23 +04:00
kwargs [ " vcpus " ] = self . config_get_vcpus ( )
hotplug_args [ " vcpus " ] = kwargs [ " vcpus " ]
2011-07-15 00:18:42 +04:00
2014-06-17 16:13:30 +04:00
if self . edited ( EDIT_MAXVCPUS ) :
kwargs [ " maxvcpus " ] = self . config_get_maxvcpus ( )
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_CPU ) :
2014-03-22 22:34:23 +04:00
kwargs [ " model " ] = self . get_config_cpu_model ( )
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 ( )
2014-03-22 22:34:23 +04:00
kwargs [ " sockets " ] = self . widget ( " cpu-sockets " ) . get_value ( )
kwargs [ " cores " ] = self . widget ( " cpu-cores " ) . get_value ( )
kwargs [ " threads " ] = self . widget ( " cpu-threads " ) . get_value ( )
2011-07-15 00:18:42 +04:00
if not do_top :
2014-03-22 22:34:23 +04:00
kwargs [ " sockets " ] = None
kwargs [ " cores " ] = None
kwargs [ " threads " ] = None
2011-07-15 00:18:42 +04:00
2014-06-16 07:47:19 +04:00
return vmmAddHardware . change_config_helper ( self . vm . define_cpu ,
kwargs , self . vm , self . err ,
2014-03-22 22:34:23 +04:00
hotplug_args = hotplug_args )
2006-06-14 18:59:40 +04:00
2009-11-04 21:18:14 +03:00
def config_memory_apply ( self ) :
2014-03-22 22:34:23 +04:00
kwargs = { }
hotplug_args = { }
2011-07-15 00:18:42 +04:00
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 ( )
2015-09-14 01:01:39 +03:00
if self . widget ( " mem-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
2014-03-22 22:34:23 +04:00
kwargs [ " memory " ] = curmem
kwargs [ " maxmem " ] = maxmem
hotplug_args [ " memory " ] = kwargs [ " memory " ]
hotplug_args [ " maxmem " ] = kwargs [ " maxmem " ]
2009-11-04 21:18:14 +03:00
2014-06-16 07:47:19 +04:00
return vmmAddHardware . change_config_helper ( self . vm . define_memory ,
kwargs , self . vm , self . err ,
2014-03-22 22:34:23 +04:00
hotplug_args = hotplug_args )
2009-11-04 21:18:14 +03:00
def config_boot_options_apply ( self ) :
2014-03-22 22:34:23 +04:00
kwargs = { }
2009-11-04 21:23:22 +03:00
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_AUTOSTART ) :
2015-09-14 01:01:39 +03:00
auto = self . widget ( " boot-autostart " )
2009-11-04 21:18:14 +03:00
try :
self . vm . set_autostart ( auto . get_active ( ) )
2017-05-05 19:47:21 +03:00
except Exception as 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 ) :
2014-03-22 22:34:23 +04:00
kwargs [ " boot_order " ] = self . get_config_boot_order ( )
2010-12-12 07:00:19 +03:00
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_BOOTMENU ) :
2014-03-22 22:34:23 +04:00
kwargs [ " boot_menu " ] = self . widget ( " boot-menu " ) . get_active ( )
2010-12-12 07:00:19 +03:00
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_KERNEL ) :
2014-03-22 22:34:23 +04:00
kwargs [ " kernel " ] = self . get_text ( " boot-kernel " , checksens = True )
kwargs [ " initrd " ] = self . get_text ( " boot-initrd " , checksens = True )
kwargs [ " dtb " ] = self . get_text ( " boot-dtb " , checksens = True )
kwargs [ " kernel_args " ] = self . get_text ( " boot-kernel-args " ,
checksens = True )
2011-07-15 00:31:38 +04:00
2014-03-22 22:34:23 +04:00
if kwargs [ " initrd " ] and not kwargs [ " kernel " ] :
2011-07-15 00:31:38 +04:00
return self . err . val_err (
_ ( " Cannot set initrd without specifying a kernel path " ) )
2014-03-22 22:34:23 +04:00
if kwargs [ " kernel_args " ] and not kwargs [ " kernel " ] :
2011-07-15 00:31:38 +04:00
return self . err . val_err (
_ ( " Cannot set kernel arguments without specifying a kernel path " ) )
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_INIT ) :
2014-03-22 22:34:23 +04:00
kwargs [ " init " ] = self . get_text ( " boot-init-path " )
2014-06-01 01:34:23 +04:00
kwargs [ " initargs " ] = self . get_text ( " boot-init-args " ) or " "
2014-03-22 22:34:23 +04:00
if not kwargs [ " init " ] :
2011-05-26 20:38:48 +04:00
return self . err . val_err ( _ ( " An init path must be specified " ) )
2014-06-16 07:47:19 +04:00
return vmmAddHardware . change_config_helper ( self . vm . define_boot ,
kwargs , self . vm , self . err )
2009-11-04 21:23:22 +03:00
2015-05-19 20:57:53 +03:00
#####################
# <device> defining #
#####################
2014-03-22 22:34:23 +04:00
def config_disk_apply ( self , devobj ) :
kwargs = { }
2011-07-15 00:18:42 +04:00
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_DISK_RO ) :
2014-03-22 22:34:23 +04:00
kwargs [ " readonly " ] = self . widget ( " disk-readonly " ) . get_active ( )
2011-07-15 00:18:42 +04:00
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_DISK_SHARE ) :
2014-03-22 22:34:23 +04:00
kwargs [ " shareable " ] = self . widget ( " disk-shareable " ) . get_active ( )
2011-07-15 00:18:42 +04:00
2013-10-04 05:39:01 +04:00
if self . edited ( EDIT_DISK_REMOVABLE ) :
2014-06-24 15:59:12 +04:00
kwargs [ " removable " ] = bool (
2014-03-22 22:34:23 +04:00
self . widget ( " disk-removable " ) . get_active ( ) )
2013-10-04 05:39:01 +04:00
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_DISK_CACHE ) :
2015-05-20 00:54:53 +03:00
kwargs [ " cache " ] = uiutil . get_list_selection (
self . widget ( " disk-cache " ) )
2011-07-15 00:18:42 +04:00
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_DISK_IO ) :
2015-05-20 00:54:53 +03:00
kwargs [ " io " ] = uiutil . get_list_selection ( self . widget ( " disk-io " ) )
2011-07-24 04:41:35 +04:00
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_DISK_FORMAT ) :
2015-09-14 02:05:02 +03:00
kwargs [ " driver_type " ] = self . widget ( " disk-format " ) . get_text ( )
2011-07-15 00:18:42 +04:00
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_DISK_SERIAL ) :
2014-03-22 22:34:23 +04:00
kwargs [ " serial " ] = self . get_text ( " disk-serial " )
2011-07-15 00:18:42 +04:00
2015-03-13 16:39:47 +03:00
if self . edited ( EDIT_DISK_SGIO ) :
2015-05-20 00:54:53 +03:00
sgio = uiutil . get_list_selection ( self . widget ( " disk-sgio " ) )
2015-03-13 16:39:47 +03:00
kwargs [ " sgio " ] = sgio
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_DISK_BUS ) :
2015-05-20 00:54:53 +03:00
bus = uiutil . get_list_selection ( self . widget ( " disk-bus " ) )
2012-02-29 12:48:18 +04:00
addr = None
2011-07-15 00:18:42 +04:00
2014-03-22 22:34:23 +04:00
kwargs [ " bus " ] = bus
kwargs [ " addrstr " ] = addr
2009-11-05 00:30:51 +03:00
2014-06-16 07:47:19 +04:00
return vmmAddHardware . change_config_helper ( self . vm . define_disk ,
kwargs , self . vm , self . err ,
2014-03-22 22:34:23 +04:00
devobj = devobj )
def config_sound_apply ( self , devobj ) :
kwargs = { }
2011-07-15 00:18:42 +04:00
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_SOUND_MODEL ) :
2015-05-20 00:54:53 +03:00
model = uiutil . get_list_selection ( self . widget ( " sound-model " ) )
2011-07-15 00:18:42 +04:00
if model :
2014-03-22 22:34:23 +04:00
kwargs [ " model " ] = model
2011-07-15 00:18:42 +04:00
2014-06-16 07:47:19 +04:00
return vmmAddHardware . change_config_helper ( self . vm . define_sound ,
kwargs , self . vm , self . err ,
2014-03-22 22:34:23 +04:00
devobj = devobj )
2009-11-05 00:30:51 +03:00
2014-03-22 22:34:23 +04:00
def config_smartcard_apply ( self , devobj ) :
kwargs = { }
2011-07-15 00:18:42 +04:00
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_SMARTCARD_MODE ) :
2015-05-20 00:54:53 +03:00
model = uiutil . get_list_selection ( self . widget ( " smartcard-mode " ) )
2011-07-15 00:18:42 +04:00
if model :
2014-03-22 22:34:23 +04:00
kwargs [ " model " ] = model
2011-07-15 00:18:42 +04:00
2014-06-16 07:47:19 +04:00
return vmmAddHardware . change_config_helper ( self . vm . define_smartcard ,
kwargs , self . vm , self . err ,
2014-03-22 22:34:23 +04:00
devobj = devobj )
2011-06-23 19:42:03 +04:00
2014-03-22 22:34:23 +04:00
def config_network_apply ( self , devobj ) :
kwargs = { }
2011-07-15 00:18:42 +04:00
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_NET_MODEL ) :
2015-05-20 00:54:53 +03:00
model = uiutil . get_list_selection ( self . widget ( " network-model " ) )
2014-03-22 22:34:23 +04:00
addrstr = None
2012-03-05 12:10:15 +04:00
if model == " spapr-vlan " :
2014-03-22 22:34:23 +04:00
addrstr = " spapr-vio "
kwargs [ " model " ] = model
kwargs [ " addrstr " ] = addrstr
2011-07-15 00:18:42 +04:00
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_NET_SOURCE ) :
2014-05-31 23:51:24 +04:00
( kwargs [ " ntype " ] , kwargs [ " source " ] ,
kwargs [ " mode " ] , kwargs [ " portgroup " ] ) = (
2014-03-22 22:34:23 +04:00
self . netlist . get_network_selection ( ) )
2011-07-15 00:18:42 +04:00
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_NET_VPORT ) :
2014-03-22 22:34:23 +04:00
( kwargs [ " vtype " ] , kwargs [ " managerid " ] ,
kwargs [ " typeid " ] , kwargs [ " typeidversion " ] ,
kwargs [ " instanceid " ] ) = self . netlist . get_vport ( )
2011-07-15 00:18:42 +04:00
2015-04-08 01:52:35 +03:00
if self . edited ( EDIT_NET_MAC ) :
kwargs [ " macaddr " ] = self . widget ( " network-mac-entry " ) . get_text ( )
2014-06-16 07:47:19 +04:00
return vmmAddHardware . change_config_helper ( self . vm . define_network ,
kwargs , self . vm , self . err ,
devobj = devobj )
2011-07-15 00:18:42 +04:00
2014-03-22 22:34:23 +04:00
def config_graphics_apply ( self , devobj ) :
2017-02-21 16:00:59 +03:00
( gtype , port , tlsport , listen ,
2017-02-21 16:01:01 +03:00
addr , passwd , keymap , gl , rendernode ) = self . gfxdetails . get_values ( )
2014-01-29 03:44:40 +04:00
2014-03-22 22:34:23 +04:00
kwargs = { }
2010-12-12 04:54:48 +03:00
2014-03-22 22:34:23 +04:00
if self . edited ( EDIT_GFX_PASSWD ) :
kwargs [ " passwd " ] = passwd
2017-02-21 16:00:59 +03:00
if self . edited ( EDIT_GFX_LISTEN ) :
kwargs [ " listen " ] = listen
if self . edited ( EDIT_GFX_ADDRESS ) or self . edited ( EDIT_GFX_LISTEN ) :
kwargs [ " addr " ] = addr
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_GFX_KEYMAP ) :
2014-03-22 22:34:23 +04:00
kwargs [ " keymap " ] = keymap
2017-02-21 16:00:59 +03:00
if self . edited ( EDIT_GFX_PORT ) or self . edited ( EDIT_GFX_LISTEN ) :
2014-03-22 22:34:23 +04:00
kwargs [ " port " ] = port
2017-02-21 16:00:56 +03:00
if self . edited ( EDIT_GFX_OPENGL ) :
kwargs [ " gl " ] = gl
2017-02-21 16:00:59 +03:00
if self . edited ( EDIT_GFX_TLSPORT ) or self . edited ( EDIT_GFX_LISTEN ) :
2014-03-22 22:34:23 +04:00
kwargs [ " tlsport " ] = tlsport
2017-02-21 16:01:01 +03:00
if self . edited ( EDIT_GFX_RENDERNODE ) :
kwargs [ " rendernode " ] = rendernode
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_GFX_TYPE ) :
2014-03-22 22:34:23 +04:00
kwargs [ " gtype " ] = gtype
2010-12-12 04:54:48 +03:00
2014-06-16 07:47:19 +04:00
return vmmAddHardware . change_config_helper ( self . vm . define_graphics ,
kwargs , self . vm , self . err ,
2014-03-22 22:34:23 +04:00
devobj = devobj )
2010-12-12 04:54:48 +03:00
2014-03-22 22:34:23 +04:00
def config_video_apply ( self , devobj ) :
kwargs = { }
2011-07-15 00:18:42 +04:00
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_VIDEO_MODEL ) :
2015-05-20 00:54:53 +03:00
model = uiutil . get_list_selection ( self . widget ( " video-model " ) )
2011-07-15 00:18:42 +04:00
if model :
2014-03-22 22:34:23 +04:00
kwargs [ " model " ] = model
2011-07-15 00:18:42 +04:00
2017-02-21 16:01:02 +03:00
if self . edited ( EDIT_VIDEO_3D ) :
kwargs [ " accel3d " ] = self . widget ( " video-3d " ) . get_active ( )
2014-06-16 07:47:19 +04:00
return vmmAddHardware . change_config_helper ( self . vm . define_video ,
kwargs , self . vm , self . err ,
2014-03-22 22:34:23 +04:00
devobj = devobj )
2009-11-04 21:18:14 +03:00
2014-03-22 22:34:23 +04:00
def config_controller_apply ( self , devobj ) :
kwargs = { }
2011-09-23 19:14:15 +04:00
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_CONTROLLER_MODEL ) :
2015-05-20 00:54:53 +03:00
model = uiutil . get_list_selection ( self . widget ( " controller-model " ) )
2015-05-19 19:50:39 +03:00
kwargs [ " model " ] = model
2011-09-23 19:14:15 +04:00
2014-06-16 07:47:19 +04:00
return vmmAddHardware . change_config_helper ( self . vm . define_controller ,
kwargs , self . vm , self . err ,
devobj = devobj )
2011-09-23 19:14:15 +04:00
2014-03-22 22:34:23 +04:00
def config_watchdog_apply ( self , devobj ) :
kwargs = { }
2011-07-15 00:18:42 +04:00
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_WATCHDOG_MODEL ) :
2015-05-20 00:54:53 +03:00
kwargs [ " model " ] = uiutil . get_list_selection (
2014-03-22 22:34:23 +04:00
self . widget ( " watchdog-model " ) )
2011-07-15 00:18:42 +04:00
2013-08-18 19:11:15 +04:00
if self . edited ( EDIT_WATCHDOG_ACTION ) :
2015-05-20 00:54:53 +03:00
kwargs [ " action " ] = uiutil . get_list_selection (
2014-03-22 22:34:23 +04:00
self . widget ( " watchdog-action " ) )
2011-07-15 00:18:42 +04:00
2014-06-16 07:47:19 +04:00
return vmmAddHardware . change_config_helper ( self . vm . define_watchdog ,
kwargs , self . vm , self . err ,
2014-03-22 22:34:23 +04:00
devobj = devobj )
2010-03-24 07:22:17 +03:00
2014-03-22 22:34:23 +04:00
def config_filesystem_apply ( self , devobj ) :
kwargs = { }
2014-01-21 13:05:31 +04:00
if self . edited ( EDIT_FS ) :
2014-01-27 20:03:59 +04:00
if self . fsDetails . validate_page_filesystem ( ) is False :
return False
2014-03-22 22:34:23 +04:00
kwargs [ " newdev " ] = self . fsDetails . get_dev ( )
2014-01-21 13:05:31 +04:00
2014-06-16 07:47:19 +04:00
return vmmAddHardware . change_config_helper ( self . vm . define_filesystem ,
kwargs , self . vm , self . err ,
devobj = devobj )
2014-01-21 13:05:31 +04:00
2014-03-22 22:34:23 +04:00
def config_hostdev_apply ( self , devobj ) :
kwargs = { }
2014-02-10 23:24:22 +04:00
if self . edited ( EDIT_HOSTDEV_ROMBAR ) :
2014-03-22 22:34:23 +04:00
kwargs [ " rom_bar " ] = self . widget ( " hostdev-rombar " ) . get_active ( )
2014-06-16 07:47:19 +04:00
return vmmAddHardware . change_config_helper ( self . vm . define_hostdev ,
kwargs , self . vm , self . err ,
2014-03-22 22:34:23 +04:00
devobj = devobj )
2014-02-10 23:24:22 +04:00
2009-11-04 00:15:18 +03:00
# Device removal
2014-03-22 22:34:23 +04:00
def remove_device ( self , devobj ) :
logging . debug ( " Removing device: %s " , devobj )
2011-04-15 00:43:17 +04:00
2014-01-27 02:42:24 +04:00
if not self . err . chkbox_helper ( self . config . get_confirm_removedev ,
2017-09-20 10:36:27 +03:00
self . config . set_confirm_removedev ,
text1 = ( _ ( " Are you sure you want to remove this device? " ) ) ) :
2011-04-15 00:43:17 +04:00
return
2009-11-04 21:18:14 +03:00
2009-11-20 17:29:26 +03:00
# Define the change
try :
2014-03-22 22:34:23 +04:00
self . vm . remove_device ( devobj )
2017-05-05 19:47:21 +03:00
except Exception as e :
2015-06-02 15:21:58 +03:00
self . err . show_err ( _ ( " Error Removing Device: %s " ) % str ( e ) )
2009-11-20 17:29:26 +03:00
return
# Try to hot remove
2016-04-18 23:42:12 +03:00
detach_err = ( )
2009-11-04 21:18:14 +03:00
try :
if self . vm . is_active ( ) :
2014-03-22 22:34:23 +04:00
self . vm . detach_device ( devobj )
2017-05-05 19:47:21 +03:00
except Exception as 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
2014-03-22 22:34:23 +04:00
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 :
2015-04-11 00:50:06 +03:00
if self . is_visible ( ) :
self . vm . ensure_latest_xml ( )
2017-05-05 19:47:21 +03:00
except libvirt . libvirtError as e :
2014-01-27 02:42:24 +04:00
if util . exception_is_libvirt_error ( e , " VIR_ERR_NO_DOMAIN " ) :
2013-08-16 17:59:33 +04:00
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
2014-09-18 01:25:03 +04:00
# Firmware
2015-02-22 19:13:21 +03:00
domcaps = self . vm . get_domain_capabilities ( )
firmware = domcaps . label_for_firmware_path (
2014-09-18 01:25:03 +04:00
self . vm . get_xmlobj ( ) . os . loader )
if self . widget ( " overview-firmware " ) . is_visible ( ) :
2015-05-20 01:22:49 +03:00
uiutil . set_list_selection (
2014-09-18 01:25:03 +04:00
self . widget ( " overview-firmware " ) , firmware )
elif self . widget ( " overview-firmware-label " ) . is_visible ( ) :
self . widget ( " overview-firmware-label " ) . set_text ( firmware )
2014-01-26 23:07:35 +04:00
# Machine settings
2015-07-31 15:28:00 +03:00
machtype = self . vm . get_machtype ( ) or _ ( " Unknown " )
2015-02-22 01:54:15 +03:00
if self . widget ( " machine-type " ) . is_visible ( ) :
2015-05-20 01:22:49 +03:00
uiutil . set_list_selection (
2015-02-22 01:54:15 +03:00
self . widget ( " machine-type " ) , machtype )
elif self . widget ( " machine-type-label " ) . is_visible ( ) :
self . widget ( " machine-type-label " ) . set_text ( machtype )
2014-01-26 23:07:35 +04:00
2015-02-22 01:54:15 +03:00
# Chipset
2014-06-01 04:13:08 +04:00
chipset = _chipset_label_from_machine ( machtype )
if self . widget ( " overview-chipset " ) . is_visible ( ) :
2015-05-20 01:22:49 +03:00
uiutil . set_list_selection (
2014-06-01 04:13:08 +04:00
self . widget ( " overview-chipset " ) , chipset )
elif self . widget ( " overview-chipset-label " ) . is_visible ( ) :
self . widget ( " overview-chipset-label " ) . set_text ( chipset )
2014-02-21 14:13:11 +04:00
# User namespace idmap setting
is_container = self . vm . is_container ( )
2015-09-14 01:01:39 +03:00
self . widget ( " idmap-expander " ) . set_visible ( is_container )
2014-02-21 14:13:11 +04:00
self . widget ( " uid-target " ) . set_text ( ' 1000 ' )
self . widget ( " uid-count " ) . set_text ( ' 10 ' )
self . widget ( " gid-target " ) . set_text ( ' 1000 ' )
self . widget ( " gid-count " ) . set_text ( ' 10 ' )
IdMap = self . vm . get_idmap ( )
show_config = IdMap . uid_start is not None
2015-09-14 01:01:39 +03:00
self . widget ( " idmap-checkbutton " ) . set_active ( show_config )
2014-02-21 14:13:11 +04:00
self . widget ( " idmap-spin-grid " ) . set_sensitive ( show_config )
if show_config :
2014-02-27 06:01:29 +04:00
Name = [ " uid-target " , " uid-count " , " gid-target " , " gid-count " ]
2014-02-21 14:13:11 +04:00
for name in Name :
IdMap_proper = getattr ( IdMap , name . replace ( " - " , " _ " ) )
self . widget ( name ) . set_value ( int ( IdMap_proper ) )
2014-01-26 23:07:35 +04:00
def refresh_inspection_page ( self ) :
2018-03-13 20:00:59 +03:00
inspection_supported = self . config . inspection_supported ( )
2014-01-27 03:15:50 +04:00
uiutil . set_grid_row_visible ( self . widget ( " details-overview-error " ) ,
2018-03-13 23:37:46 +03:00
bool ( self . vm . inspection . errorstr ) )
if self . vm . inspection . errorstr :
self . widget ( " details-overview-error " ) . set_text (
self . vm . inspection . errorstr )
inspection_supported = False
2013-11-25 19:10:03 +04:00
self . widget ( " details-inspection-os " ) . set_visible ( inspection_supported )
2018-03-13 20:00:59 +03:00
self . widget ( " details-inspection-apps " ) . set_visible ( inspection_supported )
if not inspection_supported :
return
# Operating System (ie. inspection data)
hostname = self . vm . inspection . hostname
if not hostname :
hostname = _ ( " unknown " )
self . widget ( " inspection-hostname " ) . set_text ( hostname )
os_type = self . vm . inspection . os_type
if not os_type :
os_type = " unknown "
self . widget ( " inspection-type " ) . set_text ( _label_for_os_type ( os_type ) )
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)
2018-03-13 20:00:59 +03:00
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_epoch " ] > 0 :
version + = str ( app [ " app_epoch " ] ) + " : "
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 " ]
elif app [ " app_description " ] :
summary = app [ " app_description " ]
pos = summary . find ( " \n " )
if pos > - 1 :
summary = _ ( " %(summary)s ... " ) % {
" summary " : summary [ 0 : pos ]
}
apps_model . append ( [ name , version , summary ] )
2011-07-18 22:53:57 +04:00
2009-11-04 21:18:14 +03:00
def refresh_stats_page ( self ) :
2015-09-23 23:28:46 +03:00
def _multi_color ( text1 , text2 ) :
2015-09-24 00:31:26 +03:00
return ( ' <span color= " #82003B " > %s </span> '
' <span color= " #295C45 " > %s </span> ' % ( text1 , text2 ) )
2010-08-22 03:27:45 +04:00
def _dsk_rx_tx_text ( rx , tx , unit ) :
2015-09-23 23:28:46 +03:00
opts = { " received " : rx , " transfered " : tx , " units " : unit }
return _multi_color ( _ ( " %(received)d %(units)s read " ) % opts ,
_ ( " %(transfered)d %(units)s write " ) % opts )
2010-08-22 03:27:45 +04:00
def _net_rx_tx_text ( rx , tx , unit ) :
2015-09-23 23:28:46 +03:00
opts = { " received " : rx , " transfered " : tx , " units " : unit }
return _multi_color ( _ ( " %(received)d %(units)s in " ) % opts ,
_ ( " %(transfered)d %(units)s out " ) % opts )
2009-11-04 21:18:14 +03:00
cpu_txt = _ ( " Disabled " )
mem_txt = _ ( " Disabled " )
dsk_txt = _ ( " Disabled " )
net_txt = _ ( " Disabled " )
2014-02-12 00:29:30 +04:00
if self . config . get_stats_enable_cpu_poll ( ) :
cpu_txt = " %d %% " % self . vm . guest_cpu_time_percentage ( )
2009-11-04 21:18:14 +03:00
2014-02-11 00:13:31 +04:00
if self . config . get_stats_enable_memory_poll ( ) :
cur_vm_memory = self . vm . stats_memory ( )
vm_memory = self . vm . maximum_memory ( )
2015-09-24 00:31:26 +03:00
mem_txt = _ ( " % (current-memory)s of % (total-memory)s " ) % {
2015-09-23 23:28:46 +03:00
" current-memory " : util . pretty_mem ( cur_vm_memory ) ,
" total-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 ( ) ,
2014-06-16 07:56:02 +04:00
self . vm . disk_write_rate ( ) , " KiB/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 ( ) ,
2014-06-16 07:56:02 +04:00
self . vm . network_tx_rate ( ) , " KiB/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 ( ) )
2015-05-04 23:33:56 +03:00
d1 , d2 = self . vm . disk_io_vectors ( )
self . disk_io_graph . set_property ( " data_array " , d1 + d2 )
n1 , n2 = self . vm . network_traffic_vectors ( )
self . network_traffic_graph . set_property ( " data_array " , n1 + n2 )
2009-11-04 21:18:14 +03:00
2014-01-31 22:40:09 +04:00
def refresh_config_cpu ( self ) :
2015-09-24 16:31:04 +03:00
# Set topology first, because it impacts maxvcpus values
2014-04-03 18:30:37 +04:00
cpu = self . vm . get_cpu_config ( )
show_top = bool ( cpu . sockets or cpu . cores or cpu . threads )
self . widget ( " cpu-topology-enable " ) . set_active ( show_top )
2010-12-17 00:05:55 +03:00
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-sockets " ) . set_value ( sockets )
self . widget ( " cpu-cores " ) . set_value ( cores )
self . widget ( " cpu-threads " ) . set_value ( threads )
2014-02-01 18:14:55 +04:00
if show_top :
self . widget ( " cpu-topology-expander " ) . set_expanded ( True )
2010-12-17 00:05:55 +03:00
2015-09-24 16:31:04 +03:00
host_active_count = self . vm . conn . host_active_processor_count ( )
maxvcpus = self . vm . vcpu_max_count ( )
curvcpus = self . vm . vcpu_count ( )
self . widget ( " cpu-vcpus " ) . set_value ( int ( curvcpus ) )
self . widget ( " cpu-maxvcpus " ) . set_value ( int ( maxvcpus ) )
self . widget ( " state-host-cpus " ) . set_text ( str ( host_active_count ) )
# Trigger this again to make sure maxvcpus is correct
self . config_cpu_topology_changed ( )
# Warn about overcommit
warn = bool ( self . config_get_vcpus ( ) > host_active_count )
self . widget ( " cpu-vcpus-warn-box " ) . set_visible ( warn )
# CPU model config
2014-01-31 22:40:09 +04:00
model = cpu . model or None
if not model :
if cpu . mode == " host-model " or cpu . mode == " host-passthrough " :
model = cpu . mode
if model :
self . widget ( " cpu-model " ) . get_child ( ) . set_text ( model )
else :
2015-05-20 01:22:49 +03:00
uiutil . set_list_selection (
2014-02-05 22:51:53 +04:00
self . widget ( " cpu-model " ) ,
2015-05-20 00:17:53 +03:00
virtinst . CPU . SPECIAL_MODE_HV_DEFAULT , column = 2 )
2014-01-31 22:40:09 +04:00
2014-10-27 19:04:57 +03:00
# Warn about hyper-threading setting
cpu_model = self . get_config_cpu_model ( )
warn_ht = _warn_cpu_thread_topo ( threads , cpu_model )
2015-09-14 01:01:39 +03:00
self . widget ( " cpu-topology-warn-box " ) . set_visible ( warn_ht )
2014-10-27 19:04:57 +03:00
2014-09-21 04:40:05 +04:00
is_host = ( cpu . mode == " host-model " )
2014-01-31 22:40:09 +04:00
self . widget ( " cpu-copy-host " ) . set_active ( bool ( is_host ) )
self . on_cpu_copy_host_clicked ( self . widget ( " cpu-copy-host " ) )
2010-12-17 00:05:55 +03:00
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 " )
2017-10-11 14:35:55 +03: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
2014-06-16 07:56:02 +04:00
host_mem_widget . set_text ( " %d MiB " % ( int ( round ( host_mem ) ) ) )
2008-03-18 21:37:22 +03:00
2015-09-14 01:01:39 +03:00
curmem = self . widget ( " mem-memory " )
maxmem = self . widget ( " mem-maxmem " )
2013-04-17 02:37:00 +04:00
curmem . set_value ( int ( round ( vm_cur_mem ) ) )
maxmem . set_value ( int ( round ( vm_max_mem ) ) )
2006-09-22 20:31:51 +04:00
2015-09-14 01:01:39 +03:00
if not self . widget ( " mem-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
2015-03-13 16:39:47 +03:00
@staticmethod
def build_disk_sgio ( vm , combo ) :
ignore = vm
model = Gtk . ListStore ( str , str )
combo . set_model ( model )
2015-04-10 20:04:02 +03:00
uiutil . init_combo_text_column ( combo , 1 )
2015-04-08 01:08:29 +03:00
model . append ( [ None , _ ( " Hypervisor default " ) ] )
2015-03-13 16:39:47 +03:00
model . append ( [ " filtered " , " filtered " ] )
model . append ( [ " unfiltered " , " unfiltered " ] )
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
2010-09-03 22:10:04 +04:00
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
2015-09-06 00:59:47 +03:00
size = " - "
if path :
size = _ ( " Unknown " )
vol = self . conn . get_vol_by_path ( path )
2010-03-04 02:43:48 +03:00
if vol :
size = vol . get_pretty_capacity ( )
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
2017-06-27 21:13:36 +03:00
self . conn . is_test ( ) ) )
2013-10-04 05:39:01 +04:00
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
2015-08-03 19:52:07 +03:00
pretty_name = _label_for_device ( disk )
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 )
2014-01-27 03:15:50 +04:00
uiutil . set_grid_row_visible ( self . widget ( " disk-removable " ) ,
2013-10-04 05:39:01 +04:00
can_set_removable )
2015-03-13 16:39:47 +03:00
is_lun = disk . device == virtinst . VirtualDisk . DEVICE_LUN
uiutil . set_grid_row_visible ( self . widget ( " disk-sgio " ) , is_lun )
if is_lun :
self . build_disk_sgio ( self . vm , self . widget ( " disk-sgio " ) )
2015-05-20 01:22:49 +03:00
uiutil . set_list_selection ( self . widget ( " disk-sgio " ) , disk . sgio )
2015-03-13 16:39:47 +03:00
2011-07-14 21:13:13 +04:00
self . widget ( " disk-size " ) . set_text ( size )
2015-05-20 01:22:49 +03:00
uiutil . set_list_selection ( self . widget ( " disk-cache " ) , cache )
uiutil . set_list_selection ( self . widget ( " disk-io " ) , io )
2011-03-09 18:36:21 +03:00
2015-09-14 02:05:02 +03:00
self . widget ( " disk-format " ) . set_text ( driver_type )
2014-04-22 01:04:33 +04:00
self . widget ( " disk-format-warn " ) . hide ( )
2009-11-04 23:41:18 +03:00
2015-04-08 02:31:30 +03:00
vmmAddHardware . populate_disk_bus_combo ( self . vm , devtype ,
2015-08-03 19:52:06 +03:00
self . widget ( " disk-bus " ) . get_model ( ) )
2015-05-20 01:22:49 +03:00
uiutil . set_list_selection ( self . widget ( " 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
2015-09-14 01:01:39 +03:00
button = self . widget ( " disk-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
2014-01-28 01:58:45 +04:00
vmmAddHardware . populate_network_model_combo (
self . vm , self . widget ( " network-model " ) )
2015-05-20 01:22:49 +03:00
uiutil . set_list_selection ( self . widget ( " network-model " ) , net . model )
details: do not show MAC address if not set
Fixes this exception:
Traceback (most recent call last):
File "virt-manager/virtManager/create.py", line 1780, in finish
self.customize(guest)
File "virt-manager/virtManager/create.py", line 1812, in customize
self.config_window = vmmDetails(virtinst_guest, self.topwin)
File "virt-manager/virtManager/details.py", line 560, in __init__
self.populate_hw_list()
File "virt-manager/virtManager/details.py", line 3165, in populate_hw_list
self.repopulate_hw_list()
File "virt-manager/virtManager/details.py", line 3220, in repopulate_hw_list
update_hwlist(HW_LIST_TYPE_NIC, dev)
File "virt-manager/virtManager/details.py", line 3195, in update_hwlist
label = _label_for_device(dev)
File "virt-manager/virtManager/details.py", line 188, in _label_for_device
return "NIC %s" % dev.macaddr[-9:]
TypeError: 'NoneType' object has no attribute '__getitem__'
Closes: https://bugzilla.redhat.com/show_bug.cgi?id=1164123
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
2014-11-14 11:45:07 +03:00
2015-04-08 01:52:35 +03:00
macaddr = net . macaddr or " "
if self . widget ( " network-mac-label " ) . is_visible ( ) :
self . widget ( " network-mac-label " ) . set_text ( macaddr )
else :
self . widget ( " network-mac-entry " ) . set_text ( macaddr )
2011-03-17 23:33:40 +03:00
2014-01-28 01:58:45 +04:00
self . netlist . set_dev ( net )
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
2015-04-09 20:36:40 +03:00
dev = vmmAddHardware . label_for_input_device ( inp . type , inp . bus )
2007-09-26 04:05:45 +04:00
2014-05-04 21:23:54 +04:00
mode = None
2010-09-03 23:59:33 +04:00
if inp . type == " tablet " :
2009-11-11 20:56:58 +03:00
mode = _ ( " Absolute Movement " )
2014-05-04 21:23:54 +04:00
elif inp . type == " mouse " :
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 )
2014-05-04 21:23:54 +04:00
self . widget ( " input-dev-mode " ) . set_text ( mode or " " )
uiutil . set_grid_row_visible ( self . widget ( " input-dev-mode " ) , bool ( mode ) )
2009-01-15 19:23:23 +03:00
2015-04-09 20:11:20 +03:00
tooltip = _remove_tooltip
sensitive = True
2014-05-04 21:23:54 +04:00
if ( ( inp . type == " mouse " and inp . bus in ( " xen " , " ps2 " ) ) or
2014-06-03 02:54:28 +04:00
( inp . type == " keyboard " and inp . bus in ( " xen " , " ps2 " ) ) ) :
2015-04-09 20:11:20 +03:00
sensitive = False
tooltip = _ ( " Hypervisor does not support removing this device " )
self . widget ( " config-remove " ) . set_sensitive ( sensitive )
self . widget ( " config-remove " ) . set_tooltip_text ( tooltip )
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
2014-01-29 03:44:40 +04:00
title = self . gfxdetails . set_dev ( gfx )
2013-09-28 20:21:35 +04:00
self . widget ( " graphics-title " ) . set_markup ( " <b> %s </b> " % title )
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
2015-05-20 01:22:49 +03:00
uiutil . set_list_selection ( self . widget ( " 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
2015-05-20 01:22:49 +03:00
uiutil . set_list_selection ( self . widget ( " 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
2014-09-20 18:23:19 +04:00
address = None
if rd . type == ' tcp ' :
address = _ ( " %s : %s " ) % ( rd . host , rd . service )
2011-09-02 05:23:27 +04:00
2015-08-03 19:52:07 +03:00
self . widget ( " redir-title " ) . set_markup ( _label_for_device ( rd ) )
2014-09-20 18:23:19 +04:00
self . widget ( " redir-type " ) . set_text ( rd . pretty_type ( rd . type ) )
2011-09-02 05:23:27 +04:00
2014-09-20 18:23:19 +04:00
self . widget ( " redir-address " ) . set_text ( address or " " )
uiutil . set_grid_row_visible (
self . widget ( " redir-address " ) , bool ( address ) )
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 )
2014-01-27 03:15:50 +04:00
uiutil . 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
2017-09-16 02:36:58 +03:00
model = dev . model or " isa "
pmodel = virtinst . VirtualPanicDevice . get_pretty_model ( model )
2017-09-04 19:40:34 +03:00
self . widget ( " panic-model " ) . set_text ( pmodel )
2014-01-10 13:37:55 +04:00
2013-09-23 17:39:56 +04:00
def refresh_rng_page ( self ) :
dev = self . get_hw_selection ( HW_LIST_COL_DEVICE )
values = {
2017-08-05 09:39:32 +03:00
" rng-bind-host " : " bind_host " ,
" rng-bind-service " : " bind_service " ,
" rng-connect-host " : " connect_host " ,
" rng-connect-service " : " connect_service " ,
" rng-type " : " type " ,
" rng-device " : " device " ,
" rng-backend-type " : " backend_type " ,
" rng-rate-bytes " : " rate_bytes " ,
" rng-rate-period " : " rate_period "
2013-09-23 17:39:56 +04:00
}
rewriter = {
2017-08-05 09:39:32 +03:00
" rng-type " : lambda x :
2013-10-25 19:13:29 +04:00
VirtualRNGDevice . get_pretty_type ( x ) ,
2017-08-05 09:39:32 +03: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 ) :
2014-01-27 03:15:50 +04:00
uiutil . set_grid_row_visible ( self . widget ( widget ) , v )
2013-10-25 19:13:29 +04:00
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 )
2017-03-09 01:48:26 +03:00
if " rate " in k :
uiutil . set_grid_row_visible ( self . widget ( k ) , val != " - " )
2013-09-23 17:39:56 +04:00
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 )
2014-01-27 03:15:50 +04:00
uiutil . 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 ( )
2014-01-29 06:44:55 +04:00
if ( target_port is not None and
chardev . virtual_device_type == " console " ) :
typelabel + = " %s " % ( int ( target_port ) + 1 )
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
2014-02-10 23:24:22 +04:00
rom_bar = hostdev . rom_bar
if rom_bar is None :
rom_bar = True
2014-09-20 18:23:19 +04:00
devtype = hostdev . type
if hostdev . type == ' usb ' :
devtype = ' usb_device '
nodedev = None
2015-04-10 16:37:03 +03:00
for trydev in self . vm . conn . filter_nodedevs ( devtype , None ) :
2015-04-07 21:12:00 +03:00
if trydev . xmlobj . compare_to_hostdev ( hostdev ) :
nodedev = trydev . xmlobj
2014-09-20 18:23:19 +04:00
2010-09-07 20:09:48 +04:00
pretty_name = None
if nodedev :
pretty_name = nodedev . pretty_name ( )
if not pretty_name :
2014-09-20 22:56:57 +04:00
pretty_name = hostdev . pretty_name ( )
2008-03-07 00:43:46 +03:00
2014-02-10 23:24:22 +04:00
uiutil . set_grid_row_visible (
self . widget ( " hostdev-rombar " ) , hostdev . type == " pci " )
2016-02-05 18:18:16 +03:00
devlabel = " <b> " + _ ( " Physical %s Device " ) % hostdev . type . upper ( ) + " </b> "
2011-07-14 21:13:13 +04:00
self . widget ( " hostdev-title " ) . set_markup ( devlabel )
self . widget ( " hostdev-source " ) . set_text ( pretty_name )
2014-02-10 23:24:22 +04:00
self . widget ( " hostdev-rombar " ) . set_active ( rom_bar )
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
2013-07-15 19:07:40 +04:00
model = vid . model
2015-07-28 08:19:17 +03:00
if model == " qxl " and vid . vgamem :
ram = vid . vgamem
else :
ram = vid . vram
2010-09-03 23:59:33 +04:00
heads = vid . heads
2009-11-04 21:18:14 +03:00
try :
2017-10-11 14:35:55 +03:00
ramlabel = ram and " %d MiB " % ( int ( ram ) / / 1024 ) or " - "
2017-07-24 11:26:48 +03:00
except Exception :
2009-11-04 21:18:14 +03:00
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
2015-05-20 01:22:49 +03:00
uiutil . set_list_selection ( self . widget ( " video-model " ) , model )
2009-11-05 22:59:11 +03:00
2017-02-21 16:01:02 +03:00
if vid . accel3d is None :
self . widget ( " video-3d " ) . set_inconsistent ( True )
else :
self . widget ( " video-3d " ) . set_active ( vid . accel3d )
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
2015-05-20 01:22:49 +03:00
uiutil . set_list_selection ( self . widget ( " watchdog-model " ) , model )
uiutil . set_list_selection ( self . widget ( " watchdog-action " ) , action )
2010-03-24 07:22:17 +03:00
2010-12-16 20:41:47 +03:00
def refresh_controller_page ( self ) :
2017-11-23 12:32:47 +03:00
controller = self . get_hw_selection ( HW_LIST_COL_DEVICE )
if not controller :
2010-12-16 20:41:47 +03:00
return
2017-11-23 12:32:48 +03:00
uiutil . set_grid_row_visible ( self . widget ( " device-list-label " ) , False )
uiutil . set_grid_row_visible ( self . widget ( " controller-device-box " ) , False )
2017-06-27 22:35:54 +03:00
can_remove = True
2017-11-23 12:32:47 +03:00
if self . vm . get_xmlobj ( ) . os . is_x86 ( ) and controller . type == " usb " :
2017-06-27 22:35:54 +03:00
can_remove = False
2017-11-23 12:32:47 +03:00
if controller . type == " pci " :
2017-06-27 22:35:54 +03:00
can_remove = False
2017-11-23 12:32:49 +03:00
if controller . type == " scsi " :
2017-11-23 12:32:50 +03:00
model = self . widget ( " controller-device-list " ) . get_model ( )
model . clear ( )
2017-11-23 12:32:49 +03:00
for disk in self . vm . get_disk_devices ( ) :
if disk . address . compare_controller ( controller , disk . bus ) :
can_remove = False
2017-11-23 12:32:50 +03:00
name = _label_for_device ( disk )
infoStr = ( " %s on %s " % ( name , disk . address . pretty_desc ( ) ) )
model . append ( [ infoStr ] )
uiutil . set_grid_row_visible ( self . widget ( " device-list-label " ) , True )
uiutil . set_grid_row_visible ( self . widget ( " controller-device-box " ) , True )
2017-06-27 22:35:54 +03:00
self . widget ( " config-remove " ) . set_sensitive ( can_remove )
2011-09-02 05:23:26 +04:00
2017-11-23 12:32:47 +03:00
type_label = controller . pretty_desc ( )
2011-07-14 21:13:13 +04:00
self . widget ( " controller-type " ) . set_text ( type_label )
2011-09-23 19:14:15 +04:00
2015-05-19 19:50:39 +03:00
combo = self . widget ( " controller-model " )
2017-11-23 12:32:47 +03:00
vmmAddHardware . populate_controller_model_combo ( combo , controller . type )
show_model = ( controller . model or len ( combo . get_model ( ) ) > 1 )
if controller . type == " pci " :
2017-06-27 22:32:54 +03:00
show_model = False
uiutil . set_grid_row_visible ( combo , show_model )
2015-05-20 01:22:49 +03:00
uiutil . set_list_selection ( self . widget ( " controller-model " ) ,
2017-11-23 12:32:47 +03:00
controller . model or None )
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
2014-01-21 13:05:31 +04:00
self . fsDetails . set_dev ( dev )
self . fsDetails . update_fs_rows ( )
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
2015-09-14 01:01:39 +03:00
autostart_chk = self . widget ( " boot-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
2014-02-10 01:21:26 +04:00
uiutil . set_grid_row_visible (
self . widget ( " boot-order-frame " ) , show_boot )
uiutil . set_grid_row_visible (
self . widget ( " boot-kernel-expander " ) , show_kernel )
uiutil . set_grid_row_visible (
self . widget ( " boot-init-frame " ) , 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
2014-06-01 01:34:23 +04:00
init , initargs = self . vm . get_init ( )
2011-07-14 21:13:13 +04:00
self . widget ( " boot-init-path " ) . set_text ( init or " " )
2014-06-01 01:34:23 +04:00
self . widget ( " boot-init-args " ) . set_text ( initargs 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 )
2014-02-10 01:21:26 +04:00
self . repopulate_boot_order ( )
2008-03-07 00:43:46 +03:00
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
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
2014-01-26 23:07:35 +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 :
2018-03-13 20:00:59 +03:00
if self . config . inspection_supported ( ) :
2014-01-26 23:07:35 +04:00
add_hw_list_option ( _ ( " OS information " ) ,
HW_LIST_TYPE_INSPECTION , " computer " )
2015-09-22 02:16:31 +03:00
add_hw_list_option ( _ ( " Performance " ) , HW_LIST_TYPE_STATS ,
2010-02-07 20:18:28 +03:00
" utilities-system-monitor " )
2015-09-22 02:16:31 +03:00
add_hw_list_option ( _ ( " CPUs " ) , 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
2018-02-14 23:35:53 +03:00
return origdev . get_xml_id ( ) == newdev . get_xml_id ( )
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
2014-02-10 00:20:41 +04:00
def update_hwlist ( hwtype , dev ) :
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
"""
2015-08-03 19:52:07 +03:00
label = _label_for_device ( dev )
2014-02-10 00:20:41 +04:00
icon = _icon_for_device ( dev )
currentDevices . append ( dev )
2010-09-08 02:38:01 +04:00
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 ]
2014-02-10 00:20:41 +04:00
if dev_cmp ( rowdev , dev ) :
2009-07-20 23:09:32 +04:00
# Update existing HW info
2014-02-10 00:20:41 +04:00
row [ HW_LIST_COL_DEVICE ] = dev
row [ HW_LIST_COL_LABEL ] = label
row [ HW_LIST_COL_ICON_NAME ] = icon
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
2014-02-10 00:20:41 +04:00
add_hw_list_option ( insertAt , label , hwtype , dev , icon )
for dev in self . vm . get_disk_devices ( ) :
update_hwlist ( HW_LIST_TYPE_DISK , dev )
for dev in self . vm . get_network_devices ( ) :
update_hwlist ( HW_LIST_TYPE_NIC , dev )
for dev in self . vm . get_input_devices ( ) :
update_hwlist ( HW_LIST_TYPE_INPUT , dev )
for dev in self . vm . get_graphics_devices ( ) :
update_hwlist ( HW_LIST_TYPE_GRAPHICS , dev )
for dev in self . vm . get_sound_devices ( ) :
update_hwlist ( HW_LIST_TYPE_SOUND , dev )
for dev in self . vm . get_char_devices ( ) :
update_hwlist ( HW_LIST_TYPE_CHAR , dev )
for dev in self . vm . get_hostdev_devices ( ) :
update_hwlist ( HW_LIST_TYPE_HOSTDEV , dev )
for dev in self . vm . get_redirdev_devices ( ) :
update_hwlist ( HW_LIST_TYPE_REDIRDEV , dev )
for dev in self . vm . get_video_devices ( ) :
update_hwlist ( HW_LIST_TYPE_VIDEO , dev )
for dev in self . vm . get_watchdog_devices ( ) :
update_hwlist ( HW_LIST_TYPE_WATCHDOG , dev )
for dev in self . vm . get_controller_devices ( ) :
2011-09-23 19:14:15 +04:00
# skip USB2 ICH9 companion controllers
2014-02-10 00:20:41 +04:00
if dev . model in [ " ich9-uhci1 " , " ich9-uhci2 " , " ich9-uhci3 " ] :
2011-09-23 19:14:15 +04:00
continue
2017-06-27 22:28:12 +03:00
# These are all parts of a default PCIe setup, which we
# condense down to one listing
if dev . model in [ " pcie-root-port " , " dmi-to-pci-bridge " ,
" pci-bridge " ] :
continue
2014-02-10 00:20:41 +04:00
update_hwlist ( HW_LIST_TYPE_CONTROLLER , dev )
for dev in self . vm . get_filesystem_devices ( ) :
update_hwlist ( HW_LIST_TYPE_FILESYSTEM , dev )
for dev in self . vm . get_smartcard_devices ( ) :
update_hwlist ( HW_LIST_TYPE_SMARTCARD , dev )
for dev in self . vm . get_tpm_devices ( ) :
update_hwlist ( HW_LIST_TYPE_TPM , dev )
for dev in self . vm . get_rng_devices ( ) :
update_hwlist ( HW_LIST_TYPE_RNG , dev )
for dev in self . vm . get_panic_devices ( ) :
update_hwlist ( HW_LIST_TYPE_PANIC , dev )
2014-01-10 13:37:55 +04:00
2017-10-11 14:35:57 +03:00
devs = list ( range ( len ( hw_list_model ) ) )
2007-04-13 02:54:33 +04:00
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
2017-10-11 14:35:41 +03:00
if isinstance ( olddev , 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
2014-02-10 01:21:26 +04:00
def _make_boot_rows ( self ) :
if not self . vm . can_use_device_boot_order ( ) :
return [
2016-02-05 18:18:16 +03:00
[ " hd " , _ ( " Hard Disk " ) , " drive-harddisk " , False , True ] ,
[ " cdrom " , _ ( " CDROM " ) , " media-optical " , False , True ] ,
[ " network " , _ ( " Network (PXE) " ) , " network-idle " , False , True ] ,
[ " fd " , _ ( " Floppy " ) , " media-floppy " , False , True ] ,
2014-02-10 01:21:26 +04:00
]
ret = [ ]
for dev in self . vm . get_bootable_devices ( ) :
icon = _icon_for_device ( dev )
2015-08-03 19:52:07 +03:00
label = _label_for_device ( dev )
2010-02-25 04:37:41 +03:00
2014-02-10 01:21:26 +04:00
ret . append ( [ dev . vmmidstr , label , icon , False , True ] )
2010-02-25 04:37:41 +03:00
2014-02-10 01:21:26 +04:00
if not ret :
ret . append ( [ None , _ ( " No bootable devices " ) , None , False , False ] )
return ret
2010-02-25 04:37:41 +03:00
2014-02-10 01:21:26 +04:00
def repopulate_boot_order ( self ) :
2015-09-14 01:01:39 +03:00
boot_list = self . widget ( " boot-list " )
2014-02-10 01:21:26 +04:00
boot_model = boot_list . get_model ( )
boot_model . clear ( )
boot_rows = self . _make_boot_rows ( )
boot_order = self . vm . get_boot_order ( )
2010-02-25 04:37:41 +03:00
2014-02-10 01:21:26 +04:00
for key in boot_order :
for row in boot_rows [ : ] :
if key != row [ BOOT_KEY ] :
continue
2010-02-25 04:37:41 +03:00
2014-02-10 01:21:26 +04:00
row [ BOOT_ACTIVE ] = True
boot_model . append ( row )
boot_rows . remove ( row )
break
2010-02-25 04:37:41 +03:00
2014-02-10 01:21:26 +04:00
for row in boot_rows :
2010-02-25 04:37:41 +03:00
boot_model . append ( row )