2006-06-28 15:50:17 -04:00
#
2014-06-26 11:51:38 +02:00
# Copyright (C) 2006-2008, 2013-2014 Red Hat, Inc.
2006-06-28 15: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 11:12:20 -05:00
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA.
2006-06-28 15:50:17 -04:00
#
2006-06-14 10:59:40 -04:00
2012-01-31 18:16:54 -05:00
import logging
2012-05-14 14:24:56 +01:00
from gi . repository import GObject
from gi . repository import Gtk
from gi . repository import Gdk
from gi . repository import GdkPixbuf
2011-04-18 12:39:53 -04:00
2016-04-18 16:42:12 -04:00
import libvirt
2013-08-09 09:23:01 -04:00
from virtinst import util
2014-09-12 16:10:45 -04:00
from . import vmmenu
from . import uiutil
from . baseclass import vmmGObjectUI
from . graphwidgets import CellRendererSparkline
2006-07-20 11:16:07 -04:00
2012-05-14 14:24:56 +01:00
# Number of data points for performance graphs
GRAPH_LEN = 40
2006-06-14 10:59:40 -04:00
2007-08-28 17:57:25 -04:00
# fields in the tree model data set
2013-04-23 12:42:41 -04:00
( ROW_HANDLE ,
2013-09-01 18:36:58 -04:00
ROW_SORT_KEY ,
2013-04-23 12:42:41 -04:00
ROW_MARKUP ,
ROW_STATUS_ICON ,
ROW_HINT ,
ROW_IS_CONN ,
ROW_IS_CONN_CONNECTED ,
ROW_IS_VM ,
ROW_IS_VM_RUNNING ,
ROW_COLOR ,
2013-09-01 18:36:58 -04:00
ROW_INSPECTION_OS_ICON ) = range ( 11 )
2007-08-27 22:22:18 -04:00
# Columns in the tree view
2013-09-02 10:43:53 -04:00
( COL_NAME ,
COL_GUEST_CPU ,
COL_HOST_CPU ,
2013-12-18 14:42:42 +01:00
COL_MEM ,
2013-09-02 10:43:53 -04:00
COL_DISK ,
2013-12-18 14:42:42 +01:00
COL_NETWORK ) = range ( 6 )
2007-08-27 22:22:18 -04:00
2013-02-16 13:54:45 -05:00
2013-04-20 12:52:25 -04:00
def _style_get_prop ( widget , propname ) :
value = GObject . Value ( )
value . init ( GObject . TYPE_INT )
widget . style_get_property ( propname , value )
return value . get_int ( )
2009-07-26 16:15:05 -04:00
2013-09-01 18:36:58 -04:00
def _get_inspection_icon_pixbuf ( vm , w , h ) :
# libguestfs gives us the PNG data as a string.
png_data = vm . inspection . icon
if png_data is None :
return None
try :
pb = GdkPixbuf . PixbufLoader ( )
pb . set_size ( w , h )
pb . write ( png_data )
pb . close ( )
return pb . get_pixbuf ( )
2017-07-24 09:26:48 +01:00
except Exception :
2013-09-01 18:36:58 -04:00
logging . exception ( " Error loading inspection icon data " )
vm . inspection . icon = None
return None
2010-12-08 17:26:19 -05:00
class vmmManager ( vmmGObjectUI ) :
2012-05-14 14:24:56 +01:00
__gsignals__ = {
" action-show-connect " : ( GObject . SignalFlags . RUN_FIRST , None , [ ] ) ,
2013-09-22 15:13:41 -04:00
" action-show-domain " : ( GObject . SignalFlags . RUN_FIRST , None , [ str , str ] ) ,
2012-05-14 14:24:56 +01:00
" action-show-about " : ( GObject . SignalFlags . RUN_FIRST , None , [ ] ) ,
" action-show-host " : ( GObject . SignalFlags . RUN_FIRST , None , [ str ] ) ,
" action-show-preferences " : ( GObject . SignalFlags . RUN_FIRST , None , [ ] ) ,
" action-show-create " : ( GObject . SignalFlags . RUN_FIRST , None , [ str ] ) ,
" action-suspend-domain " : ( GObject . SignalFlags . RUN_FIRST , None , [ str , str ] ) ,
" action-resume-domain " : ( GObject . SignalFlags . RUN_FIRST , None , [ str , str ] ) ,
" action-run-domain " : ( GObject . SignalFlags . RUN_FIRST , None , [ str , str ] ) ,
" action-shutdown-domain " : ( GObject . SignalFlags . RUN_FIRST , None , [ str , str ] ) ,
" action-reset-domain " : ( GObject . SignalFlags . RUN_FIRST , None , [ str , str ] ) ,
" action-reboot-domain " : ( GObject . SignalFlags . RUN_FIRST , None , [ str , str ] ) ,
" action-destroy-domain " : ( GObject . SignalFlags . RUN_FIRST , None , [ str , str ] ) ,
" action-save-domain " : ( GObject . SignalFlags . RUN_FIRST , None , [ str , str ] ) ,
" action-migrate-domain " : ( GObject . SignalFlags . RUN_FIRST , None , [ str , str ] ) ,
2013-06-17 17:29:51 -03:00
" action-delete-domain " : ( GObject . SignalFlags . RUN_FIRST , None , [ str , str ] ) ,
2012-05-14 14:24:56 +01:00
" action-clone-domain " : ( GObject . SignalFlags . RUN_FIRST , None , [ str , str ] ) ,
" action-exit-app " : ( GObject . SignalFlags . RUN_FIRST , None , [ ] ) ,
" manager-closed " : ( GObject . SignalFlags . RUN_FIRST , None , [ ] ) ,
" manager-opened " : ( GObject . SignalFlags . RUN_FIRST , None , [ ] ) ,
" remove-conn " : ( GObject . SignalFlags . RUN_FIRST , None , [ str ] ) ,
}
2011-07-22 13:42:20 -04:00
def __init__ ( self ) :
2013-09-22 16:10:16 -04:00
vmmGObjectUI . __init__ ( self , " manager.ui " , " vmm-manager " )
2010-11-30 14:33:21 -05:00
2014-06-02 17:17:47 -04:00
# Mapping of rowkey -> tree model rows to
2009-11-28 20:49:44 -05:00
# allow O(1) access instead of O(n)
self . rows = { }
2009-11-28 21:00:46 -05:00
w , h = self . config . get_manager_window_size ( )
2010-02-23 14:18:12 -05:00
self . topwin . set_default_size ( w or 550 , h or 550 )
2010-12-13 17:48:19 -05:00
self . prev_position = None
2015-09-13 14:07:43 -04:00
self . _window_size = None
2009-11-28 21:00:46 -05:00
2014-01-28 18:04:46 -05:00
self . vmmenu = vmmenu . VMActionMenu ( self , self . current_vm )
2012-05-14 14:24:56 +01:00
self . connmenu = Gtk . Menu ( )
2009-11-28 20:49:44 -05:00
self . connmenu_items = { }
2011-04-13 09:27:02 -04:00
2013-02-16 13:31:46 -05:00
self . builder . connect_signals ( {
2011-07-12 08:49:47 -04:00
" on_menu_view_guest_cpu_usage_activate " :
2017-08-17 19:01:28 +08:00
self . toggle_stats_visible_guest_cpu ,
2011-07-12 08:49:47 -04:00
" on_menu_view_host_cpu_usage_activate " :
2017-08-17 19:01:28 +08:00
self . toggle_stats_visible_host_cpu ,
2013-12-18 14:42:42 +01:00
" on_menu_view_memory_usage_activate " :
2017-08-17 19:01:28 +08:00
self . toggle_stats_visible_memory_usage ,
2017-08-05 14:39:32 +08:00
" on_menu_view_disk_io_activate " :
2017-08-17 19:01:28 +08:00
self . toggle_stats_visible_disk ,
2011-07-12 08:49:47 -04:00
" on_menu_view_network_traffic_activate " :
2017-08-17 19:01:28 +08:00
self . toggle_stats_visible_network ,
2009-11-28 20:49:44 -05:00
" on_vm_manager_delete_event " : self . close ,
2009-11-28 21:00:46 -05:00
" on_vmm_manager_configure_event " : self . window_resized ,
2011-07-22 16:43:26 -04:00
" on_menu_file_add_connection_activate " : self . new_conn ,
2014-02-01 13:36:02 -05:00
" on_menu_new_vm_activate " : self . new_vm ,
2009-11-28 20:49:44 -05:00
" on_menu_file_quit_activate " : self . exit_app ,
" on_menu_file_close_activate " : self . close ,
" on_vmm_close_clicked " : self . close ,
2011-06-08 16:33:20 -04:00
" on_vm_open_clicked " : self . show_vm ,
2009-11-28 20:49:44 -05:00
" on_vm_run_clicked " : self . start_vm ,
" on_vm_new_clicked " : self . new_vm ,
" on_vm_shutdown_clicked " : self . poweroff_vm ,
" on_vm_pause_clicked " : self . pause_vm_button ,
2011-06-08 16:33:20 -04:00
" on_menu_edit_details_activate " : self . show_vm ,
2009-11-28 20:49:44 -05:00
" on_menu_edit_delete_activate " : self . do_delete ,
" on_menu_host_details_activate " : self . show_host ,
2011-06-08 16:33:20 -04:00
" on_vm_list_row_activated " : self . show_vm ,
2009-11-28 20:49:44 -05:00
" on_vm_list_button_press_event " : self . popup_vm_menu_button ,
" on_vm_list_key_press_event " : self . popup_vm_menu_key ,
" on_menu_edit_preferences_activate " : self . show_preferences ,
" on_menu_help_about_activate " : self . show_about ,
2011-04-13 09:27:02 -04:00
} )
2013-09-02 10:43:53 -04:00
# There seem to be ref counting issues with calling
# list.get_column, so avoid it
self . diskcol = None
self . netcol = None
2013-12-18 14:42:42 +01:00
self . memcol = None
2013-09-02 10:43:53 -04:00
self . guestcpucol = None
self . hostcpucol = None
self . spacer_txt = None
2011-04-13 09:27:02 -04:00
self . init_vmlist ( )
2013-09-02 10:43:53 -04:00
2011-04-13 09:27:02 -04:00
self . init_stats ( )
self . init_toolbar ( )
self . init_context_menus ( )
2009-11-28 20:49:44 -05:00
2013-09-02 09:09:31 -04:00
self . update_current_selection ( )
self . widget ( " vm-list " ) . get_selection ( ) . connect (
" changed " , self . update_current_selection )
2009-11-28 20:49:44 -05:00
2011-07-25 15:09:42 -04:00
self . max_disk_rate = 10.0
self . max_net_rate = 10.0
2009-11-28 20:49:44 -05:00
# Initialize stat polling columns based on global polling
# preferences (we want signal handlers for this)
2014-02-11 15:29:30 -05:00
self . enable_polling ( COL_GUEST_CPU )
2013-04-17 17:39:25 -04:00
self . enable_polling ( COL_DISK )
self . enable_polling ( COL_NETWORK )
2014-01-12 17:39:21 -05:00
self . enable_polling ( COL_MEM )
2009-11-28 20:49:44 -05:00
##################
# Common methods #
##################
def show ( self ) :
2010-12-08 17:26:19 -05:00
vis = self . is_visible ( )
2010-02-23 14:18:12 -05:00
self . topwin . present ( )
2010-12-08 17:26:19 -05:00
if vis :
return
2010-02-23 14:18:12 -05:00
2013-06-13 09:18:46 -04:00
logging . debug ( " Showing manager " )
2010-12-13 17:48:19 -05:00
if self . prev_position :
self . topwin . move ( * self . prev_position )
self . prev_position = None
2011-04-13 10:47:31 -04:00
self . emit ( " manager-opened " )
2009-11-28 20:49:44 -05:00
2010-12-09 11:22:35 -05:00
def close ( self , src_ignore = None , src2_ignore = None ) :
2010-12-08 17:26:19 -05:00
if not self . is_visible ( ) :
return
2013-06-13 09:18:46 -04:00
logging . debug ( " Closing manager " )
2010-12-13 17:48:19 -05:00
self . prev_position = self . topwin . get_position ( )
2010-12-08 17:26:19 -05:00
self . topwin . hide ( )
2011-04-13 10:47:31 -04:00
self . emit ( " manager-closed " )
2010-12-08 17:26:19 -05:00
return 1
2009-11-28 20:49:44 -05:00
2011-04-13 09:27:02 -04:00
2011-07-23 21:16:54 -04:00
def _cleanup ( self ) :
self . rows = None
2011-04-13 09:27:02 -04:00
2011-07-23 21:16:54 -04:00
self . diskcol = None
self . guestcpucol = None
2013-12-18 14:42:42 +01:00
self . memcol = None
2011-07-23 21:16:54 -04:00
self . hostcpucol = None
self . netcol = None
2011-04-13 09:27:02 -04:00
2014-04-02 18:39:43 -04:00
self . vmmenu . destroy ( )
2011-07-23 21:16:54 -04:00
self . vmmenu = None
self . connmenu . destroy ( )
self . connmenu = None
self . connmenu_items = None
2011-04-13 09:27:02 -04:00
2015-09-13 14:07:43 -04:00
if self . _window_size :
self . config . set_manager_window_size ( * self . _window_size )
2009-11-28 20:49:44 -05:00
def is_visible ( self ) :
2012-05-14 14:24:56 +01:00
return bool ( self . topwin . get_visible ( ) )
2009-11-28 20:49:44 -05:00
2010-03-02 20:35:54 -05:00
def set_startup_error ( self , msg ) :
2011-07-14 13:13:13 -04:00
self . widget ( " vm-notebook " ) . set_current_page ( 1 )
self . widget ( " startup-error-label " ) . set_text ( msg )
2006-06-14 10:59:40 -04:00
2009-11-28 20:49:44 -05:00
################
# Init methods #
################
def init_stats ( self ) :
2014-09-28 13:37:16 +02:00
self . add_gsettings_handle (
2011-07-12 08:49:47 -04:00
self . config . on_vmlist_guest_cpu_usage_visible_changed (
self . toggle_guest_cpu_usage_visible_widget ) )
2014-09-28 13:37:16 +02:00
self . add_gsettings_handle (
2011-07-12 08:49:47 -04:00
self . config . on_vmlist_host_cpu_usage_visible_changed (
self . toggle_host_cpu_usage_visible_widget ) )
2014-09-28 13:37:16 +02:00
self . add_gsettings_handle (
2013-12-18 14:42:42 +01:00
self . config . on_vmlist_memory_usage_visible_changed (
self . toggle_memory_usage_visible_widget ) )
2014-09-28 13:37:16 +02:00
self . add_gsettings_handle (
2011-04-13 09:27:02 -04:00
self . config . on_vmlist_disk_io_visible_changed (
2011-07-12 08:49:47 -04:00
self . toggle_disk_io_visible_widget ) )
2014-09-28 13:37:16 +02:00
self . add_gsettings_handle (
2011-04-13 09:27:02 -04:00
self . config . on_vmlist_network_traffic_visible_changed (
self . toggle_network_traffic_visible_widget ) )
2006-06-14 10:59:40 -04:00
2008-12-17 15:27:06 -05:00
# Register callbacks with the global stats enable/disable values
# that disable the associated vmlist widgets if reporting is disabled
2014-09-28 13:37:16 +02:00
self . add_gsettings_handle (
2014-02-11 15:29:30 -05:00
self . config . on_stats_enable_cpu_poll_changed (
self . enable_polling , COL_GUEST_CPU ) )
2014-09-28 13:37:16 +02:00
self . add_gsettings_handle (
2014-02-11 15:29:30 -05:00
self . config . on_stats_enable_disk_poll_changed (
self . enable_polling , COL_DISK ) )
2014-09-28 13:37:16 +02:00
self . add_gsettings_handle (
2014-02-11 15:29:30 -05:00
self . config . on_stats_enable_net_poll_changed (
self . enable_polling , COL_NETWORK ) )
2014-09-28 13:37:16 +02:00
self . add_gsettings_handle (
2014-01-12 17:39:21 -05:00
self . config . on_stats_enable_memory_poll_changed (
2014-02-11 15:29:30 -05:00
self . enable_polling , COL_MEM ) )
2011-04-13 09:27:02 -04:00
2013-09-01 21:35:23 -04:00
self . toggle_guest_cpu_usage_visible_widget ( )
self . toggle_host_cpu_usage_visible_widget ( )
2013-12-18 14:42:42 +01:00
self . toggle_memory_usage_visible_widget ( )
2013-09-01 21:35:23 -04:00
self . toggle_disk_io_visible_widget ( )
self . toggle_network_traffic_visible_widget ( )
2008-12-17 15:27:06 -05:00
2009-11-11 11:02:57 -05:00
2009-11-28 20:49:44 -05:00
def init_toolbar ( self ) :
2011-07-14 13:13:13 -04:00
self . widget ( " vm-new " ) . set_icon_name ( " vm_new " )
self . widget ( " vm-open " ) . set_icon_name ( " icon_console " )
2013-09-22 13:24:59 -04:00
2014-01-28 18:04:46 -05:00
menu = vmmenu . VMShutdownMenu ( self , self . current_vm )
2013-09-22 13:24:59 -04:00
self . widget ( " vm-shutdown " ) . set_icon_name ( " system-shutdown " )
self . widget ( " vm-shutdown " ) . set_menu ( menu )
2011-07-14 13:13:13 -04:00
tool = self . widget ( " vm-toolbar " )
2012-05-14 14:24:56 +01:00
tool . set_property ( " icon-size " , Gtk . IconSize . LARGE_TOOLBAR )
2009-11-10 12:57:28 -05:00
for c in tool . get_children ( ) :
2009-07-26 16:25:01 -04:00
c . set_homogeneous ( False )
2009-11-28 20:49:44 -05:00
def init_context_menus ( self ) :
2013-09-22 15:13:41 -04:00
def add_to_menu ( idx , text , icon , cb ) :
2012-05-14 14:24:56 +01:00
if text [ 0 : 3 ] == ' gtk ' :
item = Gtk . ImageMenuItem . new_from_stock ( text , None )
else :
item = Gtk . ImageMenuItem . new_with_mnemonic ( text )
2010-05-12 15:31:36 -04:00
if icon :
item . set_image ( icon )
if cb :
item . connect ( " activate " , cb )
2013-09-22 15:13:41 -04:00
self . connmenu . add ( item )
self . connmenu_items [ idx ] = item
2006-06-14 10:59:40 -04:00
2010-05-12 15:31:36 -04:00
# Build connection context menu
2013-09-22 15:13:41 -04:00
add_to_menu ( " create " , Gtk . STOCK_NEW , None , self . new_vm )
add_to_menu ( " connect " , Gtk . STOCK_CONNECT , None , self . open_conn )
add_to_menu ( " disconnect " , Gtk . STOCK_DISCONNECT , None ,
2011-07-22 16:43:26 -04:00
self . close_conn )
2013-09-22 15:13:41 -04:00
self . connmenu . add ( Gtk . SeparatorMenuItem ( ) )
add_to_menu ( " delete " , Gtk . STOCK_DELETE , None , self . do_delete )
self . connmenu . add ( Gtk . SeparatorMenuItem ( ) )
add_to_menu ( " details " , _ ( " D_etails " ) , None , self . show_host )
self . connmenu . show_all ( )
2007-08-13 17:13:39 -04:00
2009-11-28 20:49:44 -05:00
def init_vmlist ( self ) :
2011-07-14 13:13:13 -04:00
vmlist = self . widget ( " vm-list " )
self . widget ( " vm-notebook " ) . set_show_tabs ( False )
2006-06-14 10:59:40 -04:00
2013-04-23 12:42:41 -04:00
rowtypes = [ ]
rowtypes . insert ( ROW_HANDLE , object ) # backing object
2013-09-01 18:36:58 -04:00
rowtypes . insert ( ROW_SORT_KEY , str ) # object name
2013-04-23 12:42:41 -04:00
rowtypes . insert ( ROW_MARKUP , str ) # row markup text
rowtypes . insert ( ROW_STATUS_ICON , str ) # status icon name
rowtypes . insert ( ROW_HINT , str ) # row tooltip
rowtypes . insert ( ROW_IS_CONN , bool ) # if object is a connection
rowtypes . insert ( ROW_IS_CONN_CONNECTED , bool ) # if conn is connected
rowtypes . insert ( ROW_IS_VM , bool ) # if row is VM
rowtypes . insert ( ROW_IS_VM_RUNNING , bool ) # if VM is running
2013-04-23 13:04:33 -04:00
rowtypes . insert ( ROW_COLOR , str ) # row markup color string
2013-04-23 14:24:52 -04:00
rowtypes . insert ( ROW_INSPECTION_OS_ICON , GdkPixbuf . Pixbuf ) # OS icon
2013-04-23 12:42:41 -04:00
model = Gtk . TreeStore ( * rowtypes )
2009-11-28 20:49:44 -05:00
vmlist . set_model ( model )
2012-02-01 17:26:46 -05:00
vmlist . set_tooltip_column ( ROW_HINT )
2009-11-28 20:49:44 -05:00
vmlist . set_headers_visible ( True )
2013-04-20 12:52:53 -04:00
vmlist . set_level_indentation (
- ( _style_get_prop ( vmlist , " expander-size " ) + 3 ) )
2006-06-14 10:59:40 -04:00
2012-05-14 14:24:56 +01:00
nameCol = Gtk . TreeViewColumn ( _ ( " Name " ) )
2009-11-28 20:49:44 -05:00
nameCol . set_expand ( True )
2013-09-10 16:07:11 +02:00
nameCol . set_sizing ( Gtk . TreeViewColumnSizing . AUTOSIZE )
2009-11-28 20:49:44 -05:00
nameCol . set_spacing ( 6 )
2013-09-02 10:43:53 -04:00
nameCol . set_sort_column_id ( COL_NAME )
2006-11-06 10:34:54 -05:00
2009-11-28 20:49:44 -05:00
vmlist . append_column ( nameCol )
2008-12-17 15:27:06 -05:00
2012-05-14 14:24:56 +01:00
status_icon = Gtk . CellRendererPixbuf ( )
status_icon . set_property ( " stock-size " , Gtk . IconSize . DND )
2013-09-02 10:43:53 -04:00
nameCol . pack_start ( status_icon , False )
nameCol . add_attribute ( status_icon , ' icon-name ' , ROW_STATUS_ICON )
nameCol . add_attribute ( status_icon , ' visible ' , ROW_IS_VM )
2009-03-09 16:22:03 -04:00
2012-05-14 14:24:56 +01:00
inspection_os_icon = Gtk . CellRendererPixbuf ( )
2013-09-02 10:43:53 -04:00
nameCol . pack_start ( inspection_os_icon , False )
nameCol . add_attribute ( inspection_os_icon , ' pixbuf ' ,
2011-07-18 19:53:56 +01:00
ROW_INSPECTION_OS_ICON )
2013-09-02 10:43:53 -04:00
nameCol . add_attribute ( inspection_os_icon , ' visible ' , ROW_IS_VM )
2011-07-18 19:53:56 +01:00
2012-05-14 14:24:56 +01:00
name_txt = Gtk . CellRendererText ( )
2009-11-28 20:49:44 -05:00
nameCol . pack_start ( name_txt , True )
nameCol . add_attribute ( name_txt , ' markup ' , ROW_MARKUP )
2013-04-23 13:04:33 -04:00
nameCol . add_attribute ( name_txt , ' foreground ' , ROW_COLOR )
2013-09-02 10:43:53 -04:00
self . spacer_txt = Gtk . CellRendererText ( )
self . spacer_txt . set_property ( " ypad " , 4 )
self . spacer_txt . set_property ( " visible " , False )
nameCol . pack_end ( self . spacer_txt , False )
2007-09-09 22:57:24 -04:00
2013-09-01 21:35:23 -04:00
def make_stats_column ( title , colnum ) :
2012-05-14 14:24:56 +01:00
col = Gtk . TreeViewColumn ( title )
2011-07-12 08:49:47 -04:00
col . set_min_width ( 140 )
2013-04-20 14:11:31 -04:00
2012-05-14 14:24:56 +01:00
txt = Gtk . CellRendererText ( )
2013-04-20 13:43:21 -04:00
txt . set_property ( " ypad " , 4 )
2013-04-20 14:11:31 -04:00
col . pack_start ( txt , True )
col . add_attribute ( txt , ' visible ' , ROW_IS_CONN )
2011-07-12 08:49:47 -04:00
img = CellRendererSparkline ( )
img . set_property ( " xpad " , 6 )
img . set_property ( " ypad " , 12 )
img . set_property ( " reversed " , True )
col . pack_start ( img , True )
col . add_attribute ( img , ' visible ' , ROW_IS_VM )
2013-04-20 14:11:31 -04:00
2011-07-12 08:49:47 -04:00
col . set_sort_column_id ( colnum )
vmlist . append_column ( col )
return col
2013-09-01 21:35:23 -04:00
self . guestcpucol = make_stats_column ( _ ( " CPU usage " ) , COL_GUEST_CPU )
self . hostcpucol = make_stats_column ( _ ( " Host CPU usage " ) , COL_HOST_CPU )
2013-12-18 14:42:42 +01:00
self . memcol = make_stats_column ( _ ( " Memory usage " ) , COL_MEM )
2013-09-01 21:35:23 -04:00
self . diskcol = make_stats_column ( _ ( " Disk I/O " ) , COL_DISK )
self . netcol = make_stats_column ( _ ( " Network I/O " ) , COL_NETWORK )
2006-06-14 10:59:40 -04:00
2009-11-28 20:49:44 -05:00
model . set_sort_func ( COL_NAME , self . vmlist_name_sorter )
2011-07-12 08:49:47 -04:00
model . set_sort_func ( COL_GUEST_CPU , self . vmlist_guest_cpu_usage_sorter )
model . set_sort_func ( COL_HOST_CPU , self . vmlist_host_cpu_usage_sorter )
2013-12-18 14:42:42 +01:00
model . set_sort_func ( COL_MEM , self . vmlist_memory_usage_sorter )
2009-11-28 20:49:44 -05:00
model . set_sort_func ( COL_DISK , self . vmlist_disk_io_sorter )
model . set_sort_func ( COL_NETWORK , self . vmlist_network_usage_sorter )
2012-05-14 14:24:56 +01:00
model . set_sort_column_id ( COL_NAME , Gtk . SortType . ASCENDING )
2009-11-28 20:49:44 -05:00
##################
# Helper methods #
##################
def current_row ( self ) :
2015-05-19 17:17:53 -04:00
return uiutil . get_list_selected_row ( self . widget ( " vm-list " ) )
2009-11-28 20:49:44 -05:00
def current_vm ( self ) :
row = self . current_row ( )
if not row or row [ ROW_IS_CONN ] :
return None
return row [ ROW_HANDLE ]
2011-07-22 16:43:26 -04:00
def current_conn ( self ) :
2009-11-28 20:49:44 -05:00
row = self . current_row ( )
if not row :
return None
handle = row [ ROW_HANDLE ]
if row [ ROW_IS_CONN ] :
return handle
else :
2011-07-22 16:43:26 -04:00
return handle . conn
2009-11-28 20:49:44 -05:00
2011-07-22 16:43:26 -04:00
def current_conn_uri ( self , default_selection = False ) :
2011-07-14 13:13:13 -04:00
vmlist = self . widget ( " vm-list " )
2010-08-22 12:50:31 -04:00
model = vmlist . get_model ( )
2011-07-22 16:43:26 -04:00
conn = self . current_conn ( )
2010-08-22 12:50:31 -04:00
if conn is None and default_selection :
# Nothing selected, use first connection row
for row in model :
if row [ ROW_IS_CONN ] :
conn = row [ ROW_HANDLE ]
break
if conn :
return conn . get_uri ( )
return None
2009-11-28 20:49:44 -05:00
####################
# Action listeners #
####################
2006-11-03 10:02:02 -05:00
2016-12-13 13:27:06 -05:00
def window_resized ( self , ignore , ignore2 ) :
2009-11-28 21:00:46 -05:00
if not self . is_visible ( ) :
return
2016-12-13 13:27:06 -05:00
self . _window_size = self . topwin . get_size ( )
2009-11-28 21:00:46 -05:00
2010-12-09 11:22:35 -05:00
def exit_app ( self , src_ignore = None , src2_ignore = None ) :
2008-06-13 14:40:26 -04:00
self . emit ( " action-exit-app " )
2006-06-14 10:59:40 -04:00
2011-07-22 16:43:26 -04:00
def new_conn ( self , src_ignore = None ) :
2006-06-27 14:16:13 -04:00
self . emit ( " action-show-connect " )
2006-06-14 10:59:40 -04:00
2010-12-09 11:22:35 -05:00
def new_vm ( self , src_ignore = None ) :
2011-07-22 16:43:26 -04:00
self . emit ( " action-show-create " , self . current_conn_uri ( ) )
2009-11-28 20:49:44 -05:00
2010-12-09 11:22:35 -05:00
def show_about ( self , src_ignore ) :
2009-11-28 20:49:44 -05:00
self . emit ( " action-show-about " )
2010-12-09 11:22:35 -05:00
def show_preferences ( self , src_ignore ) :
2009-11-28 20:49:44 -05:00
self . emit ( " action-show-preferences " )
2010-12-09 11:22:35 -05:00
def show_host ( self , src_ignore ) :
2011-07-22 16:43:26 -04:00
uri = self . current_conn_uri ( default_selection = True )
2010-08-22 12:50:31 -04:00
self . emit ( " action-show-host " , uri )
2009-11-28 20:49:44 -05:00
2011-06-08 16:33:20 -04:00
def show_vm ( self , ignore , ignore2 = None , ignore3 = None ) :
2011-07-22 16:43:26 -04:00
conn = self . current_conn ( )
2011-06-08 16:33:20 -04:00
vm = self . current_vm ( )
if conn is None :
return
if vm :
2014-06-02 17:17:47 -04:00
self . emit ( " action-show-domain " , conn . get_uri ( ) , vm . get_connkey ( ) )
2011-06-08 16:33:20 -04:00
else :
2011-07-22 16:43:26 -04:00
if not self . open_conn ( ) :
2011-06-08 16:33:20 -04:00
self . emit ( " action-show-host " , conn . get_uri ( ) )
2009-11-28 20:49:44 -05:00
def do_delete ( self , ignore = None ) :
2011-07-22 16:43:26 -04:00
conn = self . current_conn ( )
2009-11-28 20:49:44 -05:00
vm = self . current_vm ( )
if vm is None :
2011-07-22 16:43:26 -04:00
self . _do_delete_conn ( conn )
2009-11-28 20:49:44 -05:00
else :
2014-06-02 17:17:47 -04:00
self . emit ( " action-delete-domain " , conn . get_uri ( ) , vm . get_connkey ( ) )
2009-11-28 20:49:44 -05:00
2011-07-22 16:43:26 -04:00
def _do_delete_conn ( self , conn ) :
2009-11-28 20:49:44 -05:00
if conn is None :
return
result = self . err . yes_no ( _ ( " This will remove the connection: \n \n %s \n \n "
" Are you sure? " ) % conn . get_uri ( ) )
if not result :
return
2011-07-22 13:42:20 -04:00
2011-07-22 16:43:26 -04:00
self . emit ( " remove-conn " , conn . get_uri ( ) )
2009-11-28 20:49:44 -05:00
def set_pause_state ( self , state ) :
2011-07-14 13:13:13 -04:00
src = self . widget ( " vm-pause " )
2009-11-28 20:49:44 -05:00
try :
2015-11-10 18:30:31 -05:00
src . handler_block_by_func ( self . pause_vm_button )
2009-11-28 20:49:44 -05:00
src . set_active ( state )
finally :
2015-11-10 18:30:31 -05:00
src . handler_unblock_by_func ( self . pause_vm_button )
2009-11-28 20:49:44 -05:00
def pause_vm_button ( self , src ) :
do_pause = src . get_active ( )
2011-04-15 14:49:58 -04: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 )
2009-11-28 20:49:44 -05:00
if do_pause :
self . pause_vm ( None )
else :
self . resume_vm ( None )
def start_vm ( self , ignore ) :
vm = self . current_vm ( )
2014-06-02 17:17:47 -04:00
if vm is None :
return
self . emit ( " action-run-domain " , vm . conn . get_uri ( ) , vm . get_connkey ( ) )
2009-11-28 20:49:44 -05:00
def poweroff_vm ( self , ignore ) :
vm = self . current_vm ( )
2014-06-02 17:17:47 -04:00
if vm is None :
return
self . emit ( " action-shutdown-domain " ,
vm . conn . get_uri ( ) , vm . get_connkey ( ) )
2009-11-28 20:49:44 -05:00
def pause_vm ( self , ignore ) :
vm = self . current_vm ( )
2014-06-02 17:17:47 -04:00
if vm is None :
return
self . emit ( " action-suspend-domain " , vm . conn . get_uri ( ) , vm . get_connkey ( ) )
2009-11-28 20:49:44 -05:00
def resume_vm ( self , ignore ) :
vm = self . current_vm ( )
2014-06-02 17:17:47 -04:00
if vm is None :
return
self . emit ( " action-resume-domain " , vm . conn . get_uri ( ) , vm . get_connkey ( ) )
2009-11-28 20:49:44 -05:00
2011-07-22 16:43:26 -04:00
def close_conn ( self , ignore ) :
conn = self . current_conn ( )
2014-09-11 18:16:21 -04:00
if not conn . is_disconnected ( ) :
2009-11-28 20:49:44 -05:00
conn . close ( )
2011-07-22 16:43:26 -04:00
def open_conn ( self , ignore = None ) :
conn = self . current_conn ( )
2014-09-11 18:16:21 -04:00
if conn . is_disconnected ( ) :
2009-11-28 20:49:44 -05:00
conn . open ( )
return True
####################################
# VM add/remove management methods #
####################################
def vm_row_key ( self , vm ) :
2011-07-22 16:43:26 -04:00
return vm . get_uuid ( ) + " : " + vm . conn . get_uri ( )
2006-07-20 11:16:07 -04:00
2014-06-02 17:17:47 -04:00
def vm_added ( self , conn , connkey ) :
vm = conn . get_vm ( connkey )
2016-05-19 19:31:22 -04:00
if not vm :
2014-02-13 11:16:48 -05:00
return
2016-05-19 19:31:22 -04:00
row_key = self . vm_row_key ( vm )
if row_key in self . rows :
return
row = self . _build_row ( None , vm )
parent = self . rows [ conn . get_uri ( ) ] . iter
model = self . widget ( " vm-list " ) . get_model ( )
_iter = model . append ( parent , row )
path = model . get_path ( _iter )
self . rows [ row_key ] = model [ path ]
2015-04-09 18:02:42 -04:00
vm . connect ( " state-changed " , self . vm_changed )
2013-09-02 09:09:31 -04:00
vm . connect ( " resources-sampled " , self . vm_row_updated )
2011-07-18 19:53:56 +01:00
vm . connect ( " inspection-changed " , self . vm_inspection_changed )
2006-06-14 17:52:49 -04:00
2016-05-19 19:31:22 -04:00
# Expand a connection when adding a vm to it
self . widget ( " vm-list " ) . expand_row ( model . get_path ( parent ) , False )
2006-06-14 10:59:40 -04:00
2014-06-02 17:17:47 -04:00
def vm_removed ( self , conn , connkey ) :
2011-07-14 13:13:13 -04:00
vmlist = self . widget ( " vm-list " )
2009-11-28 20:49:44 -05:00
model = vmlist . get_model ( )
2011-07-22 13:54:40 -04:00
parent = self . rows [ conn . get_uri ( ) ] . iter
2009-11-28 20:49:44 -05:00
for row in range ( model . iter_n_children ( parent ) ) :
2014-01-26 20:21:12 -05:00
vm = model [ model . iter_nth_child ( parent , row ) ] [ ROW_HANDLE ]
2014-06-02 17:17:47 -04:00
if vm . get_connkey ( ) == connkey :
2009-11-28 20:49:44 -05:00
model . remove ( model . iter_nth_child ( parent , row ) )
del self . rows [ self . vm_row_key ( vm ) ]
break
2009-10-21 10:36:58 -04:00
def _build_conn_hint ( self , conn ) :
hint = conn . get_uri ( )
2014-09-11 18:16:21 -04:00
if conn . is_disconnected ( ) :
2009-10-21 10:36:58 -04:00
hint + = " ( %s ) " % _ ( " Double click to connect " )
return hint
2013-09-01 18:36:58 -04:00
def _build_conn_markup ( self , conn , name ) :
name = util . xml_escape ( name )
2011-08-29 12:11:43 -04:00
text = name
2014-09-11 18:16:21 -04:00
if conn . is_disconnected ( ) :
2011-08-29 12:11:43 -04:00
text + = " - " + _ ( " Not Connected " )
2014-09-11 18:16:21 -04:00
elif conn . is_connecting ( ) :
2011-08-29 12:11:43 -04:00
text + = " - " + _ ( " Connecting... " )
2010-12-01 15:22:38 -05:00
markup = " <span size= ' smaller ' > %s </span> " % text
2009-09-17 12:35:41 -04:00
return markup
2009-11-10 15:42:07 -05:00
def _build_conn_color ( self , conn ) :
2013-04-23 13:04:33 -04:00
color = " #000000 "
2014-09-11 18:16:21 -04:00
if conn . is_disconnected ( ) :
2013-04-23 13:04:33 -04:00
color = " #5b5b5b "
2009-11-10 15:42:07 -05:00
return color
2013-09-01 18:36:58 -04:00
def _build_vm_markup ( self , name , status ) :
2010-12-01 15:22:38 -05:00
domtext = ( " <span size= ' smaller ' weight= ' bold ' > %s </span> " %
2013-09-01 18:36:58 -04:00
util . xml_escape ( name ) )
statetext = " <span size= ' smaller ' > %s </span> " % status
2010-12-01 15:22:38 -05:00
return domtext + " \n " + statetext
2009-09-17 12:35:41 -04:00
2013-09-01 18:36:58 -04:00
def _build_row ( self , conn , vm ) :
if conn :
2015-04-11 12:57:32 -04:00
name = conn . get_pretty_desc ( )
2013-09-01 18:36:58 -04:00
markup = self . _build_conn_markup ( conn , name )
status = ( " <span size= ' smaller ' > %s </span> " %
conn . get_state_text ( ) )
status_icon = None
hint = self . _build_conn_hint ( conn )
color = self . _build_conn_color ( conn )
os_icon = None
else :
2013-10-04 11:50:19 -04:00
name = vm . get_name_or_title ( )
2013-09-01 18:36:58 -04:00
status = vm . run_status ( )
markup = self . _build_vm_markup ( name , status )
status_icon = vm . run_status_icon_name ( )
hint = vm . get_description ( )
color = None
os_icon = _get_inspection_icon_pixbuf ( vm , 16 , 16 )
2011-09-26 11:05:55 -04:00
2013-09-01 18:36:58 -04:00
row = [ ]
row . insert ( ROW_HANDLE , conn or vm )
row . insert ( ROW_SORT_KEY , name )
row . insert ( ROW_MARKUP , markup )
row . insert ( ROW_STATUS_ICON , status_icon )
row . insert ( ROW_HINT , util . xml_escape ( hint ) )
row . insert ( ROW_IS_CONN , bool ( conn ) )
row . insert ( ROW_IS_CONN_CONNECTED ,
2014-09-11 18:16:21 -04:00
bool ( conn ) and not conn . is_disconnected ( ) )
2013-09-01 18:36:58 -04:00
row . insert ( ROW_IS_VM , bool ( vm ) )
row . insert ( ROW_IS_VM_RUNNING , bool ( vm ) and vm . is_active ( ) )
row . insert ( ROW_COLOR , color )
row . insert ( ROW_INSPECTION_OS_ICON , os_icon )
2009-09-17 12:35:41 -04:00
2011-03-23 16:56:12 -04:00
return row
2011-07-22 16:43:26 -04:00
def add_conn ( self , engine_ignore , conn ) :
2014-06-26 09:05:34 -04:00
# Called from engine.py signal conn-added
2010-03-02 20:35:54 -05:00
# Make sure error page isn't showing
2011-07-14 13:13:13 -04:00
self . widget ( " vm-notebook " ) . set_current_page ( 0 )
2010-03-02 20:35:54 -05:00
2010-12-10 11:47:07 -05:00
if conn . get_uri ( ) in self . rows :
2009-11-28 20:49:44 -05:00
return
2016-05-19 19:31:22 -04:00
model = self . widget ( " vm-list " ) . get_model ( )
row = self . _build_row ( conn , None )
_iter = model . append ( None , row )
path = model . get_path ( _iter )
self . rows [ conn . get_uri ( ) ] = model [ path ]
2016-05-19 19:23:46 -04:00
2009-11-28 20:49:44 -05:00
conn . connect ( " vm-added " , self . vm_added )
conn . connect ( " vm-removed " , self . vm_removed )
2013-09-02 09:09:31 -04:00
conn . connect ( " resources-sampled " , self . conn_row_updated )
2009-11-28 20:49:44 -05:00
conn . connect ( " state-changed " , self . conn_state_changed )
2011-07-22 16:43:26 -04:00
def remove_conn ( self , engine_ignore , uri ) :
2014-06-26 09:05:34 -04:00
# Called from engine.py signal conn-removed
2011-07-14 13:13:13 -04:00
model = self . widget ( " vm-list " ) . get_model ( )
2011-04-12 11:50:10 -04:00
parent = self . rows [ uri ] . iter
if parent is None :
return
child = model . iter_children ( parent )
while child is not None :
2014-01-26 20:21:12 -05:00
del self . rows [ self . vm_row_key ( model [ child ] [ ROW_HANDLE ] ) ]
2011-04-12 11:50:10 -04:00
model . remove ( child )
2009-11-28 20:49:44 -05:00
child = model . iter_children ( parent )
2011-04-12 11:50:10 -04:00
model . remove ( parent )
del self . rows [ uri ]
2009-11-28 20:49:44 -05:00
#############################
# State/UI updating methods #
#############################
2006-06-14 10:59:40 -04:00
2013-09-02 09:09:31 -04:00
def vm_row_updated ( self , vm ) :
row = self . rows . get ( self . vm_row_key ( vm ) , None )
if row is None :
return
self . widget ( " vm-list " ) . get_model ( ) . row_changed ( row . path , row . iter )
2006-06-14 18:42:04 -04:00
2015-04-09 18:02:42 -04:00
def vm_changed ( self , vm ) :
2013-09-01 18:36:58 -04:00
row = self . rows . get ( self . vm_row_key ( vm ) , None )
if row is None :
2006-11-13 15:38:10 -05:00
return
2013-08-16 15:59:33 +02:00
try :
2015-04-09 18:02:42 -04:00
if vm == self . current_vm ( ) :
self . update_current_selection ( )
2013-10-04 11:50:19 -04:00
name = vm . get_name_or_title ( )
2013-09-01 18:36:58 -04:00
status = vm . run_status ( )
row [ ROW_SORT_KEY ] = name
2013-08-16 15:59:33 +02:00
row [ ROW_STATUS_ICON ] = vm . run_status_icon_name ( )
row [ ROW_IS_VM_RUNNING ] = vm . is_active ( )
2013-09-01 18:36:58 -04:00
row [ ROW_MARKUP ] = self . _build_vm_markup ( name , status )
2013-08-16 15:59:33 +02:00
2013-09-02 09:09:31 -04:00
desc = vm . get_description ( )
row [ ROW_HINT ] = util . xml_escape ( desc )
2017-05-05 12:47:21 -04:00
except libvirt . libvirtError as e :
2014-01-26 17:42:24 -05:00
if util . exception_is_libvirt_error ( e , " VIR_ERR_NO_DOMAIN " ) :
2013-08-16 15:59:33 +02:00
return
raise
2011-07-15 15:38:59 -04:00
2013-09-02 09:09:31 -04:00
self . vm_row_updated ( vm )
2011-07-18 19:53:56 +01:00
def vm_inspection_changed ( self , vm ) :
2013-09-01 18:36:58 -04:00
row = self . rows . get ( self . vm_row_key ( vm ) , None )
if row is None :
2011-07-18 19:53:56 +01:00
return
2013-09-01 18:36:58 -04:00
new_icon = _get_inspection_icon_pixbuf ( vm , 16 , 16 )
inspection: Check can_set_row_none before setting icon to None.
Previously one could set the icon field of a tree model to None, but
with Gtk3 and older versions of pygobject3 this would fail.
Use can_set_row_none to test for this condition and work around it.
The previous traceback was:
Traceback (most recent call last):
File "/home/rjones/d/virt-manager/virtManager/manager.py", line 981, in vm_inspection_changed
self.get_inspection_icon_pixbuf(vm, 16, 16)
File "/usr/lib64/python2.7/site-packages/gi/overrides/Gtk.py", line 1152, in __setitem__
self.model.set_value(self.iter, key, value)
File "/usr/lib64/python2.7/site-packages/gi/overrides/Gtk.py", line 1298, in set_value
Gtk.TreeStore.set_value(self, treeiter, column, value)
File "/usr/lib64/python2.7/site-packages/gi/types.py", line 47, in function
return info.invoke(*args, **kwargs)
TypeError: Argument 3 does not allow None as a value
2013-06-28 18:45:53 +01:00
row [ ROW_INSPECTION_OS_ICON ] = new_icon
2013-06-13 16:10:28 -04:00
2013-09-02 09:09:31 -04:00
self . vm_row_updated ( vm )
2008-01-02 17:55:26 -05:00
2014-06-26 11:51:38 +02:00
def set_initial_selection ( self , uri ) :
vmlist = self . widget ( " vm-list " )
model = vmlist . get_model ( )
it = model . get_iter_first ( )
selected = None
while it :
key = model . get_value ( it , ROW_HANDLE )
if key . get_uri ( ) == uri :
vmlist . get_selection ( ) . select_iter ( it )
return
if not selected :
vmlist . get_selection ( ) . select_iter ( it )
selected = key
elif key . get_autoconnect ( ) and not selected . get_autoconnect ( ) :
vmlist . get_selection ( ) . select_iter ( it )
selected = key
if not uri :
return
it = model . iter_next ( it )
2015-04-11 13:39:25 -04:00
def conn_state_changed ( self , conn ) :
2007-09-09 22:57:24 -04:00
row = self . rows [ conn . get_uri ( ) ]
2015-04-11 13:39:25 -04:00
row [ ROW_SORT_KEY ] = conn . get_pretty_desc ( )
2013-09-01 18:36:58 -04:00
row [ ROW_MARKUP ] = self . _build_conn_markup ( conn , row [ ROW_SORT_KEY ] )
2014-09-11 18:16:21 -04:00
row [ ROW_IS_CONN_CONNECTED ] = not conn . is_disconnected ( )
2009-11-28 20:49:44 -05:00
row [ ROW_COLOR ] = self . _build_conn_color ( conn )
2011-07-15 15:38:59 -04:00
row [ ROW_HINT ] = self . _build_conn_hint ( conn )
2006-08-08 17:02:15 -04:00
2014-09-11 18:16:21 -04:00
if not conn . is_active ( ) :
2009-11-28 20:49:44 -05:00
# Connection went inactive, delete any VM child nodes
2013-09-02 09:09:31 -04:00
parent = row . iter
2009-11-28 20:49:44 -05:00
if parent is not None :
2013-09-02 09:09:31 -04:00
model = self . widget ( " vm-list " ) . get_model ( )
2009-11-28 20:49:44 -05:00
child = model . iter_children ( parent )
while child is not None :
2013-09-02 09:09:31 -04:00
vm = model [ child ] [ ROW_HANDLE ]
del self . rows [ self . vm_row_key ( vm ) ]
2009-11-28 20:49:44 -05:00
model . remove ( child )
child = model . iter_children ( parent )
2011-07-25 15:09:42 -04:00
2013-09-02 09:09:31 -04:00
self . conn_row_updated ( conn )
self . update_current_selection ( )
def conn_row_updated ( self , conn ) :
row = self . rows [ conn . get_uri ( ) ]
2011-07-25 15:09:42 -04:00
self . max_disk_rate = max ( self . max_disk_rate , conn . disk_io_max_rate ( ) )
self . max_net_rate = max ( self . max_net_rate ,
conn . network_traffic_max_rate ( ) )
2013-09-02 09:09:31 -04:00
self . widget ( " vm-list " ) . get_model ( ) . row_changed ( row . path , row . iter )
2006-06-14 10:59:40 -04:00
2010-05-12 12: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 15:13:41 -04:00
self . vmmenu . change_run_text ( text )
2011-07-14 13:13:13 -04:00
self . widget ( " vm-run " ) . set_label ( strip_text )
2006-06-14 10:59:40 -04:00
2013-09-02 09:09:31 -04:00
def update_current_selection ( self , ignore = None ) :
2007-08-09 16:19:41 -04:00
vm = self . current_vm ( )
2009-07-26 16:15:05 -04:00
show_open = bool ( vm )
show_details = bool ( vm )
2010-08-22 12:50:31 -04:00
host_details = bool ( len ( self . rows ) )
2009-07-26 16:15:05 -04:00
show_run = bool ( vm and vm . is_runable ( ) )
is_paused = bool ( vm and vm . is_paused ( ) )
if is_paused :
show_pause = bool ( vm and vm . is_unpauseable ( ) )
2007-08-09 16:19:41 -04:00
else :
2009-07-26 16:15:05 -04:00
show_pause = bool ( vm and vm . is_pauseable ( ) )
show_shutdown = bool ( vm and vm . is_stoppable ( ) )
2010-05-12 12:57:32 -04:00
if vm and vm . managedsave_supported :
2014-09-11 18:01:41 -04:00
self . change_run_text ( vm . has_managed_save ( ) )
2010-05-12 12:57:32 -04:00
2011-07-14 13:13:13 -04:00
self . widget ( " vm-open " ) . set_sensitive ( show_open )
self . widget ( " vm-run " ) . set_sensitive ( show_run )
self . widget ( " vm-shutdown " ) . set_sensitive ( show_shutdown )
2013-09-22 13:24:59 -04:00
self . widget ( " vm-shutdown " ) . get_menu ( ) . update_widget_states ( vm )
2009-07-26 16:15:05 -04:00
self . set_pause_state ( is_paused )
2011-07-14 13:13:13 -04:00
self . widget ( " vm-pause " ) . set_sensitive ( show_pause )
2009-07-26 16:15:05 -04:00
2015-11-12 13:13:19 +01:00
if is_paused :
pauseTooltip = _ ( " Resume the virtual machine " )
else :
pauseTooltip = _ ( " Pause the virtual machine " )
self . widget ( " vm-pause " ) . set_tooltip_text ( pauseTooltip )
2011-07-14 13:13:13 -04:00
self . widget ( " menu_edit_details " ) . set_sensitive ( show_details )
self . widget ( " menu_host_details " ) . set_sensitive ( host_details )
2009-07-26 16:15:05 -04:00
2010-12-09 11:22:35 -05:00
def popup_vm_menu_key ( self , widget_ignore , event ) :
2012-05-14 14:24:56 +01:00
if Gdk . keyval_name ( event . keyval ) != " Menu " :
2009-11-11 09:49:34 -05:00
return False
2014-01-26 20:21:12 -05:00
model , treeiter = self . widget ( " vm-list " ) . get_selection ( ) . get_selected ( )
self . popup_vm_menu ( model , treeiter , event )
2009-11-11 09:49:34 -05:00
return True
2007-08-13 17:13:39 -04:00
2009-11-11 09:49:34 -05:00
def popup_vm_menu_button ( self , widget , event ) :
2009-11-10 16:01:56 -05:00
if event . button != 3 :
return False
2008-11-18 15:42:51 -05:00
tup = widget . get_path_at_pos ( int ( event . x ) , int ( event . y ) )
2012-11-08 14:15:02 +01:00
if tup is None :
2007-08-23 17:46:30 -04:00
return False
2008-11-18 15:42:51 -05:00
path = tup [ 0 ]
2007-08-23 17:46:30 -04:00
model = widget . get_model ( )
2008-11-18 15:42:51 -05:00
_iter = model . get_iter ( path )
2009-11-10 16:01:56 -05:00
2009-11-11 09:49:34 -05:00
self . popup_vm_menu ( model , _iter , event )
2009-12-09 11:28:38 -05:00
return False
2009-11-11 09:49:34 -05:00
def popup_vm_menu ( self , model , _iter , event ) :
2012-11-08 14:15:02 +01:00
if model . iter_parent ( _iter ) is not None :
2009-11-10 16:01:56 -05:00
# Popup the vm menu
2014-01-26 20:21:12 -05:00
vm = model [ _iter ] [ ROW_HANDLE ]
2013-09-22 15:13:41 -04:00
self . vmmenu . update_widget_states ( vm )
2014-04-02 18:39:43 -04:00
self . vmmenu . popup ( None , None , None , None , 0 , event . time )
2007-08-23 17:46:30 -04:00
else :
2009-11-10 16:01:56 -05:00
# Pop up connection menu
2014-01-26 20:21:12 -05:00
conn = model [ _iter ] [ ROW_HANDLE ]
2014-09-11 18:16:21 -04:00
disconn = conn . is_disconnected ( )
conning = conn . is_connecting ( )
2009-11-10 16:01:56 -05:00
self . connmenu_items [ " create " ] . set_sensitive ( not disconn )
self . connmenu_items [ " disconnect " ] . set_sensitive ( not ( disconn or
conning ) )
self . connmenu_items [ " connect " ] . set_sensitive ( disconn )
2009-11-16 16:35:34 -05:00
self . connmenu_items [ " delete " ] . set_sensitive ( disconn )
2009-11-10 16:01:56 -05:00
2012-05-14 14:24:56 +01:00
self . connmenu . popup ( None , None , None , None , 0 , event . time )
2009-11-10 16:01:56 -05:00
2009-11-11 11:02:57 -05:00
2009-11-28 20:49:44 -05:00
#################
# Stats methods #
#################
2006-06-14 10:59:40 -04:00
2012-05-14 14:24:56 +01:00
def vmlist_name_sorter ( self , model , iter1 , iter2 , ignore ) :
2015-03-26 19:13:29 -04:00
key1 = str ( model [ iter1 ] [ ROW_SORT_KEY ] ) . lower ( )
key2 = str ( model [ iter2 ] [ ROW_SORT_KEY ] ) . lower ( )
return cmp ( key1 , key2 )
2006-06-14 10:59:40 -04:00
2012-05-14 14:24:56 +01:00
def vmlist_guest_cpu_usage_sorter ( self , model , iter1 , iter2 , ignore ) :
2014-01-26 20:21:12 -05:00
obj1 = model [ iter1 ] [ ROW_HANDLE ]
obj2 = model [ iter2 ] [ ROW_HANDLE ]
2011-07-12 08:49:47 -04:00
return cmp ( obj1 . guest_cpu_time_percentage ( ) ,
obj2 . guest_cpu_time_percentage ( ) )
2012-05-14 14:24:56 +01:00
def vmlist_host_cpu_usage_sorter ( self , model , iter1 , iter2 , ignore ) :
2014-01-26 20:21:12 -05:00
obj1 = model [ iter1 ] [ ROW_HANDLE ]
obj2 = model [ iter2 ] [ ROW_HANDLE ]
2011-07-11 21:22:50 -04:00
return cmp ( obj1 . host_cpu_time_percentage ( ) ,
obj2 . host_cpu_time_percentage ( ) )
2006-06-14 10:59:40 -04:00
2013-12-18 14:42:42 +01:00
def vmlist_memory_usage_sorter ( self , model , iter1 , iter2 , ignore ) :
2014-01-26 20:21:12 -05:00
obj1 = model [ iter1 ] [ ROW_HANDLE ]
obj2 = model [ iter2 ] [ ROW_HANDLE ]
2013-12-18 14:42:42 +01:00
return cmp ( obj1 . stats_memory ( ) ,
obj2 . stats_memory ( ) )
2012-05-14 14:24:56 +01:00
def vmlist_disk_io_sorter ( self , model , iter1 , iter2 , ignore ) :
2014-01-26 20:21:12 -05:00
obj1 = model [ iter1 ] [ ROW_HANDLE ]
obj2 = model [ iter2 ] [ ROW_HANDLE ]
2011-07-11 21:22:50 -04:00
return cmp ( obj1 . disk_io_rate ( ) , obj2 . disk_io_rate ( ) )
2006-06-14 10:59:40 -04:00
2012-05-14 14:24:56 +01:00
def vmlist_network_usage_sorter ( self , model , iter1 , iter2 , ignore ) :
2014-01-26 20:21:12 -05:00
obj1 = model [ iter1 ] [ ROW_HANDLE ]
obj2 = model [ iter2 ] [ ROW_HANDLE ]
2011-07-11 21:22:50 -04:00
return cmp ( obj1 . network_traffic_rate ( ) , obj2 . network_traffic_rate ( ) )
2006-06-14 10:59:40 -04:00
2013-04-17 17:39:25 -04:00
def enable_polling ( self , column ) :
2016-04-18 16:42:12 -04:00
# pylint: disable=redefined-variable-type
2014-02-11 15:29:30 -05:00
if column == COL_GUEST_CPU :
widgn = [ " menu_view_stats_guest_cpu " , " menu_view_stats_host_cpu " ]
do_enable = self . config . get_stats_enable_cpu_poll ( )
2013-04-17 17:39:25 -04:00
if column == COL_DISK :
2009-07-26 16:15:28 -04:00
widgn = " menu_view_stats_disk "
2013-04-17 17:39:25 -04:00
do_enable = self . config . get_stats_enable_disk_poll ( )
elif column == COL_NETWORK :
2009-07-26 16:15:28 -04:00
widgn = " menu_view_stats_network "
2013-04-17 17:39:25 -04:00
do_enable = self . config . get_stats_enable_net_poll ( )
2014-01-12 17:39:21 -05:00
elif column == COL_MEM :
widgn = " menu_view_stats_memory "
do_enable = self . config . get_stats_enable_memory_poll ( )
2008-12-17 15:27:06 -05:00
2014-02-11 15:29:30 -05:00
for w in util . listify ( widgn ) :
widget = self . widget ( w )
tool_text = " "
2010-12-13 16:24:49 -05:00
2014-02-11 15:29:30 -05:00
if do_enable :
widget . set_sensitive ( True )
else :
if widget . get_active ( ) :
widget . set_active ( False )
widget . set_sensitive ( False )
tool_text = _ ( " Disabled in preferences dialog. " )
widget . set_tooltip_text ( tool_text )
2011-02-15 11:38:35 -05:00
2013-09-01 21:35:23 -04:00
def _toggle_graph_helper ( self , do_show , col , datafunc , menu ) :
img = - 1
for child in col . get_cells ( ) :
if isinstance ( child , CellRendererSparkline ) :
img = child
datafunc = do_show and datafunc or None
2009-07-26 16:15:28 -04:00
2013-09-01 21:35:23 -04:00
col . set_cell_data_func ( img , datafunc , None )
col . set_visible ( do_show )
self . widget ( menu ) . set_active ( do_show )
2011-07-12 08:49:47 -04:00
2013-12-18 14:42:42 +01:00
any_visible = any ( [ c . get_visible ( ) for c in
[ self . netcol , self . diskcol , self . memcol ,
self . guestcpucol , self . hostcpucol ] ] )
2013-09-02 10:43:53 -04:00
self . spacer_txt . set_property ( " visible " , not any_visible )
2013-09-01 21:35:23 -04:00
def toggle_network_traffic_visible_widget ( self ) :
self . _toggle_graph_helper (
self . config . is_vmlist_network_traffic_visible ( ) , self . netcol ,
self . network_traffic_img , " menu_view_stats_network " )
def toggle_disk_io_visible_widget ( self ) :
self . _toggle_graph_helper (
self . config . is_vmlist_disk_io_visible ( ) , self . diskcol ,
self . disk_io_img , " menu_view_stats_disk " )
2013-12-18 14:42:42 +01:00
def toggle_memory_usage_visible_widget ( self ) :
self . _toggle_graph_helper (
self . config . is_vmlist_memory_usage_visible ( ) , self . memcol ,
self . memory_usage_img , " menu_view_stats_memory " )
2013-04-17 17:39:25 -04:00
def toggle_guest_cpu_usage_visible_widget ( self ) :
2013-09-01 21:35:23 -04:00
self . _toggle_graph_helper (
self . config . is_vmlist_guest_cpu_usage_visible ( ) , self . guestcpucol ,
self . guest_cpu_usage_img , " menu_view_stats_guest_cpu " )
2013-04-17 17:39:25 -04:00
def toggle_host_cpu_usage_visible_widget ( self ) :
2013-09-01 21:35:23 -04:00
self . _toggle_graph_helper (
self . config . is_vmlist_host_cpu_usage_visible ( ) , self . hostcpucol ,
self . host_cpu_usage_img , " menu_view_stats_host_cpu " )
2009-11-11 11:02:57 -05:00
def toggle_stats_visible ( self , src , stats_id ) :
visible = src . get_active ( )
set_stats = {
2011-07-12 08:49:47 -04:00
COL_GUEST_CPU : self . config . set_vmlist_guest_cpu_usage_visible ,
COL_HOST_CPU : self . config . set_vmlist_host_cpu_usage_visible ,
2013-12-18 14:42:42 +01:00
COL_MEM : self . config . set_vmlist_memory_usage_visible ,
2011-07-12 08:49:47 -04:00
COL_DISK : self . config . set_vmlist_disk_io_visible ,
COL_NETWORK : self . config . set_vmlist_network_traffic_visible ,
2009-11-11 11:02:57 -05:00
}
set_stats [ stats_id ] ( visible )
2006-06-14 10:59:40 -04:00
2012-05-14 14:24:56 +01:00
def toggle_stats_visible_guest_cpu ( self , src ) :
self . toggle_stats_visible ( src , COL_GUEST_CPU )
def toggle_stats_visible_host_cpu ( self , src ) :
self . toggle_stats_visible ( src , COL_HOST_CPU )
2013-12-18 14:42:42 +01:00
def toggle_stats_visible_memory_usage ( self , src ) :
self . toggle_stats_visible ( src , COL_MEM )
2012-05-14 14:24:56 +01:00
def toggle_stats_visible_disk ( self , src ) :
self . toggle_stats_visible ( src , COL_DISK )
def toggle_stats_visible_network ( self , src ) :
self . toggle_stats_visible ( src , COL_NETWORK )
2011-07-12 08:49:47 -04:00
def guest_cpu_usage_img ( self , column_ignore , cell , model , _iter , data ) :
2013-09-01 21:35:23 -04:00
obj = model [ _iter ] [ ROW_HANDLE ]
2012-05-14 14:24:56 +01:00
if obj is None or not hasattr ( obj , " conn " ) :
2011-07-12 08:49:47 -04:00
return
2015-05-04 16:33:56 -04:00
data = obj . guest_cpu_time_vector ( GRAPH_LEN )
2011-07-12 08:49:47 -04:00
cell . set_property ( ' data_array ' , data )
def host_cpu_usage_img ( self , column_ignore , cell , model , _iter , data ) :
2013-09-01 21:35:23 -04:00
obj = model [ _iter ] [ ROW_HANDLE ]
2012-05-14 14:24:56 +01:00
if obj is None or not hasattr ( obj , " conn " ) :
2007-08-14 16:28:36 -04:00
return
2011-07-11 21:22:50 -04:00
2015-05-04 16:33:56 -04:00
data = obj . host_cpu_time_vector ( GRAPH_LEN )
2008-10-18 21:28:57 +02:00
cell . set_property ( ' data_array ' , data )
2013-12-18 14:42:42 +01:00
def memory_usage_img ( self , column_ignore , cell , model , _iter , data ) :
obj = model [ _iter ] [ ROW_HANDLE ]
if obj is None or not hasattr ( obj , " conn " ) :
return
2015-05-04 16:33:56 -04:00
data = obj . stats_memory_vector ( GRAPH_LEN )
2013-12-18 14:42:42 +01:00
cell . set_property ( ' data_array ' , data )
2010-12-09 11:22:35 -05:00
def disk_io_img ( self , column_ignore , cell , model , _iter , data ) :
2013-09-01 21:35:23 -04:00
obj = model [ _iter ] [ ROW_HANDLE ]
2012-05-14 14:24:56 +01:00
if obj is None or not hasattr ( obj , " conn " ) :
2011-07-25 15:09:42 -04:00
return
2015-05-04 16:33:56 -04:00
d1 , d2 = obj . disk_io_vectors ( GRAPH_LEN , self . max_disk_rate )
data = [ ( x + y ) / 2 for x , y in zip ( d1 , d2 ) ]
2008-10-18 21:28:57 +02:00
cell . set_property ( ' data_array ' , data )
2010-12-09 11:22:35 -05:00
def network_traffic_img ( self , column_ignore , cell , model , _iter , data ) :
2013-09-01 21:35:23 -04:00
obj = model [ _iter ] [ ROW_HANDLE ]
2012-05-14 14:24:56 +01:00
if obj is None or not hasattr ( obj , " conn " ) :
2011-07-25 15:09:42 -04:00
return
2015-05-04 16:33:56 -04:00
d1 , d2 = obj . network_traffic_vectors ( GRAPH_LEN , self . max_net_rate )
data = [ ( x + y ) / 2 for x , y in zip ( d1 , d2 ) ]
2006-06-26 17:17:45 -04:00
cell . set_property ( ' data_array ' , data )