2006-06-28 23:50:17 +04:00
#
# Copyright (C) 2006 Red Hat, Inc.
# Copyright (C) 2006 Daniel P. Berrange <berrange@redhat.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
2007-11-20 19:12:20 +03:00
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA.
2006-06-28 23:50:17 +04:00
#
2007-11-20 19:12:20 +03:00
2006-06-14 18:59:40 +04:00
import gobject
2006-06-14 22:36:26 +04:00
import gtk
2006-06-15 00:20:06 +04:00
import sys
2006-07-17 21:08:58 +04:00
import libvirt
2006-09-26 02:41:47 +04:00
import logging
2007-03-08 22:07:00 +03:00
import gnome
2007-03-22 18:11:05 +03:00
import traceback
2006-06-14 18:59:40 +04:00
from virtManager . about import vmmAbout
from virtManager . connect import vmmConnect
from virtManager . connection import vmmConnection
from virtManager . preferences import vmmPreferences
2006-06-15 00:20:06 +04:00
from virtManager . manager import vmmManager
from virtManager . details import vmmDetails
2006-07-24 21:50:11 +04:00
from virtManager . asyncjob import vmmAsyncJob
2006-08-09 01:02:15 +04:00
from virtManager . create import vmmCreate
2007-03-28 03:52:00 +04:00
from virtManager . host import vmmHost
2007-11-27 19:31:30 +03:00
from virtManager . error import vmmErrorDialog
2006-06-14 18:59:40 +04:00
2007-09-10 06:57:24 +04:00
class vmmEngine ( gobject . GObject ) :
__gsignals__ = {
" connection-added " : ( gobject . SIGNAL_RUN_FIRST , gobject . TYPE_NONE ,
[ object ] ) ,
" connection-removed " : ( gobject . SIGNAL_RUN_FIRST , gobject . TYPE_NONE ,
[ object ] )
}
2006-06-14 18:59:40 +04:00
def __init__ ( self , config ) :
2007-09-10 06:57:24 +04:00
self . __gobject_init__ ( )
2006-06-15 00:20:06 +04:00
self . windowConnect = None
2006-06-14 18:59:40 +04:00
self . windowPreferences = None
self . windowAbout = None
2006-08-09 01:02:15 +04:00
self . windowCreate = None
2007-08-10 00:19:41 +04:00
self . windowManager = None
2006-06-14 18:59:40 +04:00
self . connections = { }
2008-03-14 20:18:44 +03:00
self . err = vmmErrorDialog ( None ,
0 , gtk . MESSAGE_ERROR , gtk . BUTTONS_CLOSE ,
_ ( " Unexpected Error " ) ,
_ ( " An unexpected error occurred " ) )
2006-06-14 18:59:40 +04:00
self . timer = None
self . last_timeout = 0
2008-06-13 20:12:37 +04:00
# Counter keeping track of how many manager and details windows
# are open. When it is decremented to 0, close the app
self . windows = 0
2007-11-27 19:31:30 +03:00
self . _save_callback_info = [ ]
2006-06-14 18:59:40 +04:00
self . config = config
self . config . on_stats_update_interval_changed ( self . reschedule_timer )
self . schedule_timer ( )
2007-09-10 06:57:24 +04:00
self . load_stored_uris ( )
2006-06-14 18:59:40 +04:00
self . tick ( )
2007-08-29 01:57:25 +04:00
def load_stored_uris ( self ) :
uris = self . config . get_connections ( )
if uris != None :
logging . debug ( " About to connect to uris %s " % uris )
for uri in uris :
2007-09-10 06:57:24 +04:00
self . add_connection ( uri )
2007-08-29 01:57:25 +04:00
2008-03-24 18:39:19 +03:00
def autostart_connections ( self ) :
for uri in self . connections :
conn = self . connections [ uri ] [ " connection " ]
if conn . get_autoconnect ( ) :
self . connect_to_uri ( uri )
2008-06-11 23:24:32 +04:00
def connect_to_uri ( self , uri , readOnly = None , autoconnect = False ) :
return self . _connect_to_uri ( None , uri , readOnly , autoconnect )
2006-06-14 22:36:26 +04:00
2008-06-11 23:24:32 +04:00
def _connect_to_uri ( self , connect , uri , readOnly , autoconnect ) :
2006-06-27 22:16:13 +04:00
self . windowConnect = None
2006-06-27 18:08:55 +04:00
try :
2008-06-11 23:24:32 +04:00
conn = self . get_connection ( uri , readOnly , autoconnect )
2007-08-10 00:19:41 +04:00
self . show_manager ( )
2007-09-11 05:14:50 +04:00
conn . open ( )
2007-08-17 00:38:24 +04:00
return conn
2006-06-27 18:08:55 +04:00
except :
2007-08-17 00:38:24 +04:00
return None
2006-06-14 22:36:26 +04:00
2006-07-20 19:38:32 +04:00
def _connect_cancelled ( self , connect ) :
2006-06-27 22:16:13 +04:00
self . windowConnect = None
2006-06-27 18:08:55 +04:00
if len ( self . connections . keys ( ) ) == 0 :
2008-06-13 22:40:26 +04:00
self . exit_app ( )
2006-06-14 22:36:26 +04:00
2006-06-15 00:56:49 +04:00
def _do_vm_removed ( self , connection , hvuri , vmuuid ) :
if self . connections [ hvuri ] [ " windowDetails " ] . has_key ( vmuuid ) :
2006-07-13 21:35:40 +04:00
self . connections [ hvuri ] [ " windowDetails " ] [ vmuuid ] . close ( )
2006-06-15 00:56:49 +04:00
del self . connections [ hvuri ] [ " windowDetails " ] [ vmuuid ]
2007-09-27 05:04:02 +04:00
def _do_connection_changed ( self , connection ) :
2008-09-18 18:33:53 +04:00
if connection . get_state ( ) == connection . STATE_ACTIVE or \
connection . get_state ( ) == connection . STATE_CONNECTING :
2007-09-27 05:04:02 +04:00
return
hvuri = connection . get_uri ( )
for vmuuid in self . connections [ hvuri ] [ " windowDetails " ] . keys ( ) :
self . connections [ hvuri ] [ " windowDetails " ] [ vmuuid ] . close ( )
del self . connections [ hvuri ] [ " windowDetails " ] [ vmuuid ]
if self . connections [ hvuri ] [ " windowHost " ] is not None :
self . connections [ hvuri ] [ " windowHost " ] . close ( )
self . connections [ hvuri ] [ " windowHost " ] = None
if self . connections [ hvuri ] [ " windowCreate " ] is not None :
self . connections [ hvuri ] [ " windowCreate " ] . close ( )
self . connections [ hvuri ] [ " windowCreate " ] = None
2006-06-14 18:59:40 +04:00
def reschedule_timer ( self , ignore1 , ignore2 , ignore3 , ignore4 ) :
self . schedule_timer ( )
def schedule_timer ( self ) :
interval = self . get_config ( ) . get_stats_update_interval ( ) * 1000
if self . timer != None :
gobject . source_remove ( self . timer )
self . timer = None
self . timer = gobject . timeout_add ( interval , self . tick )
def tick ( self ) :
2007-03-10 00:22:43 +03:00
gtk . gdk . threads_enter ( )
try :
2007-03-13 18:48:19 +03:00
return self . _tick ( )
2007-03-10 00:22:43 +03:00
finally :
gtk . gdk . threads_leave ( )
def _tick ( self ) :
2006-06-14 18:59:40 +04:00
for uri in self . connections . keys ( ) :
try :
2006-06-15 00:20:06 +04:00
self . connections [ uri ] [ " connection " ] . tick ( )
2006-07-11 23:36:54 +04:00
except KeyboardInterrupt :
raise KeyboardInterrupt
2006-06-14 18:59:40 +04:00
except :
2007-03-23 03:59:10 +03:00
logging . error ( ( " Could not refresh connection %s \n " % ( uri ) ) + str ( sys . exc_info ( ) [ 0 ] ) + \
2007-03-22 18:11:05 +03:00
" " + str ( sys . exc_info ( ) [ 1 ] ) + " \n " + \
traceback . format_exc ( sys . exc_info ( ) [ 2 ] ) )
2006-06-14 18:59:40 +04:00
return 1
def change_timer_interval ( self , ignore1 , ignore2 , ignore3 , ignore4 ) :
gobject . source_remove ( self . timer )
self . schedule_timer ( )
def get_config ( self ) :
return self . config
2006-06-15 00:20:06 +04:00
def _do_show_about ( self , src ) :
self . show_about ( )
def _do_show_preferences ( self , src ) :
self . show_preferences ( )
2007-03-28 03:52:00 +04:00
def _do_show_host ( self , src , uri ) :
self . show_host ( uri )
2006-06-15 00:20:06 +04:00
def _do_show_connect ( self , src ) :
self . show_connect ( )
2007-08-15 00:28:36 +04:00
def _do_connect ( self , src , uri ) :
self . connect_to_uri ( uri )
2006-06-15 00:20:06 +04:00
def _do_show_details ( self , src , uri , uuid ) :
self . show_details ( uri , uuid )
2007-08-14 01:13:39 +04:00
def _do_show_create ( self , src , uri ) :
self . show_create ( uri )
2007-03-08 22:07:00 +03:00
def _do_show_help ( self , src , index ) :
self . show_help ( index )
2006-06-15 00:20:06 +04:00
def _do_show_console ( self , src , uri , uuid ) :
self . show_console ( uri , uuid )
2008-06-13 22:40:26 +04:00
def _do_show_manager ( self , src ) :
self . show_manager ( )
2008-03-14 00:06:40 +03:00
def _do_refresh_console ( self , src , uri , uuid ) :
self . refresh_console ( uri , uuid )
2006-07-17 21:08:58 +04:00
def _do_save_domain ( self , src , uri , uuid ) :
2006-07-19 02:14:44 +04:00
self . save_domain ( src , uri , uuid )
2006-11-15 20:27:36 +03:00
def _do_destroy_domain ( self , src , uri , uuid ) :
self . destroy_domain ( src , uri , uuid )
2007-11-27 19:31:30 +03:00
def _do_suspend_domain ( self , src , uri , uuid ) :
self . suspend_domain ( src , uri , uuid )
def _do_resume_domain ( self , src , uri , uuid ) :
self . resume_domain ( src , uri , uuid )
def _do_run_domain ( self , src , uri , uuid ) :
self . run_domain ( src , uri , uuid )
def _do_shutdown_domain ( self , src , uri , uuid ) :
self . shutdown_domain ( src , uri , uuid )
2008-04-08 22:30:47 +04:00
def _do_reboot_domain ( self , src , uri , uuid ) :
self . reboot_domain ( src , uri , uuid )
2008-10-30 23:38:13 +03:00
def _do_migrate_domain ( self , src , uri , uuid , desturi ) :
self . migrate_domain ( uri , uuid , desturi )
2008-06-13 22:40:26 +04:00
def _do_exit_app ( self , src ) :
self . exit_app ( )
2006-06-15 00:20:06 +04:00
2006-06-14 18:59:40 +04:00
def show_about ( self ) :
if self . windowAbout == None :
self . windowAbout = vmmAbout ( self . get_config ( ) )
self . windowAbout . show ( )
2007-03-08 22:07:00 +03:00
def show_help ( self , index ) :
try :
2008-04-22 19:25:00 +04:00
logging . debug ( " Showing help for %s " % index )
2007-03-08 22:07:00 +03:00
gnome . help_display ( self . config . get_appname ( ) , index )
except gobject . GError , e :
2007-03-16 23:27:50 +03:00
logging . error ( ( " Unable to display documentation: \n %s " ) % e )
2007-03-08 22:07:00 +03:00
2006-06-14 18:59:40 +04:00
def show_preferences ( self ) :
if self . windowPreferences == None :
self . windowPreferences = vmmPreferences ( self . get_config ( ) )
2007-03-20 01:12:40 +03:00
self . windowPreferences . connect ( " action-show-help " , self . _do_show_help )
2006-06-14 18:59:40 +04:00
self . windowPreferences . show ( )
2007-03-28 03:52:00 +04:00
def show_host ( self , uri ) :
con = self . get_connection ( uri )
if self . connections [ uri ] [ " windowHost " ] == None :
manager = vmmHost ( self . get_config ( ) , con )
2008-04-22 18:40:59 +04:00
manager . connect ( " action-show-help " , self . _do_show_help )
2007-03-28 03:52:00 +04:00
self . connections [ uri ] [ " windowHost " ] = manager
self . connections [ uri ] [ " windowHost " ] . show ( )
2006-06-15 00:20:06 +04:00
def show_connect ( self ) :
if self . windowConnect == None :
self . windowConnect = vmmConnect ( self . get_config ( ) , self )
self . windowConnect . connect ( " completed " , self . _connect_to_uri )
2006-06-27 19:17:46 +04:00
self . windowConnect . connect ( " cancelled " , self . _connect_cancelled )
2006-06-15 00:20:06 +04:00
self . windowConnect . show ( )
2006-06-14 18:59:40 +04:00
def show_console ( self , uri , uuid ) :
2008-04-08 22:30:47 +04:00
win = self . show_details ( uri , uuid )
win . activate_console_page ( )
2006-08-11 00:47:14 +04:00
2008-03-14 00:06:40 +03:00
def refresh_console ( self , uri , uuid ) :
if not ( self . connections [ uri ] [ " windowConsole " ] . has_key ( uuid ) ) :
return
console = self . connections [ uri ] [ " windowConsole " ] [ uuid ]
if not ( console . is_visible ( ) ) :
return
console . show ( )
2006-07-14 01:44:49 +04:00
def show_details_performance ( self , uri , uuid ) :
win = self . show_details ( uri , uuid )
win . activate_performance_page ( )
def show_details_config ( self , uri , uuid ) :
win = self . show_details ( uri , uuid )
win . activate_config_page ( )
2007-03-28 03:52:00 +04:00
2006-06-14 18:59:40 +04:00
def show_details ( self , uri , uuid ) :
con = self . get_connection ( uri )
2006-06-15 00:20:06 +04:00
if not ( self . connections [ uri ] [ " windowDetails " ] . has_key ( uuid ) ) :
2008-03-14 20:18:44 +03:00
try :
2008-06-13 20:12:37 +04:00
details = vmmDetails ( self . get_config ( ) , con . get_vm ( uuid ) , self )
2008-03-14 20:18:44 +03:00
details . connect ( " action-save-domain " , self . _do_save_domain )
details . connect ( " action-destroy-domain " , self . _do_destroy_domain )
details . connect ( " action-show-help " , self . _do_show_help )
details . connect ( " action-suspend-domain " , self . _do_suspend_domain )
details . connect ( " action-resume-domain " , self . _do_resume_domain )
details . connect ( " action-run-domain " , self . _do_run_domain )
details . connect ( " action-shutdown-domain " , self . _do_shutdown_domain )
2008-04-08 22:30:47 +04:00
details . connect ( " action-reboot-domain " , self . _do_reboot_domain )
2008-06-13 22:40:26 +04:00
details . connect ( " action-exit-app " , self . _do_exit_app )
details . connect ( " action-view-manager " , self . _do_show_manager )
2008-10-30 23:38:13 +03:00
details . connect ( " action-migrate-domain " , self . _do_migrate_domain )
2008-07-25 00:39:09 +04:00
2008-03-14 20:18:44 +03:00
except Exception , e :
self . err . show_err ( _ ( " Error bringing up domain details: %s " ) % str ( e ) ,
" " . join ( traceback . format_exc ( ) ) )
2006-06-15 00:20:06 +04:00
self . connections [ uri ] [ " windowDetails " ] [ uuid ] = details
self . connections [ uri ] [ " windowDetails " ] [ uuid ] . show ( )
2006-07-14 01:44:49 +04:00
return self . connections [ uri ] [ " windowDetails " ] [ uuid ]
2006-06-14 18:59:40 +04:00
2007-08-10 00:19:41 +04:00
def get_manager ( self ) :
if self . windowManager == None :
2007-09-10 06:57:24 +04:00
self . windowManager = vmmManager ( self . get_config ( ) , self )
2007-11-27 19:31:30 +03:00
self . windowManager . connect ( " action-suspend-domain " , self . _do_suspend_domain )
self . windowManager . connect ( " action-resume-domain " , self . _do_resume_domain )
self . windowManager . connect ( " action-run-domain " , self . _do_run_domain )
self . windowManager . connect ( " action-shutdown-domain " , self . _do_shutdown_domain )
2008-04-08 22:30:47 +04:00
self . windowManager . connect ( " action-reboot-domain " , self . _do_reboot_domain )
self . windowManager . connect ( " action-destroy-domain " , self . _do_destroy_domain )
2008-10-30 23:38:13 +03:00
self . windowManager . connect ( " action-migrate-domain " , self . _do_migrate_domain )
2007-08-10 00:19:41 +04:00
self . windowManager . connect ( " action-show-console " , self . _do_show_console )
self . windowManager . connect ( " action-show-details " , self . _do_show_details )
self . windowManager . connect ( " action-show-preferences " , self . _do_show_preferences )
self . windowManager . connect ( " action-show-create " , self . _do_show_create )
self . windowManager . connect ( " action-show-help " , self . _do_show_help )
self . windowManager . connect ( " action-show-about " , self . _do_show_about )
self . windowManager . connect ( " action-show-host " , self . _do_show_host )
self . windowManager . connect ( " action-show-connect " , self . _do_show_connect )
2007-08-15 00:28:36 +04:00
self . windowManager . connect ( " action-connect " , self . _do_connect )
2008-03-14 00:06:40 +03:00
self . windowManager . connect ( " action-refresh-console " , self . _do_refresh_console )
2008-06-13 22:40:26 +04:00
self . windowManager . connect ( " action-exit-app " , self . _do_exit_app )
2007-08-10 00:19:41 +04:00
return self . windowManager
def show_manager ( self ) :
self . get_manager ( ) . show ( )
2008-06-13 20:12:37 +04:00
def increment_window_counter ( self ) :
self . windows + = 1
logging . debug ( " window counter incremented to %s " % self . windows )
def decrement_window_counter ( self ) :
self . windows - = 1
logging . debug ( " window counter decremented to %s " % self . windows )
if self . windows < = 0 :
2008-06-13 22:40:26 +04:00
self . exit_app ( )
2008-06-13 20:12:37 +04:00
2008-06-13 22:40:26 +04:00
def exit_app ( self ) :
conns = self . connections . values ( )
for conn in conns :
conn [ " connection " ] . close ( )
2008-10-30 16:25:53 +03:00
logging . debug ( " Exiting app normally. " )
2008-06-13 22:40:26 +04:00
gtk . main_quit ( )
2008-06-13 20:12:37 +04:00
2008-06-04 22:30:18 +04:00
def wait_for_open ( self , uri ) :
# Used to ensure connection fully starts before running
# ONLY CALL FROM WITHIN A THREAD
conn = self . connect_to_uri ( uri )
conn . connectThreadEvent . wait ( )
if conn . state != conn . STATE_ACTIVE :
return False
return True
2007-08-14 01:13:39 +04:00
def show_create ( self , uri ) :
2007-09-27 05:04:02 +04:00
con = self . get_connection ( uri )
if self . connections [ uri ] [ " windowCreate " ] == None :
create = vmmCreate ( self . get_config ( ) , con )
create . connect ( " action-show-console " , self . _do_show_console )
create . connect ( " action-show-help " , self . _do_show_help )
self . connections [ uri ] [ " windowCreate " ] = create
self . connections [ uri ] [ " windowCreate " ] . show ( )
2006-08-09 01:02:15 +04:00
2008-06-11 22:59:50 +04:00
def add_connection ( self , uri , readOnly = None , autoconnect = False ) :
2007-09-10 06:57:24 +04:00
conn = vmmConnection ( self . get_config ( ) , uri , readOnly )
self . connections [ uri ] = {
" connection " : conn ,
" windowHost " : None ,
2007-09-27 05:04:02 +04:00
" windowCreate " : None ,
2007-09-10 06:57:24 +04:00
" windowDetails " : { } ,
" windowConsole " : { } ,
}
self . connections [ uri ] [ " connection " ] . connect ( " vm-removed " , self . _do_vm_removed )
2007-09-27 05:04:02 +04:00
self . connections [ uri ] [ " connection " ] . connect ( " state-changed " , self . _do_connection_changed )
2007-09-10 06:57:24 +04:00
self . connections [ uri ] [ " connection " ] . tick ( )
self . emit ( " connection-added " , conn )
self . config . add_connection ( conn . get_uri ( ) )
2008-06-11 22:59:50 +04:00
if autoconnect :
conn . toggle_autoconnect ( )
2007-09-10 06:57:24 +04:00
def remove_connection ( self , uri ) :
conn = self . connections [ uri ] [ " connection " ]
conn . close ( )
self . emit ( " connection-removed " , conn )
del self . connections [ uri ]
self . config . remove_connection ( conn . get_uri ( ) )
def connect ( self , name , callback ) :
handle_id = gobject . GObject . connect ( self , name , callback )
if name == " connection-added " :
for uri in self . connections . keys ( ) :
self . emit ( " connection-added " , self . connections [ uri ] [ " connection " ] )
return handle_id
2008-06-11 23:24:32 +04:00
def get_connection ( self , uri , readOnly = None , autoconnect = False ) :
2006-06-27 22:16:13 +04:00
if not ( self . connections . has_key ( uri ) ) :
2008-06-11 23:24:32 +04:00
self . add_connection ( uri , readOnly , autoconnect )
2006-06-15 00:20:06 +04:00
2006-06-27 22:16:13 +04:00
return self . connections [ uri ] [ " connection " ]
2006-07-17 21:08:58 +04:00
2006-07-19 02:14:44 +04:00
def save_domain ( self , src , uri , uuid ) :
2006-07-17 21:08:58 +04:00
con = self . get_connection ( uri , False )
2008-01-10 00:44:10 +03:00
if con . is_remote ( ) :
2008-03-19 22:39:12 +03:00
self . err . val_err ( _ ( " Saving virtual machines over remote connections is not yet supported. " ) )
2008-01-10 00:44:10 +03:00
return
2006-07-17 21:08:58 +04:00
vm = con . get_vm ( uuid )
status = vm . status ( )
2006-07-19 18:54:39 +04:00
if status in [ libvirt . VIR_DOMAIN_SHUTDOWN ,
libvirt . VIR_DOMAIN_SHUTOFF ,
libvirt . VIR_DOMAIN_CRASHED ,
libvirt . VIR_DOMAIN_PAUSED ] :
2006-09-26 02:22:27 +04:00
logging . warning ( " Save requested, but machine is shutdown / shutoff / paused " )
2006-07-17 21:08:58 +04:00
else :
2006-08-04 23:46:06 +04:00
self . fcdialog = gtk . FileChooserDialog ( _ ( " Save Virtual Machine " ) ,
src . window . get_widget ( " vmm-details " ) ,
gtk . FILE_CHOOSER_ACTION_SAVE ,
( gtk . STOCK_CANCEL , gtk . RESPONSE_CANCEL ,
gtk . STOCK_SAVE , gtk . RESPONSE_ACCEPT ) ,
None )
2008-05-07 18:39:15 +04:00
self . fcdialog . set_default_response ( gtk . RESPONSE_ACCEPT )
2007-04-12 19:46:51 +04:00
self . fcdialog . set_current_folder ( self . config . get_default_save_dir ( con ) )
2006-07-19 02:14:44 +04:00
self . fcdialog . set_do_overwrite_confirmation ( True )
response = self . fcdialog . run ( )
self . fcdialog . hide ( )
2006-07-18 03:37:24 +04:00
if ( response == gtk . RESPONSE_ACCEPT ) :
2006-07-20 19:16:07 +04:00
file_to_save = self . fcdialog . get_filename ( )
2007-11-27 19:31:30 +03:00
progWin = vmmAsyncJob ( self . config , self . _save_callback ,
[ vm , file_to_save ] ,
2006-08-04 23:46:06 +04:00
_ ( " Saving Virtual Machine " ) )
2006-07-20 19:16:07 +04:00
progWin . run ( )
self . fcdialog . destroy ( )
2006-11-15 20:27:36 +03:00
2007-11-27 19:31:30 +03:00
if self . _save_callback_info != [ ] :
2008-03-14 20:18:44 +03:00
self . err . show_err ( _ ( " Error saving domain: %s " % self . _save_callback_info [ 0 ] ) , self . _save_callback_info [ 1 ] )
2007-11-27 19:31:30 +03:00
self . _save_callback_info = [ ]
def _save_callback ( self , vm , file_to_save , ignore1 = None ) :
try :
vm . save ( file_to_save )
except Exception , e :
self . _save_callback_info = [ str ( e ) , \
" " . join ( traceback . format_exc ( ) ) ]
2006-11-15 20:27:36 +03:00
def destroy_domain ( self , src , uri , uuid ) :
con = self . get_connection ( uri , False )
vm = con . get_vm ( uuid )
status = vm . status ( )
if status in [ libvirt . VIR_DOMAIN_SHUTDOWN ,
libvirt . VIR_DOMAIN_SHUTOFF ] :
logging . warning ( " Destroy requested, but machine is shutdown / shutoff " )
else :
2008-05-07 19:28:37 +04:00
resp = self . err . yes_no ( text1 = _ ( " About to poweroff virtual machine %s " % vm . get_name ( ) ) , text2 = _ ( " This will immediately poweroff the VM without shutting down the OS and may cause data loss. Are you sure? " ) )
2008-03-19 22:39:12 +03:00
if resp :
2008-08-19 22:25:25 +04:00
logging . debug ( " Destroying vm ' %s ' . " % vm . get_name ( ) )
2007-11-27 19:31:30 +03:00
try :
vm . destroy ( )
except Exception , e :
2008-11-05 23:46:47 +03:00
self . err . show_err ( _ ( " Error shutting down domain: %s " % str ( e ) ) , " " . join ( traceback . format_exc ( ) ) )
2007-11-27 19:31:30 +03:00
def suspend_domain ( self , src , uri , uuid ) :
con = self . get_connection ( uri , False )
vm = con . get_vm ( uuid )
status = vm . status ( )
if status in [ libvirt . VIR_DOMAIN_SHUTDOWN , \
libvirt . VIR_DOMAIN_SHUTOFF , \
libvirt . VIR_DOMAIN_CRASHED ] :
logging . warning ( " Pause requested, but machine is shutdown / shutoff " )
elif status in [ libvirt . VIR_DOMAIN_PAUSED ] :
logging . warning ( " Pause requested, but machine is already paused " )
else :
2008-08-19 22:25:25 +04:00
logging . debug ( " Pausing vm ' %s ' . " % vm . get_name ( ) )
2007-11-27 19:31:30 +03:00
try :
vm . suspend ( )
except Exception , e :
2008-03-14 20:18:44 +03:00
self . err . show_err ( _ ( " Error pausing domain: %s " % str ( e ) ) ,
" " . join ( traceback . format_exc ( ) ) )
2007-11-27 19:31:30 +03:00
def resume_domain ( self , src , uri , uuid ) :
con = self . get_connection ( uri , False )
vm = con . get_vm ( uuid )
status = vm . status ( )
if status in [ libvirt . VIR_DOMAIN_SHUTDOWN , \
libvirt . VIR_DOMAIN_SHUTOFF , \
libvirt . VIR_DOMAIN_CRASHED ] :
logging . warning ( " Resume requested, but machine is shutdown / shutoff " )
elif status in [ libvirt . VIR_DOMAIN_PAUSED ] :
2008-08-19 22:25:25 +04:00
logging . debug ( " Unpausing vm ' %s ' . " % vm . get_name ( ) )
2007-11-27 19:31:30 +03:00
try :
vm . resume ( )
except Exception , e :
2008-03-14 20:18:44 +03:00
self . err . show_err ( _ ( " Error unpausing domain: %s " % str ( e ) ) ,
" " . join ( traceback . format_exc ( ) ) )
2007-11-27 19:31:30 +03:00
else :
logging . warning ( " Resume requested, but machine is already running " )
def run_domain ( self , src , uri , uuid ) :
con = self . get_connection ( uri , False )
vm = con . get_vm ( uuid )
status = vm . status ( )
if status != libvirt . VIR_DOMAIN_SHUTOFF :
logging . warning ( " Run requested, but domain isn ' t shutoff. " )
else :
2008-08-19 22:25:25 +04:00
logging . debug ( " Starting vm ' %s ' . " % vm . get_name ( ) )
2007-11-27 19:31:30 +03:00
try :
vm . startup ( )
except Exception , e :
2008-03-14 20:18:44 +03:00
self . err . show_err ( _ ( " Error starting domain: %s " % str ( e ) ) ,
" " . join ( traceback . format_exc ( ) ) )
2007-11-27 19:31:30 +03:00
def shutdown_domain ( self , src , uri , uuid ) :
con = self . get_connection ( uri , False )
vm = con . get_vm ( uuid )
status = vm . status ( )
if not ( status in [ libvirt . VIR_DOMAIN_SHUTDOWN , \
libvirt . VIR_DOMAIN_SHUTOFF , \
libvirt . VIR_DOMAIN_CRASHED ] ) :
2008-08-19 22:25:25 +04:00
logging . debug ( " Shutting down vm ' %s ' . " % vm . get_name ( ) )
2007-11-27 19:31:30 +03:00
try :
vm . shutdown ( )
except Exception , e :
2008-03-14 20:18:44 +03:00
self . err . show_err ( _ ( " Error shutting down domain: %s " % str ( e ) ) ,
" " . join ( traceback . format_exc ( ) ) )
2007-11-27 19:31:30 +03:00
else :
logging . warning ( " Shutdown requested, but machine is already shutting down / shutoff " )
2008-04-08 22:30:47 +04:00
def reboot_domain ( self , src , uri , uuid ) :
con = self . get_connection ( uri , False )
vm = con . get_vm ( uuid )
status = vm . status ( )
if not ( status in [ libvirt . VIR_DOMAIN_SHUTDOWN , \
libvirt . VIR_DOMAIN_SHUTOFF , \
libvirt . VIR_DOMAIN_CRASHED ] ) :
2008-08-19 22:25:25 +04:00
logging . debug ( " Rebooting vm ' %s ' . " % vm . get_name ( ) )
2008-04-08 22:30:47 +04:00
try :
vm . reboot ( )
except Exception , e :
2008-06-02 22:54:51 +04:00
self . err . show_err ( _ ( " Error shutting down domain: %s " % str ( e ) ) ,
" " . join ( traceback . format_exc ( ) ) )
2008-04-08 22:30:47 +04:00
else :
logging . warning ( " Reboot requested, but machine is already shutting down / shutoff " )
2008-10-30 23:38:13 +03:00
def migrate_domain ( self , uri , uuid , desturi ) :
conn = self . get_connection ( uri , False )
vm = conn . get_vm ( uuid )
destconn = self . get_connection ( desturi , False )
resp = self . err . yes_no ( _ ( " %s will be migrated from %s to %s , are you sure? " ) % \
( vm . get_name ( ) , conn . get_hostname ( ) , destconn . get_hostname ( ) ) )
if resp :
migrate_progress = None
try :
# show progress dialog
migrate_progress = self . get_migrate_progress ( vm . get_name ( ) , conn . get_short_hostname ( ) , destconn . get_short_hostname ( ) )
migrate_progress . show ( )
while gtk . events_pending ( ) :
gtk . main_iteration ( )
# call virDomainMigrate
vm . migrate ( destconn )
# close progress dialog
migrate_progress . destroy ( )
except Exception , e :
migrate_progress . destroy ( )
self . err . show_err ( _ ( " Error migrating domain: %s " ) % str ( e ) ,
" " . join ( traceback . format_exc ( ) ) )
self . windowManager . conn_refresh_resources ( conn )
self . windowManager . conn_refresh_resources ( destconn )
def get_migrate_progress ( self , vmname , hostname , desthostname ) :
migrate_progress = None
migrate_progress = gtk . MessageDialog ( None , \
gtk . DIALOG_DESTROY_WITH_PARENT , \
gtk . MESSAGE_INFO , \
gtk . BUTTONS_NONE , \
_ ( " %s will be migrated from %s to %s . " % \
( vmname , hostname , desthostname ) ) )
migrate_progress . set_title ( " " )
return migrate_progress
2008-10-31 16:48:21 +03:00
def populate_migrate_menu ( self , menu , migrate_func ) :
conns = self . get_available_migrate_hostnames ( )
# Clear menu
for item in menu :
menu . remove ( item )
2008-11-18 22:48:10 +03:00
for ignore , val_list in conns . items ( ) :
2008-10-31 16:48:21 +03:00
can_migrate , label , tooltip = val_list
mitem = gtk . ImageMenuItem ( label )
mitem . set_sensitive ( can_migrate )
mitem . connect ( " activate " , migrate_func )
if tooltip :
mitem . set_tooltip_text ( tooltip )
mitem . show ( )
menu . add ( mitem )
if len ( menu ) == 0 :
mitem = gtk . ImageMenuItem ( _ ( " No connections available. " ) )
mitem . show ( )
menu . add ( mitem )
2008-10-30 23:38:13 +03:00
def get_available_migrate_hostnames ( self ) :
driver = self . windowManager . current_connection ( ) . get_driver ( )
2008-10-31 16:48:21 +03:00
uri = self . windowManager . current_connection ( ) . get_uri ( )
2008-10-30 23:38:13 +03:00
available_migrate_hostnames = { }
2008-10-31 16:48:21 +03:00
# Returns list of lists of the form
# [ Can we migrate to this connection?,
# String to use as list entry,
# Tooltip reason ]
2008-10-30 23:38:13 +03:00
# 1. connected(ACTIVE, INACTIVE) host
2008-10-31 16:48:21 +03:00
for key , value in self . connections . items ( ) :
if not value . has_key ( " connection " ) :
continue
conn = value [ " connection " ]
can_migrate = False
desc = " %s ( %s ) " % ( conn . get_hostname ( ) , conn . get_driver ( ) )
reason = " "
if conn . get_driver ( ) != driver :
reason = _ ( " Connection hypervisors do not match. " )
elif conn . get_state ( ) == vmmConnection . STATE_DISCONNECTED :
reason = _ ( " Connection is disconnected. " )
elif key == uri :
reason = _ ( " Cannot migrate to same connection. " )
# Explicitly don't include this in the list
continue ;
elif conn . get_state ( ) == vmmConnection . STATE_ACTIVE :
# Assumably we can migrate to this connection
can_migrate = True
available_migrate_hostnames [ key ] = [ can_migrate , desc , reason ]
2008-10-30 23:38:13 +03:00
return available_migrate_hostnames
2008-04-08 22:30:47 +04:00
2007-09-10 06:57:24 +04:00
gobject . type_register ( vmmEngine )