2006-06-28 15:50:17 -04:00
#
2008-04-08 13:30:47 -05:00
# Copyright (C) 2006-2008 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
2006-06-14 16:20:06 -04:00
import gobject
2006-06-14 10:59:40 -04:00
import gtk
import gtk . glade
2006-06-14 18:42:04 -04:00
import libvirt
2006-06-30 12:52:10 -04:00
import sparkline
2006-09-25 18:41:47 -04:00
import logging
2007-04-10 19:07:53 -04:00
import traceback
2007-11-16 17:12:37 -05:00
import sys
2008-04-08 13:30:47 -05:00
import dbus
import gtkvnc
import os
import socket
2008-09-09 07:06:33 -04:00
import cairo
2007-04-10 19:07:53 -04:00
from virtManager . error import vmmErrorDialog
2007-04-12 15:36:04 -04:00
from virtManager . addhardware import vmmAddHardware
2007-09-21 16:28:31 -04:00
from virtManager . choosecd import vmmChooseCD
2008-10-02 16:17:25 -04:00
from virtManager . serialcon import vmmSerialConsole
2009-01-26 11:12:43 -05:00
from virtManager import util as util
2007-04-10 19:07:53 -04:00
2007-04-11 14:48:36 -04:00
import virtinst
2007-07-14 14:43:20 -04:00
# Columns in hw list model
HW_LIST_COL_LABEL = 0
HW_LIST_COL_STOCK_ID = 1
HW_LIST_COL_STOCK_SIZE = 2
HW_LIST_COL_PIXBUF = 3
HW_LIST_COL_TYPE = 4
HW_LIST_COL_DEVICE = 5
2008-07-23 16:23:56 -04:00
# Types for the hw list model: numbers specify what order they will be listed
2009-02-09 14:55:18 -05:00
HW_LIST_TYPE_GENERAL = 0
HW_LIST_TYPE_STATS = 1
HW_LIST_TYPE_CPU = 2
HW_LIST_TYPE_MEMORY = 3
HW_LIST_TYPE_BOOT = 4
HW_LIST_TYPE_DISK = 5
HW_LIST_TYPE_NIC = 6
HW_LIST_TYPE_INPUT = 7
HW_LIST_TYPE_GRAPHICS = 8
HW_LIST_TYPE_SOUND = 9
HW_LIST_TYPE_CHAR = 10
HW_LIST_TYPE_HOSTDEV = 11
2009-07-09 14:35:55 -04:00
HW_LIST_TYPE_VIDEO = 12
2006-06-14 10:59:40 -04:00
2009-07-09 14:35:36 -04:00
apply_pages = [ HW_LIST_TYPE_GENERAL , HW_LIST_TYPE_CPU , HW_LIST_TYPE_MEMORY ,
HW_LIST_TYPE_BOOT ]
remove_pages = [ HW_LIST_TYPE_DISK , HW_LIST_TYPE_NIC , HW_LIST_TYPE_INPUT ,
HW_LIST_TYPE_GRAPHICS , HW_LIST_TYPE_SOUND , HW_LIST_TYPE_CHAR ,
2009-07-09 14:35:55 -04:00
HW_LIST_TYPE_HOSTDEV , HW_LIST_TYPE_VIDEO ]
2009-07-09 14:35:36 -04:00
2008-04-08 13:30:47 -05:00
# Console pages
PAGE_UNAVAILABLE = 0
PAGE_SCREENSHOT = 1
PAGE_AUTHENTICATE = 2
PAGE_VNCVIEWER = 3
2009-02-23 18:50:27 -05:00
# Main tab pages
2008-05-07 11:14:20 -04:00
PAGE_CONSOLE = 0
2009-02-09 14:55:18 -05:00
PAGE_DETAILS = 1
PAGE_DYNAMIC_OFFSET = 2
2008-05-07 11:14:20 -04:00
2006-06-14 16:20:06 -04:00
class vmmDetails ( gobject . GObject ) :
__gsignals__ = {
" action-show-console " : ( gobject . SIGNAL_RUN_FIRST ,
gobject . TYPE_NONE , ( str , str ) ) ,
2006-07-17 13:08:58 -04:00
" action-save-domain " : ( gobject . SIGNAL_RUN_FIRST ,
2006-11-15 12:27:36 -05:00
gobject . TYPE_NONE , ( str , str ) ) ,
" action-destroy-domain " : ( gobject . SIGNAL_RUN_FIRST ,
2007-03-16 16:27:50 -04:00
gobject . TYPE_NONE , ( str , str ) ) ,
2007-11-27 11:31:30 -05:00
" action-suspend-domain " : ( gobject . SIGNAL_RUN_FIRST ,
gobject . TYPE_NONE , ( str , str ) ) ,
" action-resume-domain " : ( gobject . SIGNAL_RUN_FIRST ,
gobject . TYPE_NONE , ( str , str ) ) ,
" action-run-domain " : ( gobject . SIGNAL_RUN_FIRST ,
gobject . TYPE_NONE , ( str , str ) ) ,
" action-shutdown-domain " : ( gobject . SIGNAL_RUN_FIRST ,
gobject . TYPE_NONE , ( str , str ) ) ,
2008-04-08 13:30:47 -05:00
" action-reboot-domain " : ( gobject . SIGNAL_RUN_FIRST ,
gobject . TYPE_NONE , ( str , str ) ) ,
2007-03-16 16:27:50 -04:00
" action-show-help " : ( gobject . SIGNAL_RUN_FIRST ,
gobject . TYPE_NONE , [ str ] ) ,
2008-06-13 14:40:26 -04:00
" action-exit-app " : ( gobject . SIGNAL_RUN_FIRST ,
gobject . TYPE_NONE , [ ] ) ,
" action-view-manager " : ( gobject . SIGNAL_RUN_FIRST ,
gobject . TYPE_NONE , [ ] ) ,
2008-10-30 16:38:13 -04:00
" action-migrate-domain " : ( gobject . SIGNAL_RUN_FIRST ,
gobject . TYPE_NONE , ( str , str , str ) ) ,
2006-06-14 16:20:06 -04:00
}
2007-07-14 14:43:20 -04:00
2008-06-13 12:12:37 -04:00
def __init__ ( self , config , vm , engine ) :
2006-06-14 16:20:06 -04:00
self . __gobject_init__ ( )
2007-02-15 15:35:37 -05:00
self . window = gtk . glade . XML ( config . get_glade_dir ( ) + " /vmm-details.glade " , " vmm-details " , domain = " virt-manager " )
2006-06-14 10:59:40 -04:00
self . config = config
self . vm = vm
topwin = self . window . get_widget ( " vmm-details " )
2008-03-14 13:18:44 -04:00
self . err = vmmErrorDialog ( topwin ,
0 , gtk . MESSAGE_ERROR , gtk . BUTTONS_CLOSE ,
_ ( " Unexpected Error " ) ,
_ ( " An unexpected error occurred " ) )
2008-04-08 13:30:47 -05:00
self . title = vm . get_name ( ) + " " + topwin . get_title ( )
topwin . set_title ( self . title )
2006-06-14 10:59:40 -04:00
2008-06-13 12:12:37 -04:00
self . engine = engine
2008-10-02 16:17:25 -04:00
self . dynamic_tabs = [ ]
2008-11-18 17:01:22 -05:00
self . ignorePause = False
2008-06-13 12:12:37 -04:00
2007-04-12 17:50:22 -04:00
# Don't allowing changing network/disks for Dom0
2008-09-05 09:41:38 -04:00
if self . vm . is_management_domain ( ) :
2007-04-12 17:50:22 -04:00
self . window . get_widget ( " add-hardware-button " ) . set_sensitive ( False )
else :
self . window . get_widget ( " add-hardware-button " ) . set_sensitive ( True )
2006-06-14 10:59:40 -04:00
self . window . get_widget ( " control-shutdown " ) . set_icon_widget ( gtk . Image ( ) )
2006-07-19 12:42:19 -04:00
self . window . get_widget ( " control-shutdown " ) . get_icon_widget ( ) . set_from_file ( config . get_icon_dir ( ) + " /icon_shutdown.png " )
2006-06-14 10:59:40 -04:00
2008-04-08 13:30:47 -05:00
menu = gtk . Menu ( )
self . window . get_widget ( " control-shutdown " ) . set_menu ( menu )
2008-10-30 16:38:13 -04:00
2008-04-08 13:30:47 -05:00
rebootimg = gtk . Image ( )
rebootimg . set_from_pixbuf ( gtk . gdk . pixbuf_new_from_file_at_size ( self . config . get_icon_dir ( ) + " /icon_shutdown.png " , 18 , 18 ) )
shutdownimg = gtk . Image ( )
shutdownimg . set_from_pixbuf ( gtk . gdk . pixbuf_new_from_file_at_size ( self . config . get_icon_dir ( ) + " /icon_shutdown.png " , 18 , 18 ) )
destroyimg = gtk . Image ( )
destroyimg . set_from_pixbuf ( gtk . gdk . pixbuf_new_from_file_at_size ( self . config . get_icon_dir ( ) + " /icon_shutdown.png " , 18 , 18 ) )
2009-05-11 12:24:15 -04:00
reboot = gtk . ImageMenuItem ( _ ( " _Reboot " ) )
2008-04-08 13:30:47 -05:00
reboot . set_image ( rebootimg )
reboot . show ( )
reboot . connect ( " activate " , self . control_vm_reboot )
menu . add ( reboot )
2009-05-11 12:24:15 -04:00
shutdown = gtk . ImageMenuItem ( _ ( " _Shut Down " ) )
2008-04-08 13:30:47 -05:00
shutdown . set_image ( shutdownimg )
shutdown . show ( )
shutdown . connect ( " activate " , self . control_vm_shutdown )
menu . add ( shutdown )
2009-05-11 12:24:15 -04:00
destroy = gtk . ImageMenuItem ( _ ( " _Force Off " ) )
2008-04-08 13:30:47 -05:00
destroy . set_image ( destroyimg )
destroy . show ( )
destroy . connect ( " activate " , self . control_vm_destroy )
menu . add ( destroy )
2008-10-02 16:17:25 -04:00
smenu = gtk . Menu ( )
smenu . connect ( " show " , self . populate_serial_menu )
self . window . get_widget ( " details-menu-view-serial-list " ) . set_submenu ( smenu )
self . serial_popup = gtk . Menu ( )
self . serial_copy = gtk . ImageMenuItem ( gtk . STOCK_COPY )
self . serial_popup . add ( self . serial_copy )
self . serial_paste = gtk . ImageMenuItem ( gtk . STOCK_PASTE )
self . serial_popup . add ( self . serial_paste )
self . serial_popup . add ( gtk . SeparatorMenuItem ( ) )
self . serial_close = gtk . ImageMenuItem ( _ ( " Close tab " ) )
close_image = gtk . Image ( )
close_image . set_from_stock ( gtk . STOCK_CLOSE , gtk . ICON_SIZE_MENU )
self . serial_close . set_image ( close_image )
self . serial_popup . add ( self . serial_close )
2008-04-08 13:30:47 -05:00
2006-06-14 10:59:40 -04:00
self . window . get_widget ( " hw-panel " ) . set_show_tabs ( False )
2007-04-12 15:36:04 -04:00
self . addhw = None
2007-09-21 16:28:31 -04:00
self . choose_cd = None
2009-02-28 19:27:20 -05:00
2009-07-07 12:16:03 -04:00
# Security info tooltips
util . tooltip_wrapper ( self . window . get_widget ( " security-static-info " ) ,
_ ( " Static SELinux security type tells libvirt to always start the guest process with the specified label. The administrator is responsible for making sure the images are labeled corectly on disk. " ) )
util . tooltip_wrapper ( self . window . get_widget ( " security-dynamic-info " ) ,
_ ( " The dynamic SELinux security type tells libvirt to automatically pick a unique label for the guest process and guest image, ensuring total isolation of the guest. (Default) " ) )
2006-06-30 12:52:10 -04:00
self . cpu_usage_graph = sparkline . Sparkline ( )
2008-10-06 12:56:11 -04:00
self . cpu_usage_graph . set_property ( " reversed " , True )
2006-06-30 12:52:10 -04:00
self . window . get_widget ( " graph-table " ) . attach ( self . cpu_usage_graph , 1 , 2 , 0 , 1 )
self . memory_usage_graph = sparkline . Sparkline ( )
2008-10-06 12:56:11 -04:00
self . memory_usage_graph . set_property ( " reversed " , True )
2006-06-30 12:52:10 -04:00
self . window . get_widget ( " graph-table " ) . attach ( self . memory_usage_graph , 1 , 2 , 1 , 2 )
2008-10-18 21:21:33 +02:00
self . disk_io_graph = sparkline . Sparkline ( )
self . disk_io_graph . set_property ( " reversed " , True )
2008-10-18 21:24:19 +02:00
self . disk_io_graph . set_property ( " filled " , False )
self . disk_io_graph . set_property ( " num_sets " , 2 )
2008-10-18 21:25:16 +02:00
self . disk_io_graph . set_property ( " rgb " , map ( lambda x : x / 255.0 ,
[ 0x82 , 0x00 , 0x3B , 0x29 , 0x5C , 0x45 ] ) )
2008-10-18 21:21:33 +02:00
self . window . get_widget ( " graph-table " ) . attach ( self . disk_io_graph , 1 , 2 , 2 , 3 )
2009-02-28 19:27:20 -05:00
2006-06-30 12:52:10 -04:00
self . network_traffic_graph = sparkline . Sparkline ( )
2008-10-06 12:56:11 -04:00
self . network_traffic_graph . set_property ( " reversed " , True )
2008-10-18 21:24:19 +02:00
self . network_traffic_graph . set_property ( " filled " , False )
self . network_traffic_graph . set_property ( " num_sets " , 2 )
2008-10-18 21:25:16 +02:00
self . network_traffic_graph . set_property ( " rgb " , map ( lambda x : x / 255.0 ,
[ 0x82 , 0x00 , 0x3B , 0x29 , 0x5C , 0x45 ] ) )
2006-06-30 12:52:10 -04:00
self . window . get_widget ( " graph-table " ) . attach ( self . network_traffic_graph , 1 , 2 , 3 , 4 )
2006-06-14 10:59:40 -04:00
2008-04-08 13:30:47 -05:00
self . accel_groups = gtk . accel_groups_from_object ( topwin )
self . gtk_settings_accel = None
self . vncViewer = gtkvnc . Display ( )
self . window . get_widget ( " console-vnc-viewport " ) . add ( self . vncViewer )
self . vncViewer . realize ( )
self . vncTunnel = None
if self . config . get_console_keygrab ( ) == 2 :
self . vncViewer . set_keyboard_grab ( True )
else :
self . vncViewer . set_keyboard_grab ( False )
self . vncViewer . set_pointer_grab ( True )
2009-02-23 18:50:27 -05:00
2009-05-11 10:45:25 -04:00
self . scale_type = self . vm . get_console_scaling ( )
self . vm . on_console_scaling_changed ( self . refresh_scaling )
self . refresh_scaling ( )
2008-04-08 13:30:47 -05:00
self . vncViewer . connect ( " vnc-pointer-grab " , self . notify_grabbed )
self . vncViewer . connect ( " vnc-pointer-ungrab " , self . notify_ungrabbed )
self . vncViewer . show ( )
self . vncViewerRetriesScheduled = 0
self . vncViewerRetryDelay = 125
self . vncViewer . connect ( " size-request " , self . _force_resize )
self . vncViewer . connect ( " vnc-auth-credential " , self . _vnc_auth_credential )
self . vncViewer . connect ( " vnc-initialized " , self . _vnc_initialized )
self . vncViewer . connect ( " vnc-disconnected " , self . _vnc_disconnected )
self . vncViewer . connect ( " vnc-keyboard-grab " , self . _disable_modifiers )
self . vncViewer . connect ( " vnc-keyboard-ungrab " , self . _enable_modifiers )
2009-01-19 15:48:21 -05:00
self . vnc_connected = False
2008-04-08 13:30:47 -05:00
self . notifyID = None
2008-12-08 13:17:48 -05:00
self . notifyInterface = None
2008-04-08 13:30:47 -05:00
try :
bus = dbus . SessionBus ( )
2008-12-08 13:17:48 -05:00
notifyObject = bus . get_object ( " org.freedesktop.Notifications " , " /org/freedesktop/Notifications " )
self . notifyInterface = dbus . Interface ( notifyObject , " org.freedesktop.Notifications " )
2008-04-08 13:30:47 -05:00
self . notifyInterface . connect_to_signal ( " ActionInvoked " , self . notify_action )
self . notifyInterface . connect_to_signal ( " NotificationClosed " , self . notify_closed )
except Exception , e :
logging . error ( " Cannot initialize notification system " + str ( e ) )
self . window . get_widget ( " console-pages " ) . set_show_tabs ( False )
2008-09-05 16:34:14 -04:00
self . window . get_widget ( " details-menu-view-toolbar " ) . set_active ( self . config . get_details_show_toolbar ( ) )
2008-04-08 13:30:47 -05:00
2006-06-14 10:59:40 -04:00
self . window . signal_autoconnect ( {
" on_close_details_clicked " : self . close ,
2006-09-01 11:18:49 -04:00
" on_details_menu_close_activate " : self . close ,
2006-06-14 10:59:40 -04:00
" on_vmm_details_delete_event " : self . close ,
2008-06-13 14:40:26 -04:00
" on_details_menu_quit_activate " : self . exit_app ,
2006-06-14 10: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 13:30:47 -05:00
" on_control_fullscreen_toggled " : self . control_fullscreen ,
2006-06-14 10:59:40 -04:00
2006-09-01 11:18:49 -04:00
" on_details_menu_run_activate " : self . control_vm_run ,
2008-04-08 13:30:47 -05:00
" on_details_menu_poweroff_activate " : self . control_vm_shutdown ,
" on_details_menu_reboot_activate " : self . control_vm_reboot ,
2006-09-01 11:18:49 -04:00
" on_details_menu_save_activate " : self . control_vm_save_domain ,
2006-11-15 12:27:36 -05:00
" on_details_menu_destroy_activate " : self . control_vm_destroy ,
2007-09-27 17:52:29 -04:00
" on_details_menu_pause_activate " : self . control_vm_pause ,
2009-04-03 14:18:40 -04:00
" on_details_menu_migrate_activate " : self . populate_migrate_menu ,
2008-05-07 11:40:29 -04:00
" on_details_menu_screenshot_activate " : self . control_vm_screenshot ,
2006-09-01 11:18:49 -04:00
" on_details_menu_graphics_activate " : self . control_vm_console ,
" on_details_menu_view_toolbar_activate " : self . toggle_toolbar ,
2008-06-13 14:40:26 -04:00
" on_details_menu_view_manager_activate " : self . view_manager ,
2006-09-01 11:18:49 -04:00
2008-05-07 11:26:00 -04:00
" on_details_pages_switch_page " : self . switch_page ,
2006-11-13 15:31:17 -05:00
" on_config_vcpus_changed " : self . config_vcpus_changed ,
" on_config_memory_changed " : self . config_memory_changed ,
" on_config_maxmem_changed " : self . config_maxmem_changed ,
2008-03-06 16:43:46 -05:00
" on_config_boot_device_changed " : self . config_boot_options_changed ,
" on_config_autostart_changed " : self . config_boot_options_changed ,
2009-07-09 14:35:36 -04:00
" on_config_apply_clicked " : self . config_apply ,
2007-03-16 16:27:50 -04:00
" on_details_help_activate " : self . show_help ,
2007-04-11 14:48:36 -04:00
2007-09-21 16:28:31 -04:00
" on_config_cdrom_connect_clicked " : self . toggle_cdrom ,
2009-07-09 14:35:36 -04:00
" on_config_remove_clicked " : self . remove_xml_dev ,
2007-04-11 14:48:36 -04:00
" on_add_hardware_button_clicked " : self . add_hardware ,
2008-04-08 13:30:47 -05:00
" on_details_menu_view_fullscreen_activate " : self . toggle_fullscreen ,
" on_details_menu_view_toolbar_activate " : self . toggle_toolbar ,
2009-02-23 18:50:27 -05:00
" on_details_menu_view_scale_always_toggled " : self . set_scale_type ,
" on_details_menu_view_scale_fullscreen_toggled " : self . set_scale_type ,
" on_details_menu_view_scale_never_toggled " : self . set_scale_type ,
2008-04-08 13:30:47 -05:00
" on_details_menu_send_cad_activate " : self . send_key ,
" on_details_menu_send_cab_activate " : self . send_key ,
" on_details_menu_send_caf1_activate " : self . send_key ,
" on_details_menu_send_caf2_activate " : self . send_key ,
" on_details_menu_send_caf3_activate " : self . send_key ,
" on_details_menu_send_caf4_activate " : self . send_key ,
" on_details_menu_send_caf5_activate " : self . send_key ,
" on_details_menu_send_caf6_activate " : self . send_key ,
" on_details_menu_send_caf7_activate " : self . send_key ,
" on_details_menu_send_caf8_activate " : self . send_key ,
" on_details_menu_send_caf9_activate " : self . send_key ,
" on_details_menu_send_caf10_activate " : self . send_key ,
" on_details_menu_send_caf11_activate " : self . send_key ,
" on_details_menu_send_caf12_activate " : self . send_key ,
" on_details_menu_send_printscreen_activate " : self . send_key ,
2009-01-26 10:17:33 -05:00
2009-02-28 17:21:41 -05:00
" on_console_auth_password_activate " : self . auth_login ,
2009-01-26 10:17:33 -05:00
" on_console_auth_login_clicked " : self . auth_login ,
2009-07-07 12:16:03 -04:00
" on_security_label_changed " : self . security_label_changed ,
" on_security_type_changed " : self . security_type_changed ,
" on_security_model_changed " : self . security_model_changed ,
2006-06-14 10:59:40 -04:00
} )
2006-06-14 18:42:04 -04:00
self . vm . connect ( " status-changed " , self . update_widget_states )
self . vm . connect ( " resources-sampled " , self . refresh_resources )
2009-02-28 19:27:20 -05:00
self . vm . connect ( " config-changed " , self . refresh_vm_info )
2007-04-11 14:48:36 -04:00
self . window . get_widget ( " hw-list " ) . get_selection ( ) . connect ( " changed " , self . hw_selected )
2007-04-25 17:09:37 -04:00
self . update_widget_states ( self . vm , self . vm . status ( ) )
2006-06-14 10:59:40 -04:00
2007-04-11 14:48:36 -04:00
self . pixbuf_processor = gtk . gdk . pixbuf_new_from_file ( config . get_icon_dir ( ) + " /icon_cpu.png " )
self . pixbuf_memory = gtk . gdk . pixbuf_new_from_file ( config . get_icon_dir ( ) + " /icon_cpu.png " )
self . prepare_hw_list ( )
2009-07-09 14:35:44 -04:00
self . hw_selected ( page = 0 )
2009-02-28 19:27:20 -05:00
self . refresh_vm_info ( )
2006-08-29 15:52:19 -04:00
2008-04-08 13:30:47 -05:00
# Black magic todo with scrolled windows. Basically the behaviour we want
# is that if it possible to resize the window to show entire guest desktop
# then we should do that and never show scrollbars. If the local screen is
# too small then we can turn on scrolling. You would think the 'Automatic'
# policy would work, but even if viewport is identical sized to the VNC
# widget it still seems to show scrollbars. So we do evil stuff here
def _force_resize ( self , src , size ) :
w , h = src . get_size_request ( )
if w == - 1 or h == - 1 :
return
topw , toph = self . window . get_widget ( " vmm-details " ) . size_request ( )
padx = topw - w
pady = toph - h
rootw = src . get_screen ( ) . get_width ( )
rooth = src . get_screen ( ) . get_height ( )
maxw = rootw - 100 - padx
maxh = rooth - 100 - pady
2008-05-05 16:10:37 -04:00
2008-04-08 13:30:47 -05:00
self . window . get_widget ( " console-vnc-viewport " ) . set_size_request ( w , h )
self . window . get_widget ( " console-screenshot " ) . set_size_request ( w , h )
self . window . get_widget ( " console-screenshot-viewport " ) . set_size_request ( w , h )
self . window . get_widget ( " console-vnc-scroll " ) . set_size_request ( w , h )
if w > maxw or h > maxh :
self . window . get_widget ( " console-vnc-scroll " ) . set_policy ( gtk . POLICY_ALWAYS , gtk . POLICY_ALWAYS )
self . window . get_widget ( " console-screenshot-scroll " ) . set_policy ( gtk . POLICY_ALWAYS , gtk . POLICY_ALWAYS )
else :
self . window . get_widget ( " console-vnc-scroll " ) . set_policy ( gtk . POLICY_NEVER , gtk . POLICY_NEVER )
self . window . get_widget ( " console-screenshot-scroll " ) . set_policy ( gtk . POLICY_NEVER , gtk . POLICY_NEVER )
def _disable_modifiers ( self , ignore = None ) :
topwin = self . window . get_widget ( " vmm-details " )
for g in self . accel_groups :
topwin . remove_accel_group ( g )
settings = gtk . settings_get_default ( )
self . gtk_settings_accel = settings . get_property ( ' gtk-menu-bar-accel ' )
settings . set_property ( ' gtk-menu-bar-accel ' , None )
def _enable_modifiers ( self , ignore = None ) :
topwin = self . window . get_widget ( " vmm-details " )
if self . gtk_settings_accel is None :
return
settings = gtk . settings_get_default ( )
settings . set_property ( ' gtk-menu-bar-accel ' , self . gtk_settings_accel )
self . gtk_settings_accel = None
for g in self . accel_groups :
topwin . add_accel_group ( g )
def notify_grabbed ( self , src ) :
topwin = self . window . get_widget ( " vmm-details " )
topwin . set_title ( _ ( " Press Ctrl+Alt to release pointer. " ) + " " + self . title )
2008-12-08 13:17:48 -05:00
if self . config . show_console_grab_notify ( ) and self . notifyInterface :
2008-04-08 13:30:47 -05:00
try :
( x , y ) = topwin . window . get_origin ( )
self . notifyID = self . notifyInterface . Notify ( topwin . get_title ( ) ,
0 ,
' ' ,
_ ( " Pointer grabbed " ) ,
2009-01-24 15:03:53 -05:00
_ ( " The mouse pointer has been restricted to the virtual console window. To release the pointer, press the key pair: Ctrl+Alt " ) ,
[ " dismiss " , _ ( " Do not show this notification in the future. " ) ] ,
2008-04-08 13:30:47 -05:00
{ " desktop-entry " : " virt-manager " ,
" x " : x + 200 , " y " : y } ,
2008-11-18 17:01:22 -05:00
8 * 1000 )
2008-04-08 13:30:47 -05:00
except Exception , e :
logging . error ( " Cannot popup notification " + str ( e ) )
def notify_ungrabbed ( self , src ) :
topwin = self . window . get_widget ( " vmm-details " )
topwin . set_title ( self . title )
2008-11-18 15:42:51 -05:00
def notify_closed ( self , i , reason = None ) :
if self . notifyID is not None and self . notifyID == i :
2008-04-08 13:30:47 -05:00
self . notifyID = None
2008-11-18 15:42:51 -05:00
def notify_action ( self , i , action ) :
if self . notifyID is None or self . notifyID != i :
2008-04-08 13:30:47 -05:00
return
if action == " dismiss " :
self . config . set_console_grab_notify ( False )
def keygrab_changed ( self , src , ignore1 = None , ignore2 = None , ignore3 = None ) :
if self . config . get_console_keygrab ( ) == 2 :
self . vncViewer . set_keyboard_grab ( True )
else :
self . vncViewer . set_keyboard_grab ( False )
2009-05-11 10:45:25 -04:00
def refresh_scaling ( self , ignore1 = None , ignore2 = None , ignore3 = None ,
ignore4 = None ) :
self . scale_type = self . vm . get_console_scaling ( )
self . window . get_widget ( " details-menu-view-scale-always " ) . set_active ( self . scale_type == self . config . CONSOLE_SCALE_ALWAYS )
self . window . get_widget ( " details-menu-view-scale-never " ) . set_active ( self . scale_type == self . config . CONSOLE_SCALE_NEVER )
self . window . get_widget ( " details-menu-view-scale-fullscreen " ) . set_active ( self . scale_type == self . config . CONSOLE_SCALE_FULLSCREEN )
self . update_scaling ( )
2009-02-23 18:50:27 -05:00
def set_scale_type ( self , src ) :
if not src . get_active ( ) :
return
if src == self . window . get_widget ( " details-menu-view-scale-always " ) :
2009-02-23 18:50:47 -05:00
self . scale_type = self . config . CONSOLE_SCALE_ALWAYS
2009-02-23 18:50:27 -05:00
elif src == self . window . get_widget ( " details-menu-view-scale-fullscreen " ) :
2009-02-23 18:50:47 -05:00
self . scale_type = self . config . CONSOLE_SCALE_FULLSCREEN
2009-02-23 18:50:27 -05:00
elif src == self . window . get_widget ( " details-menu-view-scale-never " ) :
2009-02-23 18:50:47 -05:00
self . scale_type = self . config . CONSOLE_SCALE_NEVER
2009-02-23 18:50:27 -05:00
2009-05-11 10:45:25 -04:00
self . vm . set_console_scaling ( self . scale_type )
2009-02-23 18:50:27 -05:00
self . update_scaling ( )
def update_scaling ( self ) :
curscale = self . vncViewer . get_scaling ( )
fs = self . window . get_widget ( " control-fullscreen " ) . get_active ( )
2009-02-23 18:50:47 -05:00
if ( self . scale_type == self . config . CONSOLE_SCALE_NEVER
and curscale == True ) :
2008-04-08 13:30:47 -05:00
self . vncViewer . set_scaling ( False )
2009-02-23 18:50:47 -05:00
elif ( self . scale_type == self . config . CONSOLE_SCALE_ALWAYS
and curscale == False ) :
2009-02-23 18:50:27 -05:00
self . vncViewer . set_scaling ( True )
2009-02-23 18:50:47 -05:00
elif ( self . scale_type == self . config . CONSOLE_SCALE_FULLSCREEN
and curscale != fs ) :
2009-02-23 18:50:27 -05:00
self . vncViewer . set_scaling ( fs )
2008-04-08 13:30:47 -05:00
def control_fullscreen ( self , src ) :
menu = self . window . get_widget ( " details-menu-view-fullscreen " )
if src . get_active ( ) != menu . get_active ( ) :
menu . set_active ( src . get_active ( ) )
def toggle_fullscreen ( self , src ) :
self . window . get_widget ( " control-fullscreen " ) . set_active ( src . get_active ( ) )
2006-09-01 11:18:49 -04:00
if src . get_active ( ) :
2009-02-23 19:02:27 -05:00
# if scaling is enabled make sure we fit onto the root window
if self . vncViewer . get_scaling ( ) :
ignore , h = self . window . get_widget ( " menubar3 " ) . size_request ( )
rootw = src . get_screen ( ) . get_width ( )
rooth = src . get_screen ( ) . get_height ( ) - h
self . vncViewer . set_size_request ( rootw , rooth )
else :
self . vncViewer . set_size_request ( - 1 , - 1 )
2008-04-08 13:30:47 -05:00
self . window . get_widget ( " vmm-details " ) . fullscreen ( )
if self . config . get_console_keygrab ( ) == 1 :
gtk . gdk . keyboard_grab ( self . vncViewer . window , False , 0 L )
self . _disable_modifiers ( )
tabs = self . window . get_widget ( " details-pages " )
tabs . set_show_tabs ( False )
tabs . set_border_width ( 0 )
self . window . get_widget ( " details-toolbar " ) . hide ( )
else :
if self . config . get_console_keygrab ( ) == 1 :
self . _enable_modifiers ( )
gtk . gdk . keyboard_ungrab ( 0 L )
self . window . get_widget ( " vmm-details " ) . unfullscreen ( )
tabs = self . window . get_widget ( " details-pages " )
tabs . set_show_tabs ( True )
tabs . set_border_width ( 6 )
if self . window . get_widget ( " details-menu-view-toolbar " ) . get_active ( ) :
self . window . get_widget ( " details-toolbar " ) . show ( )
2009-02-23 18:50:27 -05:00
self . update_scaling ( )
2008-04-08 13:30:47 -05:00
2009-01-26 10:17:33 -05:00
def auth_login ( self , ignore ) :
2009-05-07 19:22:33 +01:00
self . set_credentials ( )
2009-01-26 10:17:33 -05:00
self . activate_viewer_page ( )
2008-04-08 13:30:47 -05:00
def toggle_toolbar ( self , src ) :
2008-09-05 16:34:14 -04:00
active = src . get_active ( )
self . config . set_details_show_toolbar ( active )
if active and not \
self . window . get_widget ( " details-menu-view-fullscreen " ) . get_active ( ) :
2006-09-01 11:18:49 -04:00
self . window . get_widget ( " details-toolbar " ) . show ( )
else :
self . window . get_widget ( " details-toolbar " ) . hide ( )
2008-10-02 16:17:25 -04:00
def populate_serial_menu ( self , src ) :
for ent in src :
src . remove ( ent )
devs = self . vm . get_serial_devs ( )
if len ( devs ) == 0 :
item = gtk . CheckMenuItem ( _ ( " No serial devices found " ) )
item . set_sensitive ( False )
src . add ( item )
usable_types = [ " pty " ]
for dev in devs :
sensitive = False
msg = " "
item = gtk . CheckMenuItem ( dev [ 0 ] )
if self . vm . get_connection ( ) . is_remote ( ) :
msg = _ ( " Serial console not yet supported over remote "
" connection. " )
elif not self . vm . is_active ( ) :
msg = _ ( " Serial console not available for inactive guest. " )
elif not dev [ 1 ] in usable_types :
msg = _ ( " Console for device type ' %s ' not yet supported. " ) % \
dev [ 1 ]
elif dev [ 2 ] and not os . access ( dev [ 2 ] , os . R_OK | os . W_OK ) :
msg = _ ( " Can not access console path ' %s ' . " ) % str ( dev [ 2 ] )
else :
sensitive = True
if not sensitive :
2009-01-26 11:12:43 -05:00
util . tooltip_wrapper ( item , msg )
2008-10-02 16:17:25 -04:00
item . set_sensitive ( sensitive )
if sensitive and self . dynamic_tabs . count ( dev [ 0 ] ) :
# Tab is already open, make sure marked as such
item . set_active ( True )
2009-07-14 19:42:16 -04:00
item . connect ( " activate " , self . control_serial_tab , dev [ 0 ] , dev [ 3 ] )
2008-10-02 16:17:25 -04:00
src . add ( item )
src . show_all ( )
2006-06-14 10:59:40 -04:00
def show ( self ) :
2008-06-13 14:40:26 -04:00
dialog = self . window . get_widget ( " vmm-details " )
2008-06-13 12:12:37 -04:00
if self . is_visible ( ) :
2008-06-13 14:40:26 -04:00
dialog . present ( )
2008-06-13 12:12:37 -04:00
return
2006-06-14 10:59:40 -04:00
dialog . show_all ( )
dialog . present ( )
2009-02-28 19:27:20 -05:00
2008-06-13 12:12:37 -04:00
self . engine . increment_window_counter ( )
2007-04-25 17:09:37 -04:00
self . update_widget_states ( self . vm , self . vm . status ( ) )
2006-06-14 10:59:40 -04:00
2007-03-16 16:27:50 -04:00
def show_help ( self , src ) :
# From the Details window, show the help document from the Details page
2007-04-12 15:36:04 -04:00
self . emit ( " action-show-help " , " virt-manager-details-window " )
2007-03-16 16:27:50 -04:00
2008-04-08 13:30:47 -05:00
def activate_console_page ( self ) :
2008-05-07 11:14:20 -04:00
self . window . get_widget ( " details-pages " ) . set_current_page ( PAGE_CONSOLE )
2006-07-13 17:44:49 -04:00
2008-04-08 13:30:47 -05:00
def activate_performance_page ( self ) :
2009-02-09 14:55:18 -05:00
self . window . get_widget ( " details-pages " ) . set_current_page ( PAGE_DETAILS )
self . window . get_widget ( " hw-panel " ) . set_current_page ( HW_LIST_TYPE_STATS )
2006-07-13 17:44:49 -04:00
2008-04-08 13:30:47 -05:00
def activate_config_page ( self ) :
2008-05-07 11:14:20 -04:00
self . window . get_widget ( " details-pages " ) . set_current_page ( PAGE_DETAILS )
2008-04-08 13:30:47 -05:00
2006-06-14 10:59:40 -04:00
def close ( self , ignore1 = None , ignore2 = None ) :
2008-04-08 13:30:47 -05:00
fs = self . window . get_widget ( " details-menu-view-fullscreen " )
if fs . get_active ( ) :
fs . set_active ( False )
2008-08-18 11:47:29 -04:00
if not self . is_visible ( ) :
return
2006-06-14 10:59:40 -04:00
self . window . get_widget ( " vmm-details " ) . hide ( )
2008-04-08 13:30:47 -05:00
if self . vncViewer . flags ( ) & gtk . VISIBLE :
2008-06-13 12:12:37 -04:00
try :
2008-04-08 13:30:47 -05:00
self . vncViewer . close ( )
2008-06-13 12:12:37 -04:00
except :
logging . error ( " Failure when disconnecting from VNC server " )
self . engine . decrement_window_counter ( )
2006-06-14 10:59:40 -04:00
return 1
2008-06-13 14:40:26 -04:00
def exit_app ( self , src ) :
self . emit ( " action-exit-app " )
2006-11-03 10:02:02 -05:00
def is_visible ( self ) :
if self . window . get_widget ( " vmm-details " ) . flags ( ) & gtk . VISIBLE :
2008-11-05 15:46:47 -05:00
return 1
2006-11-03 10:02:02 -05:00
return 0
2008-06-13 14:40:26 -04:00
def view_manager ( self , src ) :
self . emit ( " action-view-manager " )
2008-04-08 13:30:47 -05:00
def send_key ( self , src ) :
keys = None
if src . get_name ( ) == " details-menu-send-cad " :
keys = [ " Control_L " , " Alt_L " , " Delete " ]
elif src . get_name ( ) == " details-menu-send-cab " :
keys = [ " Control_L " , " Alt_L " , " BackSpace " ]
elif src . get_name ( ) == " details-menu-send-caf1 " :
keys = [ " Control_L " , " Alt_L " , " F1 " ]
elif src . get_name ( ) == " details-menu-send-caf2 " :
keys = [ " Control_L " , " Alt_L " , " F2 " ]
elif src . get_name ( ) == " details-menu-send-caf3 " :
keys = [ " Control_L " , " Alt_L " , " F3 " ]
elif src . get_name ( ) == " details-menu-send-caf4 " :
keys = [ " Control_L " , " Alt_L " , " F4 " ]
elif src . get_name ( ) == " details-menu-send-caf5 " :
keys = [ " Control_L " , " Alt_L " , " F5 " ]
elif src . get_name ( ) == " details-menu-send-caf6 " :
keys = [ " Control_L " , " Alt_L " , " F6 " ]
elif src . get_name ( ) == " details-menu-send-caf7 " :
keys = [ " Control_L " , " Alt_L " , " F7 " ]
elif src . get_name ( ) == " details-menu-send-caf8 " :
keys = [ " Control_L " , " Alt_L " , " F8 " ]
elif src . get_name ( ) == " details-menu-send-caf9 " :
keys = [ " Control_L " , " Alt_L " , " F9 " ]
elif src . get_name ( ) == " details-menu-send-caf10 " :
keys = [ " Control_L " , " Alt_L " , " F10 " ]
elif src . get_name ( ) == " details-menu-send-caf11 " :
keys = [ " Control_L " , " Alt_L " , " F11 " ]
elif src . get_name ( ) == " details-menu-send-caf12 " :
keys = [ " Control_L " , " Alt_L " , " F12 " ]
elif src . get_name ( ) == " details-menu-send-printscreen " :
2008-05-05 16:10:16 -04:00
keys = [ " Print " ]
2008-04-08 13:30:47 -05:00
if keys != None :
self . vncViewer . send_keys ( keys )
2009-07-09 14:35:44 -04:00
def hw_selected ( self , src = None , page = None , selected = True ) :
pagetype = page
if pagetype is None :
pagetype = self . get_hw_selection ( HW_LIST_COL_TYPE )
2009-07-07 12:16:03 -04:00
if pagetype is None :
2009-07-09 14:35:44 -04:00
pagetype = HW_LIST_TYPE_GENERAL
2009-02-28 19:27:20 -05:00
self . window . get_widget ( " hw-list " ) . get_selection ( ) . select_path ( 0 )
self . window . get_widget ( " hw-panel " ) . set_sensitive ( True )
self . window . get_widget ( " hw-panel " ) . show_all ( )
2007-04-12 15:36:04 -04:00
2009-02-28 19:27:20 -05:00
if pagetype == HW_LIST_TYPE_GENERAL :
2009-05-12 13:09:08 -04:00
self . refresh_overview_page ( )
2009-02-28 19:27:20 -05: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 ( )
2009-07-09 14:35:55 -04:00
elif pagetype == HW_LIST_TYPE_VIDEO :
self . refresh_video_page ( )
2006-06-14 10:59:40 -04:00
else :
2009-02-28 19:27:20 -05:00
pagetype = - 1
2009-07-09 14:35:36 -04:00
2009-07-09 14:35:44 -04:00
app = pagetype in apply_pages
rem = pagetype in remove_pages
if selected :
self . window . get_widget ( " config-apply " ) . set_sensitive ( False )
self . window . get_widget ( " config-apply " ) . set_property ( " visible " , app )
self . window . get_widget ( " config-remove " ) . set_property ( " visible " , rem )
2009-07-09 14:35:36 -04:00
2009-02-28 19:27:20 -05:00
self . window . get_widget ( " hw-panel " ) . set_current_page ( pagetype )
2006-06-14 10:59:40 -04:00
def control_vm_pause ( self , src ) :
2006-06-14 18:42:04 -04:00
if self . ignorePause :
return
2007-11-27 11:31:30 -05:00
if src . get_active ( ) :
self . emit ( " action-suspend-domain " , self . vm . get_connection ( ) . get_uri ( ) , self . vm . get_uuid ( ) )
2006-06-14 10:59:40 -04:00
else :
2007-11-27 11:31:30 -05:00
self . emit ( " action-resume-domain " , self . vm . get_connection ( ) . get_uri ( ) , self . vm . get_uuid ( ) )
self . update_widget_states ( self . vm , self . vm . status ( ) )
def control_vm_run ( self , src ) :
self . emit ( " action-run-domain " , self . vm . get_connection ( ) . get_uri ( ) , self . vm . get_uuid ( ) )
2006-06-14 10:59:40 -04:00
2007-11-27 11:31:30 -05:00
def control_vm_shutdown ( self , src ) :
self . emit ( " action-shutdown-domain " , self . vm . get_connection ( ) . get_uri ( ) , self . vm . get_uuid ( ) )
2006-09-01 11:18:49 -04:00
2008-04-08 13:30:47 -05:00
def control_vm_reboot ( self , src ) :
self . emit ( " action-reboot-domain " , self . vm . get_connection ( ) . get_uri ( ) , self . vm . get_uuid ( ) )
2006-06-14 18:51:58 -04:00
def control_vm_console ( self , src ) :
self . emit ( " action-show-console " , self . vm . get_connection ( ) . get_uri ( ) , self . vm . get_uuid ( ) )
2006-07-17 13:08:58 -04:00
def control_vm_save_domain ( self , src ) :
self . emit ( " action-save-domain " , self . vm . get_connection ( ) . get_uri ( ) , self . vm . get_uuid ( ) )
2006-06-14 10:59:40 -04:00
2006-11-15 12:27:36 -05:00
def control_vm_destroy ( self , src ) :
self . emit ( " action-destroy-domain " , self . vm . get_connection ( ) . get_uri ( ) , self . vm . get_uuid ( ) )
2009-07-14 15:59:57 -04:00
def control_vm_migrate ( self , src , uri ) :
2009-03-09 16:21:53 -04:00
self . emit ( " action-migrate-domain " , self . vm . get_connection ( ) . get_uri ( ) ,
2009-07-14 15:59:57 -04:00
self . vm . get_uuid ( ) , uri )
2008-10-30 16:38:13 -04:00
2009-04-03 14:18:40 -04:00
def populate_migrate_menu ( self , ignore1 = None ) :
2008-10-30 16:38:13 -04:00
menu = self . window . get_widget ( " details-menu-migrate_menu " )
2009-03-23 17:38:25 -04:00
self . engine . populate_migrate_menu ( menu , self . control_vm_migrate ,
self . vm )
2008-10-30 16:38:13 -04:00
2008-08-19 14:25:25 -04:00
def set_pause_widget_states ( self , state ) :
try :
self . ignorePause = True
self . window . get_widget ( " control-pause " ) . set_active ( state )
self . window . get_widget ( " details-menu-pause " ) . set_active ( state )
finally :
self . ignorePause = False
2006-06-14 18:42:04 -04:00
def update_widget_states ( self , vm , status ) :
2007-04-25 17:09:37 -04:00
self . toggle_toolbar ( self . window . get_widget ( " details-menu-view-toolbar " ) )
2008-07-24 16:39:09 -04:00
2008-08-19 14:25:25 -04:00
if status in [ libvirt . VIR_DOMAIN_SHUTDOWN ,
libvirt . VIR_DOMAIN_SHUTOFF ] or vm . is_read_only ( ) :
2006-11-15 12:27:36 -05:00
self . window . get_widget ( " details-menu-destroy " ) . set_sensitive ( False )
else :
self . window . get_widget ( " details-menu-destroy " ) . set_sensitive ( True )
2008-08-19 14:25:25 -04:00
2008-08-22 13:41:17 -04:00
if status in [ libvirt . VIR_DOMAIN_SHUTOFF , libvirt . VIR_DOMAIN_CRASHED ] and not self . vm . is_read_only ( ) :
2008-08-19 14:25:25 -04:00
self . window . get_widget ( " control-run " ) . set_sensitive ( True )
self . window . get_widget ( " details-menu-run " ) . set_sensitive ( True )
else :
self . window . get_widget ( " control-run " ) . set_sensitive ( False )
self . window . get_widget ( " details-menu-run " ) . set_sensitive ( False )
if status in [ libvirt . VIR_DOMAIN_SHUTDOWN , libvirt . VIR_DOMAIN_SHUTOFF ,
libvirt . VIR_DOMAIN_CRASHED ] or vm . is_read_only ( ) :
self . set_pause_widget_states ( False )
self . window . get_widget ( " control-shutdown " ) . set_sensitive ( False )
self . window . get_widget ( " details-menu-shutdown " ) . set_sensitive ( False )
self . window . get_widget ( " details-menu-save " ) . set_sensitive ( False )
self . window . get_widget ( " control-pause " ) . set_sensitive ( False )
self . window . get_widget ( " details-menu-pause " ) . set_sensitive ( False )
else :
self . window . get_widget ( " control-pause " ) . set_sensitive ( True )
self . window . get_widget ( " details-menu-pause " ) . set_sensitive ( True )
self . set_pause_widget_states ( status == libvirt . VIR_DOMAIN_PAUSED )
self . window . get_widget ( " control-shutdown " ) . set_sensitive ( True )
self . window . get_widget ( " details-menu-shutdown " ) . set_sensitive ( True )
self . window . get_widget ( " details-menu-save " ) . set_sensitive ( True )
2008-04-08 13:30:47 -05:00
2009-03-13 13:51:35 -04:00
ro = vm . is_read_only ( )
self . window . get_widget ( " config-vcpus " ) . set_sensitive ( not ro )
self . window . get_widget ( " config-memory " ) . set_sensitive ( not ro )
self . window . get_widget ( " config-maxmem " ) . set_sensitive ( not ro )
self . window . get_widget ( " details-menu-migrate " ) . set_sensitive ( not ro )
2008-10-30 16:38:13 -04:00
2009-04-03 14:18:40 -04:00
if status in [ libvirt . VIR_DOMAIN_SHUTOFF ,
libvirt . VIR_DOMAIN_CRASHED ] :
2008-04-08 13:30:47 -05:00
if self . window . get_widget ( " console-pages " ) . get_current_page ( ) != PAGE_UNAVAILABLE :
self . vncViewer . close ( )
self . window . get_widget ( " console-pages " ) . set_current_page ( PAGE_UNAVAILABLE )
self . view_vm_status ( )
else :
2008-05-07 10:03:56 -04:00
# Disabled screenshot when paused - doesn't work when scaled
# and you can connect to VNC when paused already, it'll simply
# not respond to input.
if status == libvirt . VIR_DOMAIN_PAUSED and 0 == 1 :
2008-04-08 13:30:47 -05:00
if self . window . get_widget ( " console-pages " ) . get_current_page ( ) == PAGE_VNCVIEWER :
screenshot = self . window . get_widget ( " console-screenshot " )
image = self . vncViewer . get_pixbuf ( )
width = image . get_width ( )
height = image . get_height ( )
pixmap = gtk . gdk . Pixmap ( screenshot . get_root_window ( ) , width , height )
cr = pixmap . cairo_create ( )
cr . set_source_pixbuf ( image , 0 , 0 )
cr . rectangle ( 0 , 0 , width , height )
cr . fill ( )
# Set 50% gray overlayed
cr . set_source_rgba ( 0 , 0 , 0 , 0.5 )
cr . rectangle ( 0 , 0 , width , height )
cr . fill ( )
# Render a big text 'paused' across it
cr . set_source_rgba ( 1 , 1 , 1 , 1 )
cr . set_font_size ( 80 )
cr . select_font_face ( " Sans " , cairo . FONT_SLANT_NORMAL , cairo . FONT_WEIGHT_NORMAL )
overlay = _ ( " paused " )
extents = cr . text_extents ( overlay )
x = width / 2 - ( extents [ 2 ] / 2 )
y = height / 2 - ( extents [ 3 ] / 2 )
cr . move_to ( x , y )
cr . show_text ( overlay )
screenshot . set_from_pixmap ( pixmap , None )
self . activate_screenshot_page ( )
elif self . window . get_widget ( " console-pages " ) . get_current_page ( ) == PAGE_SCREENSHOT :
pass
else :
if self . window . get_widget ( " console-pages " ) . get_current_page ( ) != PAGE_UNAVAILABLE :
self . vncViewer . close ( )
self . activate_unavailable_page ( _ ( " Console not available while paused " ) )
else :
2008-08-19 14:54:17 -04:00
page = self . window . get_widget ( " console-pages " ) . get_current_page ( )
if page in [ PAGE_UNAVAILABLE , PAGE_SCREENSHOT , PAGE_VNCVIEWER ] :
2008-04-08 13:30:47 -05:00
if self . vncViewer . is_open ( ) :
self . activate_viewer_page ( )
else :
self . vncViewerRetriesScheduled = 0
self . vncViewerRetryDelay = 125
self . try_login ( )
2006-06-14 10:59:40 -04:00
2006-06-14 18:42:04 -04:00
self . window . get_widget ( " overview-status-text " ) . set_text ( self . vm . run_status ( ) )
self . window . get_widget ( " overview-status-icon " ) . set_from_pixbuf ( self . vm . run_status_icon ( ) )
2006-06-14 10:59:40 -04:00
2008-11-18 14:48:10 -05:00
def switch_page ( self , ignore1 = None , ignore2 = None , newpage = None ) :
2008-05-07 11:26:00 -04:00
self . page_refresh ( newpage )
2009-02-28 19:27:20 -05:00
def refresh_resources ( self , ignore ) :
details = self . window . get_widget ( " details-pages " )
page = details . get_current_page ( )
2009-07-14 17:06:37 -04:00
# If the dialog is visible, we want to make sure the XML is always
# up to date
if self . is_visible ( ) :
2009-07-14 19:25:17 -04:00
self . vm . refresh_xml ( )
2009-07-14 17:06:37 -04:00
2009-02-28 19:27:20 -05:00
if ( page == PAGE_DETAILS and
self . get_hw_selection ( HW_LIST_COL_TYPE ) == HW_LIST_TYPE_STATS ) :
self . refresh_stats_page ( )
def refresh_vm_info ( self , ignore = None ) :
2007-04-12 15:36:04 -04:00
details = self . window . get_widget ( " details-pages " )
2008-05-07 11:26:00 -04:00
self . page_refresh ( details . get_current_page ( ) )
def page_refresh ( self , page ) :
2009-02-28 19:27:20 -05:00
if page != PAGE_DETAILS :
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 ( )
2009-07-09 14:35:44 -04:00
pagetype = self . get_hw_selection ( HW_LIST_COL_TYPE )
if pagetype is None :
return
pagetype = self . get_hw_selection ( HW_LIST_COL_TYPE )
self . hw_selected ( page = pagetype )
2006-11-13 15:31:17 -05:00
2009-05-12 13:09:08 -04:00
def refresh_overview_page ( self ) :
self . window . get_widget ( " overview-name " ) . set_text ( self . vm . get_name ( ) )
self . window . get_widget ( " overview-uuid " ) . set_text ( self . vm . get_uuid ( ) )
self . window . get_widget ( " overview-hv " ) . set_text ( self . vm . get_pretty_hv_type ( ) )
arch = self . vm . get_arch ( ) or _ ( " Unknown " )
emu = self . vm . get_emulator ( ) or _ ( " None " )
self . window . get_widget ( " overview-arch " ) . set_text ( arch )
self . window . get_widget ( " overview-emulator " ) . set_text ( emu )
2009-07-07 12:16:03 -04:00
vmmodel , ignore , vmlabel = self . vm . get_seclabel ( )
semodel_combo = self . window . get_widget ( " security-model " )
semodel_model = semodel_combo . get_model ( )
caps = self . vm . get_connection ( ) . get_capabilities ( )
semodel_model . clear ( )
semodel_model . append ( [ " None " ] )
if caps . host . secmodel and caps . host . secmodel . model :
semodel_model . append ( [ caps . host . secmodel . model ] )
active = 0
for i in range ( 0 , len ( semodel_model ) ) :
if vmmodel and vmmodel == semodel_model [ i ] [ 0 ] :
active = i
break
semodel_combo . set_active ( active )
if self . vm . get_seclabel ( ) [ 1 ] == " static " :
self . window . get_widget ( " security-static " ) . set_active ( True )
else :
self . window . get_widget ( " security-dynamic " ) . set_active ( True )
self . window . get_widget ( " security-label " ) . set_text ( vmlabel )
semodel_combo . emit ( " changed " )
2009-02-09 14:55:18 -05:00
def refresh_stats_page ( self ) :
2008-10-18 21:25:16 +02:00
def _rx_tx_text ( rx , tx , unit ) :
return ' <span color= " #82003B " > %(rx)d %(unit)s in</span> \n <span color= " #295C45 " > %(tx)d %(unit)s out</span> ' % locals ( )
2008-12-17 15:27:06 -05:00
cpu_txt = _ ( " Disabled " )
mem_txt = _ ( " Disabled " )
dsk_txt = _ ( " Disabled " )
net_txt = _ ( " Disabled " )
if self . config . get_stats_enable_cpu_poll ( ) :
cpu_txt = " %d %% " % self . vm . cpu_time_percentage ( )
if self . config . get_stats_enable_mem_poll ( ) :
vm_memory = self . vm . current_memory ( )
host_memory = self . vm . get_connection ( ) . host_memory_size ( )
mem_txt = " %d MB of %d MB " % ( int ( round ( vm_memory / 1024.0 ) ) ,
int ( round ( host_memory / 1024.0 ) ) )
if self . config . get_stats_enable_disk_poll ( ) :
dsk_txt = _rx_tx_text ( self . vm . disk_read_rate ( ) ,
2009-02-09 14:55:18 -05:00
self . vm . disk_write_rate ( ) , " KB/s " )
2008-12-17 15:27:06 -05:00
if self . config . get_stats_enable_net_poll ( ) :
net_txt = _rx_tx_text ( self . vm . network_rx_rate ( ) ,
2009-02-09 14:55:18 -05:00
self . vm . network_tx_rate ( ) , " KB/s " )
2008-12-17 15:27:06 -05:00
self . window . get_widget ( " overview-cpu-usage-text " ) . set_text ( cpu_txt )
self . window . get_widget ( " overview-memory-usage-text " ) . set_text ( mem_txt )
self . window . get_widget ( " overview-network-traffic-text " ) . set_markup ( net_txt )
self . window . get_widget ( " overview-disk-usage-text " ) . set_markup ( dsk_txt )
self . cpu_usage_graph . set_property ( " data_array " ,
self . vm . cpu_time_vector ( ) )
self . memory_usage_graph . set_property ( " data_array " ,
self . vm . current_memory_vector ( ) )
self . disk_io_graph . set_property ( " data_array " ,
self . vm . disk_io_vector ( ) )
self . network_traffic_graph . set_property ( " data_array " ,
self . vm . network_traffic_vector ( ) )
2006-06-14 10:59:40 -04:00
2006-11-13 15:31:17 -05:00
def refresh_config_cpu ( self ) :
2006-09-22 12:31:51 -04:00
self . window . get_widget ( " state-host-cpus " ) . set_text ( " %d " % self . vm . get_connection ( ) . host_active_processor_count ( ) )
2006-11-13 15:31:17 -05:00
status = self . vm . status ( )
if status in [ libvirt . VIR_DOMAIN_SHUTOFF , libvirt . VIR_DOMAIN_CRASHED ] :
2009-06-16 15:36:10 -04:00
cpu_max = self . vm . get_connection ( ) . get_max_vcpus ( self . vm . get_hv_type ( ) )
2007-06-18 15:16:20 -04:00
self . window . get_widget ( " config-vcpus " ) . get_adjustment ( ) . upper = cpu_max
self . window . get_widget ( " state-vm-maxvcpus " ) . set_text ( str ( cpu_max ) )
2006-11-13 15:31:17 -05:00
else :
self . window . get_widget ( " config-vcpus " ) . get_adjustment ( ) . upper = self . vm . vcpu_max_count ( )
self . window . get_widget ( " state-vm-maxvcpus " ) . set_text ( " %d " % ( self . vm . vcpu_max_count ( ) ) )
2009-07-09 14:35:36 -04:00
if not ( self . window . get_widget ( " config-apply " ) . get_property ( " sensitive " ) ) :
2006-11-13 15:31:17 -05:00
self . window . get_widget ( " config-vcpus " ) . get_adjustment ( ) . value = self . vm . vcpu_count ( )
self . window . get_widget ( " state-vm-vcpus " ) . set_text ( " %d " % ( self . vm . vcpu_count ( ) ) )
def refresh_config_memory ( self ) :
2007-09-27 11:09:50 -04:00
self . window . get_widget ( " state-host-memory " ) . set_text ( " %d MB " % ( int ( round ( self . vm . get_connection ( ) . host_memory_size ( ) / 1024 ) ) ) )
2008-03-18 14:37:22 -04:00
curmem = self . window . get_widget ( " config-memory " ) . get_adjustment ( )
maxmem = self . window . get_widget ( " config-maxmem " ) . get_adjustment ( )
2009-07-09 14:35:36 -04:00
if self . window . get_widget ( " config-apply " ) . get_property ( " sensitive " ) :
2009-06-16 18:04:29 -04:00
memval = self . config_get_memory ( )
maxval = self . config_get_maxmem ( )
if maxval < memval :
maxmem . value = memval
maxmem . lower = memval
2006-11-13 15:31:17 -05:00
else :
2008-03-18 14:37:22 -04:00
curmem . value = int ( round ( self . vm . get_memory ( ) / 1024.0 ) )
maxmem . value = int ( round ( self . vm . maximum_memory ( ) / 1024.0 ) )
2006-09-22 12:31:51 -04:00
2008-03-18 14:37:22 -04:00
if not self . window . get_widget ( " config-memory " ) . get_property ( " sensitive " ) :
maxmem . lower = curmem . value
2007-09-27 11:09:50 -04:00
self . window . get_widget ( " state-vm-memory " ) . set_text ( " %d MB " % int ( round ( self . vm . get_memory ( ) / 1024.0 ) ) )
2006-07-26 18:19:33 -04:00
2009-01-15 11:23:23 -05:00
def get_hw_selection ( self , field ) :
2007-04-11 14:48:36 -04:00
vmlist = self . window . get_widget ( " hw-list " )
selection = vmlist . get_selection ( )
active = selection . get_selected ( )
2009-01-15 11:23:23 -05:00
if active [ 1 ] == None :
return None
else :
return active [ 0 ] . get_value ( active [ 1 ] , field )
def refresh_disk_page ( self ) :
diskinfo = self . get_hw_selection ( HW_LIST_COL_DEVICE )
if not diskinfo :
return
2009-01-15 11:01:24 -05:00
self . window . get_widget ( " disk-source-type " ) . set_text ( diskinfo [ 5 ] )
self . window . get_widget ( " disk-source-path " ) . set_text ( diskinfo [ 3 ] )
self . window . get_widget ( " disk-target-type " ) . set_text ( diskinfo [ 4 ] )
self . window . get_widget ( " disk-target-device " ) . set_text ( diskinfo [ 2 ] )
if diskinfo [ 6 ] == True :
2009-01-15 11:23:23 -05:00
perms = " Readonly "
else :
perms = " Read/Write "
2009-01-15 11:01:24 -05:00
if diskinfo [ 7 ] == True :
2009-02-28 19:27:20 -05:00
perms + = " , Shareable "
2009-01-15 11:23:23 -05:00
self . window . get_widget ( " disk-permissions " ) . set_text ( perms )
2009-01-15 11:01:24 -05:00
bus = diskinfo [ 8 ] or _ ( " Unknown " )
2009-01-15 11:23:23 -05:00
self . window . get_widget ( " disk-bus " ) . set_text ( bus )
button = self . window . get_widget ( " config-cdrom-connect " )
2009-01-15 11:01:24 -05:00
if diskinfo [ 4 ] == " cdrom " :
if diskinfo [ 3 ] == " - " :
2009-01-15 11:23:23 -05:00
# source device not connected
button . set_label ( gtk . STOCK_CONNECT )
2007-09-21 16:28:31 -04:00
else :
2009-01-15 11:23:23 -05:00
button . set_label ( gtk . STOCK_DISCONNECT )
button . show ( )
else :
button . hide ( )
2007-04-11 14:48:36 -04:00
def refresh_network_page ( self ) :
2009-01-15 11:23:23 -05:00
netinfo = self . get_hw_selection ( HW_LIST_COL_DEVICE )
if not netinfo :
return
2009-01-15 11:01:24 -05:00
self . window . get_widget ( " network-source-type " ) . set_text ( netinfo [ 5 ] )
if netinfo [ 3 ] is not None :
self . window . get_widget ( " network-source-device " ) . set_text ( netinfo [ 3 ] )
2009-01-15 11:23:23 -05:00
else :
self . window . get_widget ( " network-source-device " ) . set_text ( " - " )
2009-01-15 11:01:24 -05:00
self . window . get_widget ( " network-mac-address " ) . set_text ( netinfo [ 2 ] )
2009-01-15 11:23:23 -05:00
2009-01-15 11:01:24 -05:00
model = netinfo [ 6 ] or _ ( " Hypervisor Default " )
2009-01-15 11:23:23 -05:00
self . window . get_widget ( " network-source-model " ) . set_text ( model )
2007-04-12 15:36:04 -04:00
2007-09-25 20:05:45 -04:00
def refresh_input_page ( self ) :
2009-01-15 11:23:23 -05:00
inputinfo = self . get_hw_selection ( HW_LIST_COL_DEVICE )
if not inputinfo :
return
2007-09-25 20:05:45 -04:00
2009-01-15 11:01:24 -05:00
if inputinfo [ 2 ] == " tablet:usb " :
2009-01-15 11:23:23 -05:00
self . window . get_widget ( " input-dev-type " ) . set_text ( _ ( " EvTouch USB Graphics Tablet " ) )
2009-01-15 11:01:24 -05:00
elif inputinfo [ 2 ] == " mouse:usb " :
2009-01-15 11:23:23 -05:00
self . window . get_widget ( " input-dev-type " ) . set_text ( _ ( " Generic USB Mouse " ) )
2009-01-15 11:01:24 -05:00
elif inputinfo [ 2 ] == " mouse:xen " :
2009-01-15 11:23:23 -05:00
self . window . get_widget ( " input-dev-type " ) . set_text ( _ ( " Xen Mouse " ) )
2009-01-15 11:01:24 -05:00
elif inputinfo [ 2 ] == " mouse:ps2 " :
2009-01-15 11:23:23 -05:00
self . window . get_widget ( " input-dev-type " ) . set_text ( _ ( " PS/2 Mouse " ) )
else :
2009-01-15 11:01:24 -05:00
self . window . get_widget ( " input-dev-type " ) . set_text ( inputinfo [ 4 ] + \
" " \
+ inputinfo [ 3 ] )
2007-09-25 20:05:45 -04:00
2009-01-15 11:01:24 -05:00
if inputinfo [ 4 ] == " tablet " :
2009-01-15 11:23:23 -05:00
self . window . get_widget ( " input-dev-mode " ) . set_text ( _ ( " Absolute Movement " ) )
else :
self . window . get_widget ( " input-dev-mode " ) . set_text ( _ ( " Relative Movement " ) )
# Can't remove primary Xen or PS/2 mice
2009-01-15 11:01:24 -05:00
if inputinfo [ 4 ] == " mouse " and inputinfo [ 3 ] in ( " xen " , " ps2 " ) :
2009-07-09 14:35:36 -04:00
self . window . get_widget ( " config-remove " ) . set_sensitive ( False )
2009-01-15 11:23:23 -05:00
else :
2009-07-09 14:35:36 -04:00
self . window . get_widget ( " config-remove " ) . set_sensitive ( True )
2007-09-25 20:05:45 -04:00
2007-09-26 19:39:11 -04:00
def refresh_graphics_page ( self ) :
2009-01-15 11:23:23 -05:00
gfxinfo = self . get_hw_selection ( HW_LIST_COL_DEVICE )
if not gfxinfo :
return
2007-09-26 19:39:11 -04:00
2009-01-15 11:01:24 -05:00
if gfxinfo [ 2 ] == " vnc " :
2009-01-15 11:23:23 -05:00
self . window . get_widget ( " graphics-type " ) . set_text ( _ ( " VNC server " ) )
2009-01-15 11:01:24 -05:00
elif gfxinfo [ 2 ] == " sdl " :
2009-01-15 11:23:23 -05:00
self . window . get_widget ( " graphics-type " ) . set_text ( _ ( " Local SDL window " ) )
else :
2009-01-15 11:01:24 -05:00
self . window . get_widget ( " graphics-type " ) . set_text ( gfxinfo [ 2 ] )
2009-01-15 11:23:23 -05:00
2009-01-15 11:01:24 -05:00
if gfxinfo [ 2 ] == " vnc " :
if gfxinfo [ 3 ] == None :
2009-01-15 11:23:23 -05:00
self . window . get_widget ( " graphics-address " ) . set_text ( " 127.0.0.1 " )
2007-09-26 19:39:11 -04:00
else :
2009-01-15 11:01:24 -05:00
self . window . get_widget ( " graphics-address " ) . set_text ( gfxinfo [ 3 ] )
if int ( gfxinfo [ 4 ] ) == - 1 :
2009-01-15 11:23:23 -05:00
self . window . get_widget ( " graphics-port " ) . set_text ( _ ( " Automatically allocated " ) )
2007-09-26 19:39:11 -04:00
else :
2009-01-15 11:01:24 -05:00
self . window . get_widget ( " graphics-port " ) . set_text ( gfxinfo [ 4 ] )
2009-01-15 11:23:23 -05:00
self . window . get_widget ( " graphics-password " ) . set_text ( " - " )
2009-01-15 11:01:24 -05:00
self . window . get_widget ( " graphics-keymap " ) . set_text ( gfxinfo [ 5 ] or " en-us " )
2009-01-15 11:23:23 -05:00
else :
self . window . get_widget ( " graphics-address " ) . set_text ( _ ( " N/A " ) )
self . window . get_widget ( " graphics-port " ) . set_text ( _ ( " N/A " ) )
self . window . get_widget ( " graphics-password " ) . set_text ( " N/A " )
self . window . get_widget ( " graphics-keymap " ) . set_text ( " N/A " )
2008-07-30 19:52:39 -04:00
def refresh_sound_page ( self ) :
2009-01-15 11:23:23 -05:00
soundinfo = self . get_hw_selection ( HW_LIST_COL_DEVICE )
if not soundinfo :
2008-07-30 19:52:39 -04:00
return
2009-01-15 11:23:23 -05:00
2009-01-15 11:01:24 -05:00
self . window . get_widget ( " sound-model " ) . set_text ( soundinfo [ 2 ] )
2008-07-30 19:52:39 -04:00
2008-07-30 20:38:09 -04:00
def refresh_char_page ( self ) :
2009-01-15 11:23:23 -05:00
charinfo = self . get_hw_selection ( HW_LIST_COL_DEVICE )
if not charinfo :
2008-07-30 20:38:09 -04:00
return
2009-01-15 11:23:23 -05:00
typelabel = " <b> %s Device %s </b> " % ( charinfo [ 0 ] . capitalize ( ) ,
2009-01-15 11:01:24 -05:00
charinfo [ 6 ] and \
2009-01-15 11:23:23 -05:00
_ ( " (Primary Console) " ) or " " )
2008-07-30 20:38:09 -04:00
self . window . get_widget ( " char-type " ) . set_markup ( typelabel )
2009-01-15 11:01:24 -05:00
self . window . get_widget ( " char-dev-type " ) . set_text ( charinfo [ 4 ] or " - " )
2009-03-13 11:21:07 -04:00
self . window . get_widget ( " char-target-port " ) . set_text ( charinfo [ 3 ] or " " )
2009-01-15 11:01:24 -05:00
self . window . get_widget ( " char-source-path " ) . set_text ( charinfo [ 5 ] or " - " )
2008-07-30 20:38:09 -04:00
2009-01-22 17:00:38 -05:00
def refresh_hostdev_page ( self ) :
hostdevinfo = self . get_hw_selection ( HW_LIST_COL_DEVICE )
if not hostdevinfo :
return
devlabel = " <b>Physical %s Device</b> " % hostdevinfo [ 4 ] . upper ( )
self . window . get_widget ( " hostdev-title " ) . set_markup ( devlabel )
self . window . get_widget ( " hostdev-type " ) . set_text ( hostdevinfo [ 4 ] )
self . window . get_widget ( " hostdev-mode " ) . set_text ( hostdevinfo [ 3 ] )
self . window . get_widget ( " hostdev-source " ) . set_text ( hostdevinfo [ 5 ] )
2009-07-09 14:35:55 -04:00
def refresh_video_page ( self ) :
vidinfo = self . get_hw_selection ( HW_LIST_COL_DEVICE )
if not vidinfo :
return
ignore , ignore , model , ram , heads = vidinfo
try :
ramlabel = ram and " %d MB " % ( int ( ram ) / 1024 ) or " - "
except :
ramlabel = " - "
self . window . get_widget ( " video-model " ) . set_text ( model )
self . window . get_widget ( " video-ram " ) . set_text ( ramlabel )
self . window . get_widget ( " video-heads " ) . set_text ( heads and heads or " - " )
2009-01-22 17:00:38 -05:00
2008-03-06 16:43:46 -05:00
def refresh_boot_page ( self ) :
# Refresh autostart
try :
autoval = self . vm . get_autostart ( )
self . window . get_widget ( " config-autostart " ) . set_active ( autoval )
self . window . get_widget ( " config-autostart " ) . set_sensitive ( True )
2008-11-18 14:48:10 -05:00
except libvirt . libvirtError :
2008-03-06 16:43:46 -05:00
# Autostart isn't supported
self . window . get_widget ( " config-autostart " ) . set_active ( False )
self . window . get_widget ( " config-autostart " ) . set_sensitive ( False )
# Refresh Boot Device list and correct selection
boot_combo = self . window . get_widget ( " config-boot-device " )
if not self . vm . is_hvm ( ) :
# Boot dev selection not supported for PV guest
boot_combo . set_sensitive ( False )
boot_combo . set_active ( - 1 )
return
self . repopulate_boot_list ( )
bootdev = self . vm . get_boot_device ( )
boot_combo = self . window . get_widget ( " config-boot-device " )
boot_model = boot_combo . get_model ( )
for i in range ( 0 , len ( boot_model ) ) :
if bootdev == boot_model [ i ] [ 2 ] :
boot_combo . set_active ( i )
break
if boot_model [ 0 ] [ 2 ] == None :
# If no boot devices, select the 'No Device' entry
boot_combo . set_active ( 0 )
# TODO: if nothing selected, what to select? auto change device?
2008-04-08 13:30:47 -05:00
def view_vm_status ( self ) :
status = self . vm . status ( )
if status == libvirt . VIR_DOMAIN_SHUTOFF :
self . activate_unavailable_page ( _ ( " Guest not running " ) )
else :
if status == libvirt . VIR_DOMAIN_CRASHED :
self . activate_unavailable_page ( _ ( " Guest has crashed " ) )
def _vnc_disconnected ( self , src ) :
if self . vncTunnel is not None :
self . close_tunnel ( )
2009-01-15 09:43:37 -05:00
self . vnc_connected = False
2008-04-08 13:30:47 -05:00
logging . debug ( " VNC disconnected " )
2009-07-08 21:31:04 -04:00
if self . vm . status ( ) in [ libvirt . VIR_DOMAIN_SHUTOFF ,
libvirt . VIR_DOMAIN_CRASHED ] :
2008-04-08 13:30:47 -05:00
self . view_vm_status ( )
return
self . activate_unavailable_page ( _ ( " TCP/IP error: VNC connection to hypervisor host got refused or disconnected! " ) )
if not self . is_visible ( ) :
return
self . schedule_retry ( )
def _vnc_initialized ( self , src ) :
2009-01-15 09:43:37 -05:00
self . vnc_connected = True
2008-04-08 13:30:47 -05:00
logging . debug ( " VNC initialized " )
self . activate_viewer_page ( )
# Had a succesfull connect, so reset counters now
self . vncViewerRetriesScheduled = 0
self . vncViewerRetryDelay = 125
def schedule_retry ( self ) :
self . vncViewerRetriesScheduled = self . vncViewerRetriesScheduled + 1
if self . vncViewerRetriesScheduled > = 10 :
logging . error ( " Too many connection failures, not retrying again " )
return
logging . warn ( " Retrying connection in %d ms " , self . vncViewerRetryDelay )
gobject . timeout_add ( self . vncViewerRetryDelay , self . retry_login )
if self . vncViewerRetryDelay < 2000 :
self . vncViewerRetryDelay = self . vncViewerRetryDelay * 2
def retry_login ( self ) :
2009-01-15 09:43:37 -05:00
if self . vnc_connected :
2008-04-08 13:30:47 -05:00
return
2009-07-08 21:31:04 -04:00
if self . vm . status ( ) in [ libvirt . VIR_DOMAIN_SHUTOFF ,
libvirt . VIR_DOMAIN_CRASHED ] :
return
2008-04-08 13:30:47 -05:00
gtk . gdk . threads_enter ( )
try :
logging . debug ( " Got timed retry " )
self . try_login ( )
return
finally :
gtk . gdk . threads_leave ( )
def open_tunnel ( self , server , vncaddr , vncport , username ) :
if self . vncTunnel is not None :
2009-01-12 17:05:16 -05:00
return - 1
2008-04-08 13:30:47 -05:00
logging . debug ( " Spawning SSH tunnel to %s , for %s : %d " % ( server , vncaddr , vncport ) )
fds = socket . socketpair ( )
pid = os . fork ( )
if pid == 0 :
fds [ 0 ] . close ( )
os . close ( 0 )
os . close ( 1 )
os . dup ( fds [ 1 ] . fileno ( ) )
os . dup ( fds [ 1 ] . fileno ( ) )
2008-05-20 10:28:32 -04:00
if not server . count ( " : " ) :
2008-08-22 13:17:37 -04:00
sshport = " 22 "
2008-05-20 10:28:32 -04:00
else :
( server , sshport ) = server . split ( " : " )
argv = [ " ssh " , " ssh " , " -p " , sshport ]
2008-04-08 13:30:47 -05:00
if username :
argv + = [ ' -l ' , username ]
2009-04-23 11:29:41 -04:00
argv + = [ server , " nc " , vncaddr , str ( vncport ) ]
2008-04-08 13:30:47 -05:00
os . execlp ( * argv )
os . _exit ( 1 )
else :
fds [ 1 ] . close ( )
logging . debug ( " Tunnel PID %d FD %d " % ( fds [ 0 ] . fileno ( ) , pid ) )
self . vncTunnel = [ fds [ 0 ] , pid ]
return fds [ 0 ] . fileno ( )
def close_tunnel ( self ) :
if self . vncTunnel is None :
return
logging . debug ( " Shutting down tunnel PID %d FD %d " % ( self . vncTunnel [ 1 ] , self . vncTunnel [ 0 ] . fileno ( ) ) )
self . vncTunnel [ 0 ] . close ( )
os . waitpid ( self . vncTunnel [ 1 ] , 0 )
self . vncTunnel = None
def try_login ( self , src = None ) :
2009-03-08 15:11:56 -04:00
if not self . vm . vm :
# VM was removed, skip login attempt
return
2008-04-08 13:30:47 -05:00
if self . vm . get_id ( ) < 0 :
self . activate_unavailable_page ( _ ( " Guest not running " ) )
self . schedule_retry ( )
return
logging . debug ( " Trying console login " )
protocol , host , port , trans , username = self . vm . get_graphics_console ( )
if protocol is None :
logging . debug ( " No graphics configured in guest " )
self . activate_unavailable_page ( _ ( " Console not configured for guest " ) )
return
uri = str ( protocol ) + " :// "
if username :
uri = uri + str ( username ) + ' @ '
uri = uri + str ( host ) + " : " + str ( port )
logging . debug ( " Graphics console configured at " + uri )
if protocol != " vnc " :
logging . debug ( " Not a VNC console, disabling " )
self . activate_unavailable_page ( _ ( " Console not supported for guest " ) )
return
if int ( port ) == - 1 :
self . activate_unavailable_page ( _ ( " Console is not yet active for guest " ) )
self . schedule_retry ( )
return
self . activate_unavailable_page ( _ ( " Connecting to console for guest " ) )
logging . debug ( " Starting connect process for %s %s " % ( host , str ( port ) ) )
try :
if trans is not None and trans in ( " ssh " , " ext " ) :
2009-01-12 17:05:16 -05:00
if self . vncTunnel :
logging . debug ( " Tunnel already open, skipping open_tunnel. " )
return
2008-04-08 13:30:47 -05:00
fd = self . open_tunnel ( host , " 127.0.0.1 " , port , username )
2009-01-12 17:05:16 -05:00
if fd > = 0 :
self . vncViewer . open_fd ( fd )
2008-04-08 13:30:47 -05:00
else :
self . vncViewer . open_host ( host , str ( port ) )
except :
2008-11-18 15:42:51 -05:00
( typ , value , stacktrace ) = sys . exc_info ( )
2008-04-08 13:30:47 -05:00
details = \
" Unable to start virtual machine ' %s ' " % \
2008-11-18 15:42:51 -05:00
( str ( typ ) + " " + str ( value ) + " \n " + \
2008-04-08 13:30:47 -05:00
traceback . format_exc ( stacktrace ) )
logging . error ( details )
2009-05-07 19:22:33 +01:00
def set_credentials ( self , src = None ) :
passwd = self . window . get_widget ( " console-auth-password " )
if passwd . flags ( ) & gtk . VISIBLE :
self . vncViewer . set_credential ( gtkvnc . CREDENTIAL_PASSWORD ,
passwd . get_text ( ) )
username = self . window . get_widget ( " console-auth-username " )
if username . flags ( ) & gtk . VISIBLE :
self . vncViewer . set_credential ( gtkvnc . CREDENTIAL_USERNAME ,
username . get_text ( ) )
if self . window . get_widget ( " console-auth-remember " ) . get_active ( ) :
self . config . set_console_password ( self . vm , passwd . get_text ( ) , username . get_text ( ) )
2008-04-08 13:30:47 -05:00
def _vnc_auth_credential ( self , src , credList ) :
2009-05-07 19:22:33 +01:00
for i in range ( len ( credList ) ) :
if credList [ i ] not in ( gtkvnc . CREDENTIAL_PASSWORD , gtkvnc . CREDENTIAL_USERNAME , gtkvnc . CREDENTIAL_CLIENTNAME ) :
self . err . show_err ( summary = _ ( " Unable to provide requested credentials to the VNC server " ) ,
details = _ ( " The credential type %s is not supported " ) % ( str ( credList [ i ] ) ) ,
title = _ ( " Unable to authenticate " ) ,
async = True )
self . vncViewerRetriesScheduled = 10
self . vncViewer . close ( )
self . activate_unavailable_page ( _ ( " Unsupported console authentication type " ) )
return
withUsername = False
withPassword = False
2008-04-08 13:30:47 -05:00
for i in range ( len ( credList ) ) :
logging . debug ( " Got credential request %s " , str ( credList [ i ] ) )
if credList [ i ] == gtkvnc . CREDENTIAL_PASSWORD :
2009-05-07 19:22:33 +01:00
withPassword = True
elif credList [ i ] == gtkvnc . CREDENTIAL_USERNAME :
withUsername = True
2008-04-08 13:30:47 -05:00
elif credList [ i ] == gtkvnc . CREDENTIAL_CLIENTNAME :
self . vncViewer . set_credential ( credList [ i ] , " libvirt-vnc " )
2009-05-07 19:22:33 +01:00
if withUsername or withPassword :
self . activate_auth_page ( withPassword , withUsername )
2008-04-08 13:30:47 -05:00
def activate_unavailable_page ( self , msg ) :
self . window . get_widget ( " console-pages " ) . set_current_page ( PAGE_UNAVAILABLE )
self . window . get_widget ( " details-menu-vm-screenshot " ) . set_sensitive ( False )
self . window . get_widget ( " console-unavailable " ) . set_label ( " <b> " + msg + " </b> " )
def activate_screenshot_page ( self ) :
self . window . get_widget ( " console-pages " ) . set_current_page ( PAGE_SCREENSHOT )
self . window . get_widget ( " details-menu-vm-screenshot " ) . set_sensitive ( True )
2009-05-07 19:22:33 +01:00
def activate_auth_page ( self , withPassword = True , withUsername = False ) :
( pw , username ) = self . config . get_console_password ( self . vm )
2008-04-08 13:30:47 -05:00
self . window . get_widget ( " details-menu-vm-screenshot " ) . set_sensitive ( False )
2009-05-07 19:22:33 +01:00
if withPassword :
self . window . get_widget ( " console-auth-password " ) . show ( )
self . window . get_widget ( " label-auth-password " ) . show ( )
else :
self . window . get_widget ( " console-auth-password " ) . hide ( )
self . window . get_widget ( " label-auth-password " ) . hide ( )
if withUsername :
self . window . get_widget ( " console-auth-username " ) . show ( )
self . window . get_widget ( " label-auth-username " ) . show ( )
else :
self . window . get_widget ( " console-auth-username " ) . hide ( )
self . window . get_widget ( " label-auth-username " ) . hide ( )
self . window . get_widget ( " console-auth-username " ) . set_text ( username )
2008-04-08 13:30:47 -05:00
self . window . get_widget ( " console-auth-password " ) . set_text ( pw )
2009-05-07 19:22:33 +01:00
2008-04-08 13:30:47 -05:00
if self . config . has_keyring ( ) :
self . window . get_widget ( " console-auth-remember " ) . set_sensitive ( True )
2009-05-07 19:22:33 +01:00
if pw != " " or username != " " :
2008-04-08 13:30:47 -05:00
self . window . get_widget ( " console-auth-remember " ) . set_active ( True )
else :
self . window . get_widget ( " console-auth-remember " ) . set_active ( False )
else :
self . window . get_widget ( " console-auth-remember " ) . set_sensitive ( False )
self . window . get_widget ( " console-pages " ) . set_current_page ( PAGE_AUTHENTICATE )
2009-05-07 19:22:33 +01:00
if withUsername :
self . window . get_widget ( " console-auth-username " ) . grab_focus ( )
else :
self . window . get_widget ( " console-auth-password " ) . grab_focus ( )
2008-04-08 13:30:47 -05:00
def activate_viewer_page ( self ) :
self . window . get_widget ( " console-pages " ) . set_current_page ( PAGE_VNCVIEWER )
self . window . get_widget ( " details-menu-vm-screenshot " ) . set_sensitive ( True )
self . vncViewer . grab_focus ( )
def control_vm_screenshot ( self , src ) :
# If someone feels kind they could extend this code to allow
# user to choose what image format they'd like to save in....
2009-03-08 15:14:00 -04:00
path = util . browse_local ( self . window . get_widget ( " vmm-details " ) ,
_ ( " Save Virtual Machine Screenshot " ) ,
2009-06-23 19:30:12 -04:00
self . config , self . vm . get_connection ( ) ,
_type = ( " png " , " PNG files " ) ,
dialog_type = gtk . FILE_CHOOSER_ACTION_SAVE ,
browse_reason = self . config . CONFIG_DIR_SCREENSHOT )
2009-03-08 15:14:00 -04:00
if not path :
return
filename = path
if not ( filename . endswith ( " .png " ) ) :
filename + = " .png "
image = self . vncViewer . get_pixbuf ( )
# Save along with a little metadata about us & the domain
image . save ( filename , ' png ' ,
{ ' tEXt::Hypervisor URI ' : self . vm . get_connection ( ) . 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 ( ) } )
msg = gtk . MessageDialog ( self . window . get_widget ( " vmm-details " ) ,
gtk . DIALOG_MODAL ,
gtk . MESSAGE_INFO ,
gtk . BUTTONS_OK ,
( _ ( " The screenshot has been saved to: \n %s " ) %
filename ) )
msg . set_title ( _ ( " Screenshot saved " ) )
msg . run ( )
msg . destroy ( )
2008-04-08 13:30:47 -05:00
2008-10-02 16:17:25 -04:00
# ------------------------------
# Serial Console pieces
# ------------------------------
2009-07-14 19:42:16 -04:00
def control_serial_tab ( self , src , name , target_port ) :
2008-10-02 16:17:25 -04:00
if src . get_active ( ) :
2009-07-14 19:42:16 -04:00
self . _show_serial_tab ( name , target_port )
2008-10-02 16:17:25 -04:00
else :
self . _close_serial_tab ( name )
def show_serial_rcpopup ( self , src , event ) :
if event . button != 3 :
return
self . serial_popup . show_all ( )
self . serial_copy . connect ( " activate " , self . serial_copy_text , src )
self . serial_paste . connect ( " activate " , self . serial_paste_text , src )
self . serial_close . connect ( " activate " , self . serial_close_tab ,
self . window . get_widget ( " details-pages " ) . get_current_page ( ) )
if src . get_has_selection ( ) :
self . serial_copy . set_sensitive ( True )
else :
self . serial_copy . set_sensitive ( False )
self . serial_popup . popup ( None , None , None , 0 , event . time )
def serial_close_tab ( self , src , pagenum ) :
tab_idx = ( pagenum - PAGE_DYNAMIC_OFFSET )
if ( tab_idx < 0 ) or ( tab_idx > len ( self . dynamic_tabs ) - 1 ) :
return
return self . _close_serial_tab ( self . dynamic_tabs [ tab_idx ] )
def serial_copy_text ( self , src , terminal ) :
terminal . copy_clipboard ( )
def serial_paste_text ( self , src , terminal ) :
terminal . paste_clipboard ( )
2009-07-14 19:42:16 -04:00
def _show_serial_tab ( self , name , target_port ) :
2008-10-02 16:17:25 -04:00
if not self . dynamic_tabs . count ( name ) :
2009-07-14 19:42:16 -04:00
child = vmmSerialConsole ( self . vm , target_port )
2008-10-02 16:17:25 -04:00
child . terminal . connect ( " button-press-event " ,
self . show_serial_rcpopup )
title = gtk . Label ( name )
child . show_all ( )
self . window . get_widget ( " details-pages " ) . append_page ( child , title )
self . dynamic_tabs . append ( name )
page_idx = self . dynamic_tabs . index ( name ) + PAGE_DYNAMIC_OFFSET
self . window . get_widget ( " details-pages " ) . set_current_page ( page_idx )
def _close_serial_tab ( self , name ) :
if not self . dynamic_tabs . count ( name ) :
return
page_idx = self . dynamic_tabs . index ( name ) + PAGE_DYNAMIC_OFFSET
self . window . get_widget ( " details-pages " ) . remove_page ( page_idx )
self . dynamic_tabs . remove ( name )
# -----------------------
2009-07-07 12:16:03 -04:00
# Overview -> Security
# -----------------------
def security_model_changed ( self , combo ) :
model = combo . get_model ( )
idx = combo . get_active ( )
if idx < 0 :
return
2009-07-09 14:35:36 -04:00
self . window . get_widget ( " config-apply " ) . set_sensitive ( True )
2009-07-07 12:16:03 -04:00
val = model [ idx ] [ 0 ]
show_type = ( val == " selinux " )
self . window . get_widget ( " security-type-box " ) . set_sensitive ( show_type )
def security_label_changed ( self , label ) :
2009-07-09 14:35:36 -04:00
self . window . get_widget ( " config-apply " ) . set_sensitive ( True )
2009-07-07 12:16:03 -04:00
def security_type_changed ( self , button , sensitive = True ) :
2009-07-09 14:35:36 -04:00
self . window . get_widget ( " config-apply " ) . set_sensitive ( True )
2009-07-07 12:16:03 -04:00
self . window . get_widget ( " security-label " ) . set_sensitive ( not button . get_active ( ) )
2009-07-09 14:35:36 -04:00
def config_security_apply ( self ) :
2009-07-07 12:16:03 -04:00
combo = self . window . get_widget ( " security-model " )
model = combo . get_model ( )
semodel = model [ combo . get_active ( ) ] [ 0 ]
if not semodel or str ( semodel ) . lower ( ) == " none " :
semodel = None
if self . window . get_widget ( " security-dynamic " ) . get_active ( ) :
setype = " dynamic "
else :
setype = " static "
selabel = self . window . get_widget ( " security-label " ) . get_text ( )
try :
self . vm . define_seclabel ( semodel , setype , selabel )
except Exception , e :
self . err . show_err ( _ ( " Error Setting Security data: %s " ) % str ( e ) ,
" " . join ( traceback . format_exc ( ) ) )
2009-07-09 14:35:44 -04:00
return False
2009-07-07 12:16:03 -04:00
# -----------------------
2008-10-02 16:17:25 -04:00
# Hardware Section Pieces
# -----------------------
2009-07-09 14:35:36 -04:00
def config_apply ( self , ignore ) :
pagetype = self . get_hw_selection ( HW_LIST_COL_TYPE )
2009-07-09 14:35:44 -04:00
ret = False
2009-07-09 14:35:36 -04:00
if pagetype is HW_LIST_TYPE_GENERAL :
2009-07-09 14:35:44 -04:00
ret = self . config_security_apply ( )
2009-07-09 14:35:36 -04:00
elif pagetype is HW_LIST_TYPE_CPU :
2009-07-09 14:35:44 -04:00
ret = self . config_vcpus_apply ( )
2009-07-09 14:35:36 -04:00
elif pagetype is HW_LIST_TYPE_MEMORY :
2009-07-09 14:35:44 -04:00
ret = self . config_memory_apply ( )
2009-07-09 14:35:36 -04:00
elif pagetype is HW_LIST_TYPE_BOOT :
2009-07-09 14:35:44 -04:00
ret = self . config_boot_options_apply ( )
else :
ret = False
if ret is not False :
self . window . get_widget ( " config-apply " ) . set_sensitive ( False )
2009-07-09 14:35:36 -04:00
2006-11-13 15:31:17 -05:00
def config_vcpus_changed ( self , src ) :
2009-07-09 14:35:36 -04:00
self . window . get_widget ( " config-apply " ) . set_sensitive ( True )
2006-07-26 18:19:33 -04:00
2009-07-09 14:35:36 -04:00
def config_vcpus_apply ( self ) :
2006-11-13 15:31:17 -05:00
vcpus = self . window . get_widget ( " config-vcpus " ) . get_adjustment ( ) . value
2009-07-09 14:35:44 -04:00
logging . info ( " Setting vcpus for %s to %s " % ( self . vm . get_name ( ) ,
str ( vcpus ) ) )
2009-07-14 21:22:18 -04:00
hotplug_err = False
try :
if self . vm . is_active ( ) :
self . vm . hotplug_vcpus ( vcpus )
except Exception , e :
logging . debug ( " VCPU hotplug failed: %s " % str ( e ) )
hotplug_err = True
# Change persistent config
try :
self . vm . define_vcpus ( vcpus )
except Exception , e :
self . err . show_err ( _ ( " Error changing vcpu value: %s " % str ( e ) ) ,
" " . join ( traceback . format_exc ( ) ) )
return False
if hotplug_err :
self . err . show_info ( _ ( " These changes will take effect after the "
" next guest reboot. " ) )
2006-07-26 18:19:33 -04:00
2009-06-16 18:04:29 -04:00
def config_get_maxmem ( self ) :
maxadj = self . window . get_widget ( " config-maxmem " ) . get_adjustment ( )
txtmax = self . window . get_widget ( " config-maxmem " ) . get_text ( )
try :
maxmem = int ( txtmax )
except :
maxmem = maxadj . value
return maxmem
def config_get_memory ( self ) :
memadj = self . window . get_widget ( " config-memory " ) . get_adjustment ( )
txtmem = self . window . get_widget ( " config-memory " ) . get_text ( )
try :
mem = int ( txtmem )
except :
mem = memadj . value
return mem
2006-11-13 15:31:17 -05:00
def config_maxmem_changed ( self , src ) :
2009-07-09 14:35:36 -04:00
self . window . get_widget ( " config-apply " ) . set_sensitive ( True )
2009-06-16 18:04:29 -04:00
def config_memory_changed ( self , src ) :
2009-07-09 14:35:36 -04:00
self . window . get_widget ( " config-apply " ) . set_sensitive ( True )
2009-06-16 18:04:29 -04:00
maxadj = self . window . get_widget ( " config-maxmem " ) . get_adjustment ( )
mem = self . config_get_memory ( )
if maxadj . value < mem :
maxadj . value = mem
maxadj . lower = mem
2006-07-26 18:19:33 -04:00
2009-07-09 14:35:36 -04:00
def config_memory_apply ( self ) :
2008-03-18 14:37:22 -04:00
self . refresh_config_memory ( )
2009-07-02 10:49:06 -04:00
hotplug_err = False
2008-03-18 14:37:22 -04:00
curmem = None
2009-06-16 18:04:29 -04:00
maxmem = self . config_get_maxmem ( )
2008-03-18 14:37:22 -04:00
if self . window . get_widget ( " config-memory " ) . get_property ( " sensitive " ) :
2009-06-16 18:04:29 -04:00
curmem = self . config_get_memory ( )
2008-03-18 14:37:22 -04:00
2009-07-02 10:49:06 -04:00
if curmem :
curmem = int ( curmem ) * 1024
if maxmem :
maxmem = int ( maxmem ) * 1024
2008-03-18 14:37:22 -04:00
2009-07-02 10:49:06 -04:00
try :
if self . vm . is_active ( ) :
self . vm . hotplug_both_mem ( curmem , maxmem )
except Exception , e :
logging . debug ( " Memory hotplug failed: %s " % str ( e ) )
hotplug_err = True
2008-03-18 14:37:22 -04:00
2009-07-14 21:22:18 -04:00
# Change persistent config
2009-07-02 10:49:06 -04:00
try :
self . vm . define_both_mem ( curmem , maxmem )
except Exception , e :
2009-06-16 18:04:29 -04:00
self . err . show_err ( _ ( " Error changing memory values: %s " % str ( e ) ) ,
2008-03-18 14:37:22 -04:00
" " . join ( traceback . format_exc ( ) ) )
2009-07-09 14:35:44 -04:00
return False
2009-07-02 10:49:06 -04:00
if hotplug_err :
self . err . show_info ( _ ( " These changes will take effect after the "
" next guest reboot. " ) )
2008-03-06 16:43:46 -05:00
def config_boot_options_changed ( self , src ) :
2009-07-09 14:35:36 -04:00
self . window . get_widget ( " config-apply " ) . set_sensitive ( True )
2008-03-06 16:43:46 -05:00
2009-07-09 14:35:36 -04:00
def config_boot_options_apply ( self ) :
2008-03-06 16:43:46 -05:00
boot = self . window . get_widget ( " config-boot-device " )
auto = self . window . get_widget ( " config-autostart " )
if auto . get_property ( " sensitive " ) :
try :
self . vm . set_autostart ( auto . get_active ( ) )
except Exception , e :
2008-03-14 13:18:44 -04:00
self . err . show_err ( _ ( " Error changing autostart value: %s " ) % \
str ( e ) , " " . join ( traceback . format_exc ( ) ) )
2008-03-06 16:43:46 -05:00
if boot . get_property ( " sensitive " ) :
try :
self . vm . set_boot_device ( boot . get_model ( ) [ boot . get_active ( ) ] [ 2 ] )
except Exception , e :
2008-03-14 13:18:44 -04:00
self . err . show_err ( _ ( " Error changing boot device: %s " % str ( e ) ) ,
" " . join ( traceback . format_exc ( ) ) )
2009-07-09 14:35:44 -04:00
return False
2006-11-13 15:31:17 -05:00
2009-01-15 11:15:04 -05:00
def remove_xml_dev ( self , src ) :
info = self . get_hw_selection ( HW_LIST_COL_DEVICE )
if not info :
2008-07-30 20:38:09 -04:00
return
2009-01-15 11:15:04 -05:00
self . remove_device ( info [ 0 ] , info [ 1 ] )
2008-07-30 20:38:09 -04:00
2007-04-11 14:48:36 -04:00
def prepare_hw_list ( self ) :
2007-07-14 14:43:20 -04:00
hw_list_model = gtk . ListStore ( str , str , int , gtk . gdk . Pixbuf , int , gobject . TYPE_PYOBJECT )
2007-04-11 14:48:36 -04:00
self . window . get_widget ( " hw-list " ) . set_model ( hw_list_model )
hwCol = gtk . TreeViewColumn ( " Hardware " )
2009-07-09 14:35:36 -04:00
hwCol . set_spacing ( 24 )
2007-04-11 14:48:36 -04:00
hw_txt = gtk . CellRendererText ( )
2009-07-09 14:35:36 -04:00
hw_txt . set_property ( " xpad " , 2 )
2007-04-11 14:48:36 -04:00
hw_img = gtk . CellRendererPixbuf ( )
2009-07-09 14:35:36 -04:00
hw_img . set_property ( " xpad " , 4 )
2007-04-11 14:48:36 -04:00
hwCol . pack_start ( hw_txt , True )
hwCol . pack_start ( hw_img , False )
2007-07-14 14:43:20 -04:00
hwCol . add_attribute ( hw_txt , ' text ' , HW_LIST_COL_LABEL )
hwCol . add_attribute ( hw_img , ' stock-id ' , HW_LIST_COL_STOCK_ID )
hwCol . add_attribute ( hw_img , ' stock-size ' , HW_LIST_COL_STOCK_SIZE )
hwCol . add_attribute ( hw_img , ' pixbuf ' , HW_LIST_COL_PIXBUF )
2007-04-11 14:48:36 -04:00
self . window . get_widget ( " hw-list " ) . append_column ( hwCol )
2008-03-06 16:43:46 -05:00
self . prepare_boot_list ( )
2007-04-11 14:48:36 -04:00
2007-04-12 15:36:04 -04:00
self . populate_hw_list ( )
2008-03-06 16:43:46 -05:00
self . repopulate_boot_list ( )
def prepare_boot_list ( self ) :
boot_list = self . window . get_widget ( " config-boot-device " )
# model = [ display name, icon name, boot type (hd, fd, etc) ]
boot_list_model = gtk . ListStore ( str , str , str )
boot_list . set_model ( boot_list_model )
icon = gtk . CellRendererPixbuf ( )
boot_list . pack_start ( icon , False )
boot_list . add_attribute ( icon , ' stock-id ' , 1 )
text = gtk . CellRendererText ( )
boot_list . pack_start ( text , True )
boot_list . add_attribute ( text , ' text ' , 0 )
2007-04-12 15:36:04 -04:00
2007-04-11 14:48:36 -04:00
def populate_hw_list ( self ) :
hw_list_model = self . window . get_widget ( " hw-list " ) . get_model ( )
hw_list_model . clear ( )
2009-05-11 12:24:15 -04:00
hw_list_model . append ( [ _ ( " Overview " ) , None , 0 , self . pixbuf_processor ,
2009-02-09 14:55:18 -05:00
HW_LIST_TYPE_GENERAL , [ ] ] )
2009-05-11 12:24:15 -04:00
hw_list_model . append ( [ _ ( " Performance " ) , None , 0 , self . pixbuf_memory ,
2009-02-09 14:55:18 -05:00
HW_LIST_TYPE_STATS , [ ] ] )
2009-05-11 12:24:15 -04:00
hw_list_model . append ( [ _ ( " Processor " ) , None , 0 , self . pixbuf_processor , HW_LIST_TYPE_CPU , [ ] ] )
hw_list_model . append ( [ _ ( " Memory " ) , None , 0 , self . pixbuf_memory , HW_LIST_TYPE_MEMORY , [ ] ] )
hw_list_model . append ( [ _ ( " Boot Options " ) , None , 0 , self . pixbuf_memory , HW_LIST_TYPE_BOOT , [ ] ] )
2007-04-12 15:36:04 -04:00
self . repopulate_hw_list ( )
2007-04-11 14:48:36 -04:00
2007-04-12 15:36:04 -04:00
def repopulate_hw_list ( self ) :
2007-04-12 18:54:33 -04:00
hw_list = self . window . get_widget ( " hw-list " )
hw_list_model = hw_list . get_model ( )
2007-04-11 14:48:36 -04:00
2007-04-12 18:54:33 -04:00
currentDisks = { }
2009-01-15 11:17:30 -05:00
currentNICs = { }
currentInputs = { }
currentGraphics = { }
currentSounds = { }
currentChars = { }
2009-01-22 17:00:38 -05:00
currentHostdevs = { }
2009-07-09 14:35:55 -04:00
currentVids = { }
2009-01-15 11:17:30 -05:00
def update_hwlist ( hwtype , info ) :
""" Return (true if we updated an entry,
index to insert at if we didn ' t update an entry)
"""
2007-04-12 15:36:04 -04:00
insertAt = 0
for row in hw_list_model :
2009-01-15 11:17:30 -05:00
if row [ HW_LIST_COL_TYPE ] == hwtype and \
row [ HW_LIST_COL_DEVICE ] [ 2 ] == info [ 2 ] :
row [ HW_LIST_COL_DEVICE ] = info
return ( False , insertAt )
2007-09-25 20:05:45 -04:00
2009-01-15 11:17:30 -05:00
if row [ HW_LIST_COL_TYPE ] < = hwtype :
insertAt + = 1
return ( True , insertAt )
# Populate list of disks
for diskinfo in self . vm . get_disk_devices ( ) :
currentDisks [ diskinfo [ 2 ] ] = 1
missing , insertAt = update_hwlist ( HW_LIST_TYPE_DISK ,
diskinfo )
2007-04-12 15:36:04 -04:00
# Add in row
if missing :
2007-07-14 14:43:20 -04:00
stock = gtk . STOCK_HARDDISK
2009-01-15 11:01:24 -05:00
if diskinfo [ 4 ] == " cdrom " :
2007-07-14 14:43:20 -04:00
stock = gtk . STOCK_CDROM
2009-01-15 11:01:24 -05:00
elif diskinfo [ 4 ] == " floppy " :
2007-07-14 14:43:20 -04:00
stock = gtk . STOCK_FLOPPY
2009-01-15 11:01:24 -05:00
hw_list_model . insert ( insertAt , [ " Disk %s " % diskinfo [ 2 ] , stock , gtk . ICON_SIZE_LARGE_TOOLBAR , None , HW_LIST_TYPE_DISK , diskinfo ] )
2007-04-12 15:36:04 -04:00
# Populate list of NICs
2009-01-15 11:23:23 -05:00
for netinfo in self . vm . get_network_devices ( ) :
2009-01-15 11:01:24 -05:00
currentNICs [ netinfo [ 2 ] ] = 1
2009-01-15 11:17:30 -05:00
missing , insertAt = update_hwlist ( HW_LIST_TYPE_NIC ,
netinfo )
2007-04-12 15:36:04 -04:00
# Add in row
if missing :
2009-01-15 11:01:24 -05:00
hw_list_model . insert ( insertAt , [ " NIC %s " % netinfo [ 2 ] [ - 9 : ] , gtk . STOCK_NETWORK , gtk . ICON_SIZE_LARGE_TOOLBAR , None , HW_LIST_TYPE_NIC , netinfo ] )
2007-04-12 15:36:04 -04:00
2007-09-25 20:05:45 -04:00
# Populate list of input devices
2009-01-15 11:23:23 -05:00
for inputinfo in self . vm . get_input_devices ( ) :
2009-01-15 11:01:24 -05:00
currentInputs [ inputinfo [ 2 ] ] = 1
2009-01-15 11:17:30 -05:00
missing , insertAt = update_hwlist ( HW_LIST_TYPE_INPUT ,
inputinfo )
2007-09-25 20:05:45 -04:00
# Add in row
if missing :
2009-01-15 11:01:24 -05:00
if inputinfo [ 4 ] == " tablet " :
2009-01-15 11:23:23 -05:00
label = _ ( " Tablet " )
2009-01-15 11:01:24 -05:00
elif inputinfo [ 4 ] == " mouse " :
2009-01-15 11:23:23 -05:00
label = _ ( " Mouse " )
2007-09-25 20:05:45 -04:00
else :
2009-01-15 11:23:23 -05:00
label = _ ( " Input " )
hw_list_model . insert ( insertAt , [ label , gtk . STOCK_INDEX , gtk . ICON_SIZE_LARGE_TOOLBAR , None , HW_LIST_TYPE_INPUT , inputinfo ] )
2007-09-25 20:05:45 -04:00
2007-09-26 19:39:11 -04:00
# Populate list of graphics devices
2009-01-15 11:23:23 -05:00
for gfxinfo in self . vm . get_graphics_devices ( ) :
2009-01-15 11:01:24 -05:00
currentGraphics [ gfxinfo [ 2 ] ] = 1
2009-01-15 11:17:30 -05:00
missing , insertAt = update_hwlist ( HW_LIST_TYPE_GRAPHICS ,
gfxinfo )
2007-09-26 19:39:11 -04:00
# Add in row
if missing :
2009-07-14 19:47:18 -04:00
hw_list_model . insert ( insertAt , [ _ ( " Display %s " ) % gfxinfo [ 1 ] . upper ( ) , gtk . STOCK_SELECT_COLOR , gtk . ICON_SIZE_LARGE_TOOLBAR , None , HW_LIST_TYPE_GRAPHICS , gfxinfo ] )
2007-09-26 19:39:11 -04:00
2008-07-30 19:52:39 -04:00
# Populate list of sound devices
2009-01-15 11:23:23 -05:00
for soundinfo in self . vm . get_sound_devices ( ) :
2009-01-15 11:01:24 -05:00
currentSounds [ soundinfo [ 2 ] ] = 1
2009-01-15 11:17:30 -05:00
missing , insertAt = update_hwlist ( HW_LIST_TYPE_SOUND ,
soundinfo )
2008-07-30 19:52:39 -04:00
# Add in row
if missing :
2009-01-15 11:01:24 -05:00
hw_list_model . insert ( insertAt , [ _ ( " Sound: %s " % soundinfo [ 2 ] ) , gtk . STOCK_MEDIA_PLAY , gtk . ICON_SIZE_LARGE_TOOLBAR , None , HW_LIST_TYPE_SOUND , soundinfo ] )
2008-07-30 19:52:39 -04:00
2008-07-30 20:38:09 -04:00
# Populate list of char devices
2009-01-15 11:23:23 -05:00
for charinfo in self . vm . get_char_devices ( ) :
2009-01-15 11:01:24 -05:00
currentChars [ charinfo [ 2 ] ] = 1
2009-01-15 11:17:30 -05:00
missing , insertAt = update_hwlist ( HW_LIST_TYPE_CHAR ,
charinfo )
2008-07-30 20:38:09 -04:00
# Add in row
if missing :
2009-01-15 11:23:23 -05:00
l = charinfo [ 0 ] . capitalize ( )
if charinfo [ 0 ] != " console " :
2009-01-15 11:01:24 -05:00
l + = " %s " % charinfo [ 3 ] # Don't show port for console
2009-01-15 11:23:23 -05:00
hw_list_model . insert ( insertAt , [ l , gtk . STOCK_CONNECT , gtk . ICON_SIZE_LARGE_TOOLBAR , None , HW_LIST_TYPE_CHAR , charinfo ] )
2008-07-30 20:38:09 -04:00
2009-01-22 17:00:38 -05:00
# Populate host devices
for hostdevinfo in self . vm . get_hostdev_devices ( ) :
currentHostdevs [ hostdevinfo [ 2 ] ] = 1
missing , insertAt = update_hwlist ( HW_LIST_TYPE_HOSTDEV ,
hostdevinfo )
if missing :
hw_list_model . insert ( insertAt , [ hostdevinfo [ 2 ] , None , gtk . ICON_SIZE_LARGE_TOOLBAR , None , HW_LIST_TYPE_HOSTDEV , hostdevinfo ] )
2009-07-09 14:35:55 -04:00
# Populate video devices
for vidinfo in self . vm . get_video_devices ( ) :
currentVids [ vidinfo [ 2 ] ] = 1
missing , insertAt = update_hwlist ( HW_LIST_TYPE_VIDEO ,
vidinfo )
if missing :
hw_list_model . insert ( insertAt ,
[ _ ( " Video " ) , gtk . STOCK_SELECT_COLOR ,
gtk . ICON_SIZE_LARGE_TOOLBAR ,
None , HW_LIST_TYPE_VIDEO , vidinfo ] )
2008-07-30 20:38:09 -04:00
2007-04-12 18:54:33 -04:00
# Now remove any no longer current devs
devs = range ( len ( hw_list_model ) )
devs . reverse ( )
for i in devs :
2008-11-18 17:01:22 -05:00
_iter = hw_list_model . iter_nth_child ( None , i )
2007-04-12 18:54:33 -04:00
row = hw_list_model [ i ]
removeIt = False
2009-07-09 14:35:55 -04:00
mapping = {
HW_LIST_TYPE_DISK : currentDisks ,
HW_LIST_TYPE_NIC : currentNICs ,
HW_LIST_TYPE_INPUT : currentInputs ,
HW_LIST_TYPE_GRAPHICS : currentGraphics ,
HW_LIST_TYPE_SOUND : currentSounds ,
HW_LIST_TYPE_CHAR : currentChars ,
HW_LIST_TYPE_HOSTDEV : currentHostdevs ,
HW_LIST_TYPE_VIDEO : currentVids ,
}
hwtype = row [ HW_LIST_COL_TYPE ]
if ( mapping . has_key ( hwtype ) and not
mapping [ hwtype ] . has_key ( row [ HW_LIST_COL_DEVICE ] [ 2 ] ) ) :
2009-01-22 17:00:38 -05:00
removeIt = True
2007-04-12 18:54:33 -04:00
if removeIt :
# Re-select the first row, if we're viewing the device
# we're about to remove
( selModel , selIter ) = hw_list . get_selection ( ) . get_selected ( )
2007-07-14 14:43:20 -04:00
selType = selModel . get_value ( selIter , HW_LIST_COL_TYPE )
selInfo = selModel . get_value ( selIter , HW_LIST_COL_DEVICE )
2009-07-09 14:35:55 -04:00
if ( selType == row [ HW_LIST_COL_TYPE ] and
selInfo [ 2 ] == row [ HW_LIST_COL_DEVICE ] [ 2 ] ) :
2007-04-12 18:54:33 -04:00
hw_list . get_selection ( ) . select_iter ( selModel . iter_nth_child ( None , 0 ) )
# Now actually remove it
2008-11-18 17:01:22 -05:00
hw_list_model . remove ( _iter )
2007-04-12 18:54:33 -04:00
2008-03-06 16:43:46 -05:00
def repopulate_boot_list ( self ) :
hw_list_model = self . window . get_widget ( " hw-list " ) . get_model ( )
boot_combo = self . window . get_widget ( " config-boot-device " )
boot_model = boot_combo . get_model ( )
boot_model . clear ( )
found_dev = { }
for row in hw_list_model :
if row [ 4 ] == HW_LIST_TYPE_DISK :
2009-01-15 11:15:04 -05:00
diskinfo = row [ 5 ]
if diskinfo [ 4 ] == virtinst . VirtualDisk . DEVICE_DISK and not \
2008-03-06 16:43:46 -05:00
found_dev . get ( virtinst . VirtualDisk . DEVICE_DISK , False ) :
boot_model . append ( [ " Hard Disk " , gtk . STOCK_HARDDISK , " hd " ] )
found_dev [ virtinst . VirtualDisk . DEVICE_DISK ] = True
2009-01-15 11:15:04 -05:00
elif diskinfo [ 4 ] == virtinst . VirtualDisk . DEVICE_CDROM and not \
2008-03-06 16:43:46 -05:00
found_dev . get ( virtinst . VirtualDisk . DEVICE_CDROM , False ) :
boot_model . append ( [ " CDROM " , gtk . STOCK_CDROM , " cdrom " ] )
found_dev [ virtinst . VirtualDisk . DEVICE_CDROM ] = True
2009-01-15 11:15:04 -05:00
elif diskinfo [ 4 ] == virtinst . VirtualDisk . DEVICE_FLOPPY and not \
2008-03-06 16:43:46 -05:00
found_dev . get ( virtinst . VirtualDisk . DEVICE_FLOPPY , False ) :
boot_model . append ( [ " Floppy " , gtk . STOCK_FLOPPY , " fd " ] )
found_dev [ virtinst . VirtualDisk . DEVICE_FLOPPY ] = True
elif row [ 4 ] == HW_LIST_TYPE_NIC and not \
found_dev . get ( HW_LIST_TYPE_NIC , False ) :
boot_model . append ( [ " Network (PXE) " , gtk . STOCK_NETWORK , " network " ] )
found_dev [ HW_LIST_TYPE_NIC ] = True
if len ( boot_model ) < = 0 :
boot_model . append ( [ _ ( " No Boot Device " ) , None , None ] )
boot_combo . set_model ( boot_model )
2007-04-12 15:36:04 -04:00
def add_hardware ( self , src ) :
if self . addhw is None :
self . addhw = vmmAddHardware ( self . config , self . vm )
self . addhw . show ( )
2007-04-11 14:48:36 -04:00
2007-09-21 16:28:31 -04:00
def toggle_cdrom ( self , src ) :
2009-01-15 11:15:04 -05:00
info = self . get_hw_selection ( HW_LIST_COL_DEVICE )
if not info :
return
2007-09-21 16:28:31 -04:00
if src . get_label ( ) == gtk . STOCK_DISCONNECT :
#disconnect the cdrom
2007-11-16 17:12:37 -05:00
try :
2009-01-15 11:15:04 -05:00
self . vm . disconnect_cdrom_device ( info [ 1 ] )
2007-11-16 17:12:37 -05:00
except Exception , e :
2008-03-14 13:18:44 -04:00
self . err . show_err ( _ ( " Error Removing CDROM: %s " % str ( e ) ) ,
" " . join ( traceback . format_exc ( ) ) )
2007-11-16 17:12:37 -05:00
return
2008-08-21 16:01:15 -04:00
2007-09-21 16:28:31 -04:00
else :
# connect a new cdrom
if self . choose_cd is None :
2008-09-09 07:05:58 -04:00
self . choose_cd = vmmChooseCD ( self . config , self . window . get_widget ( " disk-target-device " ) . get_text ( ) , self . vm . get_connection ( ) )
2007-11-28 16:26:08 -05:00
self . choose_cd . connect ( " cdrom-chosen " , self . connect_cdrom )
2007-09-21 16:28:31 -04:00
else :
2009-01-15 11:15:04 -05:00
self . choose_cd . dev_id_info = info [ 1 ]
2007-09-21 16:28:31 -04:00
self . choose_cd . show ( )
2009-01-15 11:15:04 -05:00
def connect_cdrom ( self , src , typ , source , dev_id_info ) :
2007-11-28 16:26:08 -05:00
try :
2009-01-15 11:15:04 -05:00
self . vm . connect_cdrom_device ( typ , source , dev_id_info )
2008-08-21 16:01:15 -04:00
except Exception , e :
2008-03-14 13:18:44 -04:00
self . err . show_err ( _ ( " Error Connecting CDROM: %s " % str ( e ) ) ,
" " . join ( traceback . format_exc ( ) ) )
2006-08-29 15:52:19 -04:00
2009-01-15 11:15:04 -05:00
def remove_device ( self , dev_type , dev_id_info ) :
logging . debug ( " Removing device: %s %s " % ( dev_type , dev_id_info ) )
2008-08-21 16:01:15 -04:00
detach_err = False
2009-01-15 11:15:04 -05:00
devxml = self . vm . get_device_xml ( dev_type , dev_id_info )
2008-08-21 16:01:15 -04:00
try :
2009-01-15 11:15:04 -05:00
if self . vm . is_active ( ) :
self . vm . detach_device ( devxml )
return
2008-08-21 16:01:15 -04:00
except Exception , e :
logging . debug ( " Device could not be hotUNplugged: %s " % str ( e ) )
detach_err = True
if detach_err :
if not self . err . yes_no ( _ ( " Are you sure you want to remove this "
" device? " ) ,
_ ( " This device could not be removed from "
" the running machine. Would you like to "
" remove the device after the next VM "
" shutdown? \n \n "
" Warning: this will overwrite any "
" other changes that require a VM "
" reboot. " ) ) :
return
2007-11-16 17:12:37 -05:00
try :
2009-01-15 11:15:04 -05:00
self . vm . remove_device ( dev_type , dev_id_info )
2007-11-16 17:12:37 -05:00
except Exception , e :
2008-03-14 13:18:44 -04:00
self . err . show_err ( _ ( " Error Removing Device: %s " % str ( e ) ) ,
" " . join ( traceback . format_exc ( ) ) )
2006-06-14 16:20:06 -04:00
gobject . type_register ( vmmDetails )