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-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
2009-07-12 05:23:16 +04:00
import threading
2006-06-14 18:59:40 +04:00
from virtManager . about import vmmAbout
2009-07-01 22:59:13 +04:00
from virtManager . netdevhelper import vmmNetDevHelper
2006-06-14 18:59:40 +04:00
from virtManager . connect import vmmConnect
from virtManager . connection import vmmConnection
2009-04-04 00:06:46 +04:00
from virtManager . createmeter import vmmCreateMeter
from virtManager . domain import vmmDomain
2006-06-14 18:59:40 +04:00
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
2009-01-26 19:12:43 +03:00
import virtManager . util as util
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__ ( )
2009-07-01 22:59:13 +04:00
self . config = config
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
2009-07-12 05:23:16 +04:00
self . _tick_thread = None
self . _tick_thread_slow = False
self . _libvirt_support_threading = ( libvirt . getVersion ( ) > = 6000 )
if not self . _libvirt_support_threading :
logging . debug ( " Libvirt doesn ' t support threading, skipping. " )
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
2009-07-01 22:59:13 +04:00
self . netdevHelper = vmmNetDevHelper ( self . config )
2006-06-14 18:59:40 +04:00
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
2009-03-09 23:16:45 +03:00
if ( self . windowCreate and self . windowCreate . conn and
self . windowCreate . conn . get_uri ( ) == hvuri ) :
self . windowCreate . close ( )
2007-09-27 05:04:02 +04:00
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 ) :
2009-07-12 05:23:16 +04:00
if not self . _libvirt_support_threading :
2007-03-13 18:48:19 +03:00
return self . _tick ( )
2009-07-12 05:23:16 +04:00
if self . _tick_thread and self . _tick_thread . isAlive ( ) :
2009-07-14 17:45:23 +04:00
if not self . _tick_thread_slow :
2009-07-12 05:23:16 +04:00
logging . debug ( " Tick is slow, not running at requested rate. " )
return 1
self . _tick_thread = threading . Thread ( name = " Tick thread " ,
target = self . _tick , args = ( ) )
self . _tick_thread . daemon = False
self . _tick_thread . start ( )
return 1
2007-03-10 00:22:43 +03:00
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 :
2008-11-19 01:01:22 +03:00
raise
2006-06-14 18:59:40 +04:00
except :
2009-04-20 20:56:07 +04:00
logging . exception ( " Could not refresh connection %s . " % uri )
logging . debug ( " Closing connection since refresh failed. " )
self . connections [ uri ] [ " connection " ] . close ( )
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 ) :
2009-03-09 23:16:45 +03:00
if self . windowCreate == None :
create = vmmCreate ( self . get_config ( ) , self )
2007-09-27 05:04:02 +04:00
create . connect ( " action-show-console " , self . _do_show_console )
create . connect ( " action-show-help " , self . _do_show_help )
2009-03-09 23:16:45 +03:00
self . windowCreate = create
self . windowCreate . show ( uri )
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 ) :
2009-07-01 22:59:13 +04:00
conn = vmmConnection ( self . get_config ( ) , uri , readOnly ,
self . netdevHelper )
2007-09-10 06:57:24 +04:00
self . connections [ uri ] = {
" connection " : conn ,
" windowHost " : None ,
" 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 ( ) :
2009-03-08 22:14:00 +03:00
# FIXME: This should work with remote storage stuff
self . err . val_err ( _ ( " Saving virtual machines over remote "
" connections is not yet supported. " ) )
2008-01-10 00:44:10 +03:00
return
2009-03-08 22:14:00 +03:00
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 ] :
2009-03-08 22:14:00 +03:00
logging . warning ( " Save requested, but machine is shutdown / "
" shutoff / paused " )
return
path = util . browse_local ( src . window . get_widget ( " vmm-details " ) ,
_ ( " Save Virtual Machine " ) ,
2009-06-24 03:30:12 +04:00
self . config , self . get_connection ( uri ) ,
dialog_type = gtk . FILE_CHOOSER_ACTION_SAVE ,
browse_reason = self . config . CONFIG_DIR_SAVE )
2009-03-08 22:14:00 +03:00
2009-04-03 22:15:15 +04:00
if not path :
return
progWin = vmmAsyncJob ( self . config , self . _save_callback , [ vm , path ] ,
_ ( " Saving Virtual Machine " ) )
progWin . run ( )
error , details = progWin . get_error ( )
2009-03-08 22:14:00 +03:00
2009-04-03 22:15:15 +04:00
if error is not None :
self . err . show_err ( _ ( " Error saving domain: %s " ) % error , details )
2007-11-27 19:31:30 +03:00
2009-04-03 22:15:15 +04:00
def _save_callback ( self , vm , file_to_save , asyncjob ) :
2007-11-27 19:31:30 +03:00
try :
vm . save ( file_to_save )
except Exception , e :
2009-04-03 22:15:15 +04:00
asyncjob . set_error ( str ( e ) , " " . join ( traceback . format_exc ( ) ) )
2007-11-27 19:31:30 +03:00
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 ( ) ) )
2009-04-04 00:06:46 +04:00
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 :
2009-01-24 00:34:33 +03:00
logging . warning ( " Shut down requested, but the virtual machine is already shutting down / powered off " )
2007-11-27 19:31:30 +03:00
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 " )
2009-03-09 23:21:53 +03:00
def migrate_domain ( self , uri , uuid , desthost ) :
desturi = None
for key in self . connections . keys ( ) :
if self . get_connection ( key ) . get_hostname ( ) == desthost :
desturi = key
break
if desturi == None :
logging . debug ( " Could not find dest uri for migrate hostname: %s "
% desthost )
return
2008-10-30 23:38:13 +03:00
conn = self . get_connection ( uri , False )
vm = conn . get_vm ( uuid )
destconn = self . get_connection ( desturi , False )
2009-04-04 00:06:46 +04:00
resp = self . err . yes_no ( _ ( " Are you sure you want to migrate %s from "
" %s to %s ? " ) %
( vm . get_name ( ) , conn . get_hostname ( ) ,
destconn . get_hostname ( ) ) )
if not resp :
return
progWin = vmmAsyncJob ( self . config , self . _async_migrate , [ vm , destconn ] ,
title = _ ( " Migrating VM ' %s ' " % vm . get_name ( ) ) ,
text = ( _ ( " Migrating VM ' %s ' from %s to %s . "
" This may take awhile. " ) %
( vm . get_name ( ) , conn . get_hostname ( ) ,
destconn . get_hostname ( ) ) ) )
progWin . run ( )
error , details = progWin . get_error ( )
if error :
self . err . show_err ( error , details )
self . windowManager . conn_refresh_resources ( vm . get_connection ( ) )
self . windowManager . conn_refresh_resources ( destconn )
def _async_migrate ( self , origvm , origdconn , asyncjob ) :
errinfo = None
try :
2008-10-30 23:38:13 +03:00
try :
2009-04-04 00:06:46 +04:00
ignore = vmmCreateMeter ( asyncjob )
srcconn = util . dup_conn ( self . config , origvm . get_connection ( ) ,
return_conn_class = True )
dstconn = util . dup_conn ( self . config , origdconn ,
return_conn_class = True )
vminst = srcconn . vmm . lookupByName ( origvm . get_name ( ) )
vm = vmmDomain ( self . config , srcconn , vminst , vminst . UUID ( ) )
logging . debug ( " Migrating vm= %s from %s to %s " , vm . get_name ( ) ,
srcconn . get_uri ( ) , dstconn . get_uri ( ) )
2009-04-21 22:46:26 +04:00
vm . migrate ( dstconn )
2008-10-30 23:38:13 +03:00
except Exception , e :
2009-04-04 00:06:46 +04:00
errinfo = ( str ( e ) , ( " Unable to migrate guest: \n %s " %
" " . join ( traceback . format_exc ( ) ) ) )
finally :
if errinfo :
asyncjob . set_error ( errinfo [ 0 ] , errinfo [ 1 ] )
2008-10-30 23:38:13 +03:00
2009-03-24 00:38:25 +03:00
def populate_migrate_menu ( self , menu , migrate_func , vm ) :
conns = self . get_available_migrate_hostnames ( vm )
2008-10-31 16:48:21 +03:00
# 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 :
2009-01-26 19:12:43 +03:00
util . tooltip_wrapper ( mitem , tooltip )
2008-10-31 16:48:21 +03:00
mitem . show ( )
menu . add ( mitem )
if len ( menu ) == 0 :
mitem = gtk . ImageMenuItem ( _ ( " No connections available. " ) )
mitem . show ( )
menu . add ( mitem )
2009-03-24 00:38:25 +03:00
def get_available_migrate_hostnames ( self , vm ) :
driver = vm . get_connection ( ) . get_driver ( )
uri = vm . get_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
2008-11-19 01:01:22 +03:00
continue
2008-10-31 16:48:21 +03:00
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 )