2006-06-28 23:50:17 +04:00
#
2014-06-26 13:51:38 +04:00
# Copyright (C) 2006, 2013-2014 Red Hat, Inc.
2006-06-28 23:50:17 +04:00
# Copyright (C) 2006 Daniel P. Berrange <berrange@redhat.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
2007-11-20 19:12:20 +03:00
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA.
2006-06-28 23:50:17 +04:00
#
2007-11-20 19:12:20 +03:00
2013-02-16 23:03:30 +04:00
from gi . repository import GLib
2012-05-14 17:24:56 +04:00
from gi . repository import GObject
from gi . repository import Gtk
2009-11-16 04:54:55 +03:00
2006-09-26 02:41:47 +04:00
import logging
2013-07-13 06:10:16 +04:00
import re
2013-07-07 04:03:42 +04:00
import Queue
2009-07-12 05:23:16 +04:00
import threading
2014-04-16 18:32:52 +04:00
import traceback
2006-06-14 18:59:40 +04:00
2014-09-13 00:10:45 +04:00
from . import packageutils
from . about import vmmAbout
from . baseclass import vmmGObject
from . clone import vmmCloneVM
from . connect import vmmConnect
from . connection import vmmConnection
from . preferences import vmmPreferences
from . manager import vmmManager
from . migrate import vmmMigrateDialog
from . details import vmmDetails
from . asyncjob import vmmAsyncJob
from . create import vmmCreate
from . host import vmmHost
from . error import vmmErrorDialog
from . systray import vmmSystray
from . delete import vmmDeleteDialog
2006-06-14 18:59:40 +04:00
2011-04-11 20:54:47 +04:00
# Enable this to get a report of leaked objects on app shutdown
2013-04-17 17:09:53 +04:00
# gtk3/pygobject has issues here as of Fedora 18
2013-01-30 21:50:55 +04:00
debug_ref_leaks = False
2011-04-11 20:54:47 +04:00
2011-06-09 00:33:20 +04:00
DETAILS_PERF = 1
DETAILS_CONFIG = 2
DETAILS_CONSOLE = 3
2013-07-07 17:42:21 +04:00
( PRIO_HIGH ,
PRIO_LOW ) = range ( 1 , 3 )
2013-04-13 22:34:52 +04:00
2010-12-09 20:37:48 +03:00
class vmmEngine ( vmmGObject ) :
2012-05-14 17:24:56 +04:00
__gsignals__ = {
" conn-added " : ( GObject . SignalFlags . RUN_FIRST , None , [ object ] ) ,
" conn-removed " : ( GObject . SignalFlags . RUN_FIRST , None , [ str ] ) ,
}
2010-12-09 20:37:48 +03:00
def __init__ ( self ) :
vmmGObject . __init__ ( self )
2009-11-15 23:17:03 +03:00
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
2009-11-15 23:17:03 +03:00
self . windowMigrate = None
2011-07-23 00:43:26 +04:00
self . conns = { }
2010-11-30 22:33:21 +03:00
self . err = vmmErrorDialog ( )
2015-04-11 21:34:38 +03:00
self . err . set_find_parent_cb ( self . _find_error_parent_cb )
2006-06-14 18:59:40 +04:00
self . timer = None
self . last_timeout = 0
2009-07-28 06:30:01 +04:00
self . systray = None
2013-06-18 00:29:51 +04:00
self . delete_dialog = None
2013-04-16 03:25:54 +04:00
self . application = Gtk . Application (
application_id = " com.redhat.virt-manager " ,
flags = 0 )
self . application . connect ( " activate " , self . _activate )
self . _appwindow = Gtk . Window ( )
2009-07-28 06:30:01 +04:00
2013-07-07 04:03:42 +04:00
self . _tick_counter = 0
2009-07-12 05:23:16 +04:00
self . _tick_thread_slow = False
2013-07-07 04:03:42 +04:00
self . _tick_thread = threading . Thread ( name = " Tick thread " ,
target = self . _handle_tick_queue ,
args = ( ) )
self . _tick_thread . daemon = True
self . _tick_queue = Queue . PriorityQueue ( 100 )
2009-07-12 05:23:16 +04:00
2011-07-22 22:19:35 +04:00
self . inspection = None
2011-07-18 22:53:54 +04:00
self . _create_inspection_thread ( )
2008-06-13 20:12:37 +04:00
# Counter keeping track of how many manager and details windows
2009-10-29 18:08:40 +03:00
# are open. When it is decremented to 0, close the app or
# keep running in system tray if enabled
2008-06-13 20:12:37 +04:00
self . windows = 0
2013-04-16 03:25:54 +04:00
# Public bits set by virt-manager cli
self . skip_autostart = False
self . uri_at_startup = None
self . uri_cb = None
2013-05-30 01:43:38 +04:00
self . show_manager_window = True
2013-04-16 03:25:54 +04:00
2009-07-28 06:30:01 +04:00
self . init_systray ( )
2009-07-01 22:59:13 +04:00
2014-09-28 15:37:16 +04:00
self . add_gsettings_handle (
2011-04-13 17:27:02 +04:00
self . config . on_stats_update_interval_changed ( self . reschedule_timer ) )
2014-09-28 15:37:16 +04:00
self . add_gsettings_handle (
2011-04-13 17:27:02 +04:00
self . config . on_view_system_tray_changed ( self . system_tray_changed ) )
2006-06-14 18:59:40 +04:00
self . schedule_timer ( )
2007-09-10 06:57:24 +04:00
self . load_stored_uris ( )
2013-07-07 04:03:42 +04:00
self . _tick_thread . start ( )
2006-06-14 18:59:40 +04:00
self . tick ( )
2010-03-04 00:58:50 +03:00
2013-04-16 03:25:54 +04:00
def _activate ( self , ignore ) :
2013-05-30 01:43:38 +04:00
if self . show_manager_window :
self . show_manager ( )
else :
self . get_manager ( )
2013-04-16 03:25:54 +04:00
self . application . add_window ( self . _appwindow )
if self . uri_at_startup :
2013-08-08 16:11:18 +04:00
conn = self . make_conn ( self . uri_at_startup )
self . register_conn ( conn , skip_config = True )
2013-04-16 03:25:54 +04:00
if conn and self . uri_cb :
2015-04-12 16:34:55 +03:00
conn . connect_opt_out ( " state-changed " , self . uri_cb )
2013-04-16 03:25:54 +04:00
self . connect_to_uri ( self . uri_at_startup )
if not self . skip_autostart :
self . autostart_conns ( )
2009-07-28 06:30:01 +04:00
def init_systray ( self ) :
if self . systray :
return
2010-12-09 22:06:00 +03:00
self . systray = vmmSystray ( self )
2009-10-29 18:08:40 +03:00
self . systray . connect ( " action-toggle-manager " , self . _do_toggle_manager )
2009-07-28 06:30:01 +04:00
self . systray . connect ( " action-suspend-domain " , self . _do_suspend_domain )
self . systray . connect ( " action-resume-domain " , self . _do_resume_domain )
self . systray . connect ( " action-run-domain " , self . _do_run_domain )
self . systray . connect ( " action-shutdown-domain " , self . _do_shutdown_domain )
self . systray . connect ( " action-reboot-domain " , self . _do_reboot_domain )
self . systray . connect ( " action-destroy-domain " , self . _do_destroy_domain )
2013-03-17 01:59:32 +04:00
self . systray . connect ( " action-reset-domain " , self . _do_reset_domain )
2013-09-22 21:24:59 +04:00
self . systray . connect ( " action-save-domain " , self . _do_save_domain )
2013-09-22 23:13:41 +04:00
self . systray . connect ( " action-show-domain " , self . _do_show_vm )
self . systray . connect ( " action-migrate-domain " , self . _do_show_migrate )
self . systray . connect ( " action-delete-domain " , self . _do_delete_domain )
self . systray . connect ( " action-clone-domain " , self . _do_show_clone )
2010-11-24 04:13:50 +03:00
self . systray . connect ( " action-exit-app " , self . exit_app )
2009-07-28 06:30:01 +04:00
2009-10-29 18:08:40 +03:00
def system_tray_changed ( self , * ignore ) :
systray_enabled = self . config . get_view_system_tray ( )
if self . windows == 0 and not systray_enabled :
# Show the manager so that the user can control the application
self . show_manager ( )
2011-07-23 00:43:26 +04:00
def add_default_conn ( self , manager ) :
2010-03-04 00:58:50 +03:00
# Only add default if no connections are currently known
2015-09-07 01:15:16 +03:00
if self . config . get_conn_uris ( ) or self . uri_at_startup :
2010-03-04 00:58:50 +03:00
return
2013-09-01 22:19:23 +04:00
self . timeout_add ( 1000 , self . _add_default_conn , manager )
def _add_default_conn ( self , manager ) :
2010-03-04 00:58:50 +03:00
# Manager fail message
msg = _ ( " Could not detect a default hypervisor. Make \n "
" sure the appropriate virtualization packages \n "
" are installed (kvm, qemu, libvirt, etc.), and \n "
" that libvirtd is running. \n \n "
" A hypervisor connection can be manually \n "
" added via File->Add Connection " )
logging . debug ( " Determining default libvirt URI " )
ret = None
try :
2011-01-14 23:19:58 +03:00
libvirt_packages = self . config . libvirt_packages
packages = self . config . hv_packages + libvirt_packages
2013-09-01 22:19:23 +04:00
ret = packageutils . check_packagekit ( manager , manager . err , packages )
2010-03-04 00:58:50 +03:00
except :
logging . exception ( " Error talking to PackageKit " )
2013-09-01 22:19:23 +04:00
if ret :
2012-07-08 23:38:52 +04:00
tryuri = " qemu:///system "
2010-03-04 00:58:50 +03:00
else :
2015-04-06 23:43:44 +03:00
tryuri = vmmConnect . default_uri ( )
2010-03-04 00:58:50 +03:00
if tryuri is None :
manager . set_startup_error ( msg )
return
2013-06-24 20:15:28 +04:00
warnmsg = _ ( " The ' libvirtd ' service will need to be started. \n \n "
" After that, virt-manager will connect to libvirt on \n "
" the next application start up. " )
2013-06-14 01:35:48 +04:00
# Do the initial connection in an idle callback, so the
# packagekit async dialog has a chance to go away
def idle_connect ( ) :
do_start = packageutils . start_libvirtd ( )
2014-02-01 19:44:45 +04:00
connected = self . connect_to_uri ( tryuri ,
autoconnect = True , do_start = do_start )
2013-10-16 19:38:37 +04:00
if not connected and do_start :
2013-06-14 01:35:48 +04:00
manager . err . ok ( _ ( " Libvirt service must be started " ) , warnmsg )
self . idle_add ( idle_connect )
2010-03-04 00:58:50 +03:00
2007-08-29 01:57:25 +04:00
def load_stored_uris ( self ) :
2011-07-23 00:43:26 +04:00
uris = self . config . get_conn_uris ( )
2012-11-08 14:02:17 +04:00
if not uris :
return
logging . debug ( " About to connect to uris %s " , uris )
for uri in uris :
2013-08-08 16:11:18 +04:00
conn = self . make_conn ( uri )
self . register_conn ( conn , skip_config = True )
2007-08-29 01:57:25 +04:00
2011-07-23 00:43:26 +04:00
def autostart_conns ( self ) :
2014-02-01 19:44:45 +04:00
"""
We serialize conn autostart , so polkit / ssh - askpass doesn ' t spam
"""
queue = Queue . Queue ( )
auto_conns = [ uri for uri in self . conns
if self . conns [ uri ] [ " conn " ] . get_autoconnect ( ) ]
def add_next_to_queue ( ) :
if not auto_conns :
queue . put ( None )
else :
queue . put ( auto_conns . pop ( 0 ) )
def state_change_cb ( conn ) :
2014-09-12 02:16:21 +04:00
if conn . is_active ( ) :
2014-02-01 19:44:45 +04:00
add_next_to_queue ( )
conn . disconnect_by_func ( state_change_cb )
def connect ( uri ) :
self . connect_to_uri ( uri )
def handle_queue ( ) :
while True :
uri = queue . get ( )
if uri is None :
return
if uri not in self . conns :
add_next_to_queue ( )
continue
conn = self . conns [ uri ] [ " conn " ]
conn . connect ( " state-changed " , state_change_cb )
self . idle_add ( connect , uri )
add_next_to_queue ( )
2014-09-12 19:28:27 +04:00
self . _start_thread ( handle_queue , " Conn autostart thread " )
2008-03-24 18:39:19 +03:00
2006-06-14 22:36:26 +04:00
2014-06-03 01:17:47 +04:00
def _do_vm_removed ( self , conn , connkey ) :
2011-07-22 21:54:40 +04:00
hvuri = conn . get_uri ( )
2014-06-03 01:17:47 +04:00
if connkey not in self . conns [ hvuri ] [ " windowDetails " ] :
2011-04-12 02:35:21 +04:00
return
2014-06-03 01:17:47 +04:00
self . conns [ hvuri ] [ " windowDetails " ] [ connkey ] . cleanup ( )
del ( self . conns [ hvuri ] [ " windowDetails " ] [ connkey ] )
2006-06-15 00:56:49 +04:00
2011-07-23 00:43:26 +04:00
def _do_conn_changed ( self , conn ) :
2014-09-12 02:16:21 +04:00
if conn . is_active ( ) or conn . is_connecting ( ) :
2007-09-27 05:04:02 +04:00
return
2011-07-23 00:43:26 +04:00
hvuri = conn . get_uri ( )
2011-04-12 02:35:21 +04:00
2014-06-03 01:17:47 +04:00
for connkey in self . conns [ hvuri ] [ " windowDetails " ] . keys ( ) :
self . conns [ hvuri ] [ " windowDetails " ] [ connkey ] . cleanup ( )
del ( self . conns [ hvuri ] [ " windowDetails " ] [ connkey ] )
2011-04-12 02:35:21 +04:00
if ( self . windowCreate and
self . windowCreate . conn and
2009-03-09 23:16:45 +03:00
self . windowCreate . conn . get_uri ( ) == hvuri ) :
self . windowCreate . close ( )
2007-09-27 05:04:02 +04:00
2013-06-15 00:22:33 +04:00
def reschedule_timer ( self , * args , * * kwargs ) :
2013-06-18 04:17:20 +04:00
ignore = args
ignore = kwargs
2006-06-14 18:59:40 +04:00
self . schedule_timer ( )
def schedule_timer ( self ) :
2010-12-09 22:06:00 +03:00
interval = self . config . get_stats_update_interval ( ) * 1000
2006-06-14 18:59:40 +04:00
2012-11-08 17:15:02 +04:00
if self . timer is not None :
self . remove_gobject_timeout ( self . timer )
2006-06-14 18:59:40 +04:00
self . timer = None
2012-11-08 17:15:02 +04:00
self . timer = self . timeout_add ( interval , self . tick )
2006-06-14 18:59:40 +04:00
2013-07-07 19:06:15 +04:00
def _add_obj_to_tick_queue ( self , obj , isprio , * * kwargs ) :
2013-07-07 04:03:42 +04:00
if self . _tick_queue . full ( ) :
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. " )
2009-10-01 20:04:03 +04:00
self . _tick_thread_slow = True
2013-07-07 04:03:42 +04:00
return
2009-07-12 05:23:16 +04:00
2013-07-07 04:03:42 +04:00
self . _tick_counter + = 1
2013-07-07 17:42:21 +04:00
self . _tick_queue . put ( ( isprio and PRIO_HIGH or PRIO_LOW ,
2013-07-07 19:06:15 +04:00
self . _tick_counter ,
obj , kwargs ) )
2007-03-10 00:22:43 +03:00
2013-07-07 19:06:15 +04:00
def _schedule_priority_tick ( self , conn , kwargs ) :
self . _add_obj_to_tick_queue ( conn , True , * * kwargs )
2013-07-07 04:03:42 +04:00
def tick ( self ) :
2011-07-23 00:43:26 +04:00
for uri in self . conns . keys ( ) :
conn = self . conns [ uri ] [ " conn " ]
2013-07-07 19:06:15 +04:00
self . _add_obj_to_tick_queue ( conn , False ,
stats_update = True , pollvm = True )
2013-07-07 04:03:42 +04:00
return 1
2011-07-25 21:31:36 +04:00
2015-04-11 21:41:02 +03:00
def _handle_tick_error ( self , msg , details ) :
if self . windows < = 0 :
# This means the systray icon is running. Don't raise an error
# here to avoid spamming dialogs out of nowhere.
logging . debug ( msg + " \n \n " + details )
return
self . err . show_err ( msg , details = details )
2013-07-07 04:03:42 +04:00
def _handle_tick_queue ( self ) :
while True :
2014-04-16 18:32:52 +04:00
ignore1 , ignore2 , conn , kwargs = self . _tick_queue . get ( )
try :
2015-04-13 23:56:46 +03:00
conn . tick_from_engine ( * * kwargs )
2014-04-16 18:32:52 +04:00
except Exception , e :
tb = " " . join ( traceback . format_exc ( ) )
error_msg = ( _ ( " Error polling connection ' %s ' : %s " )
% ( conn . get_uri ( ) , e ) )
2015-04-11 21:41:02 +03:00
self . idle_add ( self . _handle_tick_error , error_msg , tb )
2014-04-16 18:32:52 +04:00
2013-07-07 04:03:42 +04:00
self . _tick_queue . task_done ( )
2006-06-14 18:59:40 +04:00
return 1
2013-07-07 04:03:42 +04:00
2011-04-13 18:47:31 +04:00
def increment_window_counter ( self , src ) :
ignore = src
2008-06-13 20:12:37 +04:00
self . windows + = 1
2012-01-17 07:04:40 +04:00
logging . debug ( " window counter incremented to %s " , self . windows )
2008-06-13 20:12:37 +04:00
2011-04-13 18:47:31 +04:00
def decrement_window_counter ( self , src ) :
2008-06-13 20:12:37 +04:00
self . windows - = 1
2012-01-17 07:04:40 +04:00
logging . debug ( " window counter decremented to %s " , self . windows )
2011-04-13 17:27:02 +04:00
2013-07-13 06:10:16 +04:00
if self . _can_exit ( ) :
2013-06-11 18:44:25 +04:00
# Defer this to an idle callback, since we can race with
# a vmmDetails window being deleted.
self . idle_add ( self . exit_app , src )
2008-06-13 20:12:37 +04:00
2013-07-13 06:10:16 +04:00
def _can_exit ( self ) :
# Don't exit if system tray is enabled
return ( self . windows < = 0 and
self . systray and
not self . systray . is_visible ( ) )
2011-07-24 05:16:54 +04:00
def _cleanup ( self ) :
self . err = None
if self . inspection :
self . inspection . cleanup ( )
self . inspection = None
2012-11-08 17:15:02 +04:00
if self . timer is not None :
2013-02-16 23:03:30 +04:00
GLib . source_remove ( self . timer )
2011-07-24 05:16:54 +04:00
if self . systray :
self . systray . cleanup ( )
self . systray = None
self . get_manager ( )
if self . windowManager :
self . windowManager . cleanup ( )
self . windowManager = None
if self . windowPreferences :
self . windowPreferences . cleanup ( )
self . windowPreferences = None
if self . windowAbout :
self . windowAbout . cleanup ( )
self . windowAbout = None
if self . windowConnect :
self . windowConnect . cleanup ( )
self . windowConnect = None
if self . windowCreate :
self . windowCreate . cleanup ( )
self . windowCreate = None
if self . windowMigrate :
self . windowMigrate . cleanup ( )
self . windowMigrate = None
2013-06-18 00:29:51 +04:00
if self . delete_dialog :
self . delete_dialog . cleanup ( )
self . delete_dialog = None
2011-07-24 05:16:54 +04:00
# Do this last, so any manually 'disconnected' signals
# take precedence over cleanup signal removal
for uri in self . conns :
self . cleanup_conn ( uri )
self . conns = { }
2011-04-13 17:27:02 +04:00
2011-04-13 18:47:31 +04:00
def exit_app ( self , src ) :
2011-04-13 17:27:02 +04:00
if self . err is None :
# Already in cleanup
return
self . cleanup ( )
2011-04-11 20:54:47 +04:00
if debug_ref_leaks :
2011-04-13 17:27:02 +04:00
objs = self . config . get_objects ( )
# Engine will always appear to leak
objs . remove ( self . object_key )
2011-04-14 19:26:53 +04:00
if src . object_key in objs :
# UI that initiates the app exit will always appear to leak
objs . remove ( src . object_key )
2011-04-13 17:27:02 +04:00
for name in objs :
2012-01-17 07:04:40 +04:00
logging . debug ( " Leaked %s " , name )
2011-04-11 20:54:47 +04:00
2008-10-30 16:25:53 +03:00
logging . debug ( " Exiting app normally. " )
2013-06-14 19:24:32 +04:00
# We need this if there are any asyncdialog fobjs running
if Gtk . main_level ( ) :
logging . debug ( " %s other gtk main loops running, killing them. " ,
Gtk . main_level ( ) )
for ignore in range ( Gtk . main_level ( ) ) :
Gtk . main_quit ( )
2013-04-16 03:25:54 +04:00
self . application . remove_window ( self . _appwindow )
2008-06-13 20:12:37 +04:00
2011-07-18 22:53:54 +04:00
def _create_inspection_thread ( self ) :
2013-06-14 00:00:33 +04:00
logging . debug ( " libguestfs inspection support: %s " ,
self . config . support_inspection )
2011-07-18 22:53:54 +04:00
if not self . config . support_inspection :
return
2013-06-14 00:00:33 +04:00
2014-09-13 00:10:45 +04:00
from . inspection import vmmInspection
2011-07-22 22:19:35 +04:00
self . inspection = vmmInspection ( )
self . inspection . start ( )
2011-07-23 00:43:26 +04:00
self . connect ( " conn-added " , self . inspection . conn_added )
self . connect ( " conn-removed " , self . inspection . conn_removed )
2011-07-18 22:53:54 +04:00
return
2015-04-11 21:34:38 +03:00
def _find_error_parent_cb ( self ) :
"""
Search over the toplevel windows for any that are visible or have
focus , and use that
"""
windowlist = [ self . windowManager ]
for conndict in self . conns . values ( ) :
windowlist . extend ( conndict [ " windowDetails " ] . values ( ) )
windowlist . extend (
[ conndict [ " windowHost " ] for conndict in self . conns . values ( ) ] )
use_win = None
for window in windowlist :
if not window :
continue
if window . topwin . has_focus ( ) :
use_win = window
break
if not use_win and window . is_visible ( ) :
use_win = window
if use_win :
return use_win . topwin
2012-11-08 14:02:17 +04:00
2013-08-08 16:11:18 +04:00
def make_conn ( self , uri , probe = False ) :
2011-07-23 00:43:26 +04:00
conn = self . _check_conn ( uri )
2010-11-30 02:00:15 +03:00
if conn :
return conn
2011-07-15 04:52:40 +04:00
conn = vmmConnection ( uri )
2011-07-23 00:43:26 +04:00
self . conns [ uri ] = {
" conn " : conn ,
2007-09-10 06:57:24 +04:00
" windowHost " : None ,
" windowDetails " : { } ,
2009-07-26 23:54:14 +04:00
" windowClone " : None ,
2013-08-08 16:11:18 +04:00
" probeConnection " : probe
2011-04-12 20:06:44 +04:00
}
2010-11-24 02:54:12 +03:00
conn . connect ( " vm-removed " , self . _do_vm_removed )
2011-07-23 00:43:26 +04:00
conn . connect ( " state-changed " , self . _do_conn_changed )
2013-07-13 06:10:16 +04:00
conn . connect ( " connect-error " , self . _connect_error )
2013-07-07 04:03:42 +04:00
conn . connect ( " priority-tick " , self . _schedule_priority_tick )
2010-11-24 02:54:12 +03:00
2009-07-14 22:48:09 +04:00
return conn
2012-11-08 14:02:17 +04:00
2013-08-08 16:11:18 +04:00
def register_conn ( self , conn , skip_config = False ) :
# if `skip_config' then the connection is only showed in the ui and
# not added to the config.
if not skip_config and conn . get_uri ( ) not in \
( self . config . get_conn_uris ( ) or [ ] ) :
self . config . add_conn ( conn . get_uri ( ) )
self . emit ( " conn-added " , conn )
2012-11-08 14:02:17 +04:00
2013-08-08 16:11:18 +04:00
def connect_to_uri ( self , uri , autoconnect = None , do_start = True , probe = False ) :
try :
conn = self . make_conn ( uri , probe = probe )
self . register_conn ( conn )
2012-11-08 14:02:17 +04:00
if autoconnect is not None :
conn . set_autoconnect ( bool ( autoconnect ) )
if do_start :
conn . open ( )
2013-10-16 19:38:37 +04:00
else :
try :
conn . open ( )
except :
return None
2012-11-08 14:02:17 +04:00
return conn
except Exception :
logging . exception ( " Error connecting to %s " , uri )
return None
2011-07-23 00:43:26 +04:00
def cleanup_conn ( self , uri ) :
2011-04-13 17:27:02 +04:00
try :
2011-07-23 00:43:26 +04:00
if self . conns [ uri ] [ " windowHost " ] :
self . conns [ uri ] [ " windowHost " ] . cleanup ( )
if self . conns [ uri ] [ " windowClone " ] :
self . conns [ uri ] [ " windowClone " ] . cleanup ( )
2011-04-13 17:27:02 +04:00
2011-07-23 00:43:26 +04:00
details = self . conns [ uri ] [ " windowDetails " ]
2011-04-13 17:27:02 +04:00
for win in details . values ( ) :
win . cleanup ( )
2011-07-23 00:43:26 +04:00
self . conns [ uri ] [ " conn " ] . cleanup ( )
2011-04-13 17:27:02 +04:00
except :
logging . exception ( " Error cleaning up conn in engine " )
2011-07-23 00:43:26 +04:00
def remove_conn ( self , src , uri ) :
2011-07-22 21:42:20 +04:00
ignore = src
2011-07-23 00:43:26 +04:00
self . cleanup_conn ( uri )
del ( self . conns [ uri ] )
2011-04-12 19:50:10 +04:00
2011-07-23 00:43:26 +04:00
self . emit ( " conn-removed " , uri )
self . config . remove_conn ( uri )
2007-09-10 06:57:24 +04:00
2011-04-11 21:06:59 +04:00
def connect ( self , name , callback , * args ) :
handle_id = vmmGObject . connect ( self , name , callback , * args )
2007-09-10 06:57:24 +04:00
2011-07-23 00:43:26 +04:00
if name == " conn-added " :
for uri in self . conns . keys ( ) :
self . emit ( " conn-added " ,
self . conns [ uri ] [ " conn " ] )
2007-09-10 06:57:24 +04:00
return handle_id
2011-07-23 00:43:26 +04:00
def _check_conn ( self , uri ) :
conn = self . conns . get ( uri )
2010-03-24 17:57:42 +03:00
if conn :
2011-07-23 00:43:26 +04:00
return conn [ " conn " ]
2010-03-24 17:57:42 +03:00
return None
2011-07-23 00:43:26 +04:00
def _lookup_conn ( self , uri ) :
conn = self . _check_conn ( uri )
2009-07-14 22:48:09 +04:00
if not conn :
raise RuntimeError ( _ ( " Unknown connection URI %s " ) % uri )
2010-03-24 17:57:42 +03:00
return conn
2006-07-17 21:08:58 +04:00
2013-07-13 06:10:16 +04:00
def _connect_error ( self , conn , errmsg , tb , warnconsole ) :
errmsg = errmsg . strip ( " \n " )
tb = tb . strip ( " \n " )
hint = " "
show_errmsg = True
if conn . is_remote ( ) :
2014-09-25 18:13:20 +04:00
logging . debug ( " connect_error: conn transport= %s " ,
2015-04-11 19:08:57 +03:00
conn . get_uri_transport ( ) )
2013-07-13 06:10:16 +04:00
if re . search ( r " nc: .* -- ' U ' " , tb ) :
hint + = _ ( " The remote host requires a version of netcat/nc \n "
" which supports the -U option. " )
show_errmsg = False
2015-04-11 19:08:57 +03:00
elif ( conn . get_uri_transport ( ) == " ssh " and
2013-07-13 06:10:16 +04:00
re . search ( r " ssh-askpass " , tb ) ) :
if self . config . askpass_package :
ret = packageutils . check_packagekit (
2013-09-01 22:19:23 +04:00
None ,
2013-07-13 06:10:16 +04:00
self . err ,
2013-09-01 22:19:23 +04:00
self . config . askpass_package )
2013-07-13 06:10:16 +04:00
if ret :
conn . open ( )
return
hint + = _ ( " You need to install openssh-askpass or "
" similar \n to connect to this host. " )
show_errmsg = False
else :
hint + = _ ( " Verify that the ' libvirtd ' daemon is running \n "
" on the remote host. " )
elif conn . is_xen ( ) :
hint + = _ ( " Verify that: \n "
" - A Xen host kernel was booted \n "
" - The Xen service has been started " )
else :
if warnconsole :
hint + = _ ( " Could not detect a local session: if you are \n "
" running virt-manager over ssh -X or VNC, you \n "
" may not be able to connect to libvirt as a \n "
" regular user. Try running as root. " )
show_errmsg = False
elif re . search ( r " libvirt-sock " , tb ) :
hint + = _ ( " Verify that the ' libvirtd ' daemon is running. " )
show_errmsg = False
2013-08-08 16:11:18 +04:00
probe_connection = self . conns [ conn . get_uri ( ) ] [ " probeConnection " ]
2013-07-13 06:10:16 +04:00
msg = _ ( " Unable to connect to libvirt. " )
if show_errmsg :
msg + = " \n \n %s " % errmsg
if hint :
msg + = " \n \n %s " % hint
msg = msg . strip ( " \n " )
details = msg
details + = " \n \n "
details + = " Libvirt URI is: %s \n \n " % conn . get_uri ( )
details + = tb
2013-08-08 16:11:18 +04:00
if probe_connection :
2015-04-05 02:40:22 +03:00
msg + = " \n \n "
msg + = _ ( " Would you still like to remember this connection? " )
2013-08-08 16:11:18 +04:00
title = _ ( " Virtual Machine Manager Connection Failure " )
if probe_connection :
remember_connection = self . err . show_err ( msg , details , title ,
buttons = Gtk . ButtonsType . YES_NO ,
2013-09-07 04:16:37 +04:00
dialog_type = Gtk . MessageType . QUESTION , modal = True )
2013-08-08 16:11:18 +04:00
if remember_connection :
self . conns [ conn . get_uri ( ) ] [ " probeConnection " ] = False
else :
self . idle_add ( self . _do_edit_connect , self . windowManager , conn )
2013-07-13 06:10:16 +04:00
else :
2013-08-08 16:11:18 +04:00
if self . _can_exit ( ) :
2013-09-07 04:16:37 +04:00
self . err . show_err ( msg , details , title , modal = True )
2013-08-08 16:11:18 +04:00
self . idle_add ( self . exit_app , conn )
else :
self . err . show_err ( msg , details , title )
2013-07-13 06:10:16 +04:00
2015-04-05 02:40:22 +03:00
2010-11-24 02:54:12 +03:00
####################
# Dialog launchers #
####################
2010-11-24 04:13:50 +03:00
def _do_show_about ( self , src ) :
2010-11-24 02:54:12 +03:00
try :
2012-11-08 17:15:02 +04:00
if self . windowAbout is None :
2010-12-09 01:26:19 +03:00
self . windowAbout = vmmAbout ( )
2010-11-24 02:54:12 +03:00
self . windowAbout . show ( )
except Exception , e :
2011-04-06 19:22:03 +04:00
src . err . show_err ( _ ( " Error launching ' About ' dialog: %s " ) % str ( e ) )
2010-11-24 02:54:12 +03:00
def _get_preferences ( self ) :
if self . windowPreferences :
return self . windowPreferences
2010-12-09 01:26:19 +03:00
obj = vmmPreferences ( )
2010-11-24 02:54:12 +03:00
self . windowPreferences = obj
return self . windowPreferences
2010-11-24 04:13:50 +03:00
def _do_show_preferences ( self , src ) :
2010-11-24 02:54:12 +03:00
try :
2011-04-14 16:47:42 +04:00
self . _get_preferences ( ) . show ( src . topwin )
2010-11-24 02:54:12 +03:00
except Exception , e :
2011-04-06 19:22:03 +04:00
src . err . show_err ( _ ( " Error launching preferences: %s " ) % str ( e ) )
2010-11-24 02:54:12 +03:00
def _get_host_dialog ( self , uri ) :
2011-07-23 00:43:26 +04:00
if self . conns [ uri ] [ " windowHost " ] :
return self . conns [ uri ] [ " windowHost " ]
2010-11-24 02:54:12 +03:00
2014-06-03 01:17:47 +04:00
conn = self . _lookup_conn ( uri )
obj = vmmHost ( conn )
2011-04-13 18:47:31 +04:00
2010-11-24 04:13:50 +03:00
obj . connect ( " action-exit-app " , self . exit_app )
2010-11-24 02:54:12 +03:00
obj . connect ( " action-view-manager " , self . _do_show_manager )
2011-04-13 18:47:31 +04:00
obj . connect ( " host-opened " , self . increment_window_counter )
obj . connect ( " host-closed " , self . decrement_window_counter )
2011-07-23 00:43:26 +04:00
self . conns [ uri ] [ " windowHost " ] = obj
return self . conns [ uri ] [ " windowHost " ]
2010-11-24 02:54:12 +03:00
2010-11-24 04:13:50 +03:00
def _do_show_host ( self , src , uri ) :
2010-11-24 02:54:12 +03:00
try :
self . _get_host_dialog ( uri ) . show ( )
except Exception , e :
2011-04-06 19:22:03 +04:00
src . err . show_err ( _ ( " Error launching host dialog: %s " ) % str ( e ) )
2010-11-24 02:54:12 +03:00
2012-11-08 14:02:17 +04:00
2010-11-24 02:54:12 +03:00
def _get_connect_dialog ( self ) :
if self . windowConnect :
return self . windowConnect
2012-11-08 14:02:17 +04:00
def completed ( src , uri , autoconnect ) :
2011-07-15 04:52:40 +04:00
ignore = src
2013-08-08 16:11:18 +04:00
return self . connect_to_uri ( uri , autoconnect , probe = True )
2010-11-24 02:54:12 +03:00
2012-11-08 14:02:17 +04:00
def cancelled ( src ) :
if len ( self . conns . keys ( ) ) == 0 :
self . exit_app ( src )
2010-12-09 01:26:19 +03:00
obj = vmmConnect ( )
2012-11-08 14:02:17 +04:00
obj . connect ( " completed " , completed )
obj . connect ( " cancelled " , cancelled )
2010-11-24 02:54:12 +03:00
self . windowConnect = obj
return self . windowConnect
2012-11-08 14:02:17 +04:00
2013-08-08 16:11:18 +04:00
def _do_show_connect ( self , src , reset_state = True ) :
2010-11-24 02:54:12 +03:00
try :
2013-08-08 16:11:18 +04:00
self . _get_connect_dialog ( ) . show ( src . topwin , reset_state )
2010-11-24 02:54:12 +03:00
except Exception , e :
2011-04-06 19:22:03 +04:00
src . err . show_err ( _ ( " Error launching connect dialog: %s " ) % str ( e ) )
2010-11-24 02:54:12 +03:00
2013-08-08 16:11:18 +04:00
def _do_edit_connect ( self , src , connection ) :
try :
self . _do_show_connect ( src , False )
finally :
self . remove_conn ( None , connection . get_uri ( ) )
2014-06-03 01:17:47 +04:00
def _get_details_dialog ( self , uri , connkey ) :
if connkey in self . conns [ uri ] [ " windowDetails " ] :
return self . conns [ uri ] [ " windowDetails " ] [ connkey ]
2010-11-24 02:54:12 +03:00
2014-06-03 01:17:47 +04:00
conn = self . _lookup_conn ( uri )
2010-11-24 02:54:12 +03:00
2014-06-03 01:17:47 +04:00
obj = vmmDetails ( conn . get_vm ( connkey ) )
2010-11-24 02:54:12 +03:00
obj . connect ( " action-save-domain " , self . _do_save_domain )
obj . connect ( " action-destroy-domain " , self . _do_destroy_domain )
2013-03-17 01:59:32 +04:00
obj . connect ( " action-reset-domain " , self . _do_reset_domain )
2010-11-24 02:54:12 +03:00
obj . connect ( " action-suspend-domain " , self . _do_suspend_domain )
obj . connect ( " action-resume-domain " , self . _do_resume_domain )
obj . connect ( " action-run-domain " , self . _do_run_domain )
obj . connect ( " action-shutdown-domain " , self . _do_shutdown_domain )
obj . connect ( " action-reboot-domain " , self . _do_reboot_domain )
2010-11-24 04:13:50 +03:00
obj . connect ( " action-exit-app " , self . exit_app )
2010-11-24 02:54:12 +03:00
obj . connect ( " action-view-manager " , self . _do_show_manager )
2010-11-24 04:13:50 +03:00
obj . connect ( " action-migrate-domain " , self . _do_show_migrate )
2013-06-18 00:29:51 +04:00
obj . connect ( " action-delete-domain " , self . _do_delete_domain )
2010-11-24 04:13:50 +03:00
obj . connect ( " action-clone-domain " , self . _do_show_clone )
2011-04-13 18:47:31 +04:00
obj . connect ( " details-opened " , self . increment_window_counter )
obj . connect ( " details-closed " , self . decrement_window_counter )
2010-11-24 02:54:12 +03:00
2014-06-03 01:17:47 +04:00
self . conns [ uri ] [ " windowDetails " ] [ connkey ] = obj
return self . conns [ uri ] [ " windowDetails " ] [ connkey ]
2013-07-13 06:10:16 +04:00
2014-06-03 01:17:47 +04:00
def _show_vm_helper ( self , src , uri , vm , page , forcepage ) :
try :
details = self . _get_details_dialog ( uri , vm . get_connkey ( ) )
2011-06-09 00:33:20 +04:00
if forcepage or not details . is_visible ( ) :
if page == DETAILS_PERF :
details . activate_performance_page ( )
elif page == DETAILS_CONFIG :
details . activate_config_page ( )
elif page == DETAILS_CONSOLE :
details . activate_console_page ( )
elif page is None :
details . activate_default_page ( )
2010-11-24 02:54:12 +03:00
details . show ( )
except Exception , e :
2011-04-06 19:22:03 +04:00
src . err . show_err ( _ ( " Error launching details: %s " ) % str ( e ) )
2013-07-13 06:10:16 +04:00
finally :
if self . _can_exit ( ) :
self . idle_add ( self . exit_app , src )
2010-11-24 02:54:12 +03:00
2014-06-03 01:17:47 +04:00
def _do_show_vm ( self , src , uri , connkey ) :
conn = self . _lookup_conn ( uri )
vm = conn . get_vm ( connkey )
self . _show_vm_helper ( src , uri , vm , None , False )
2010-11-24 02:54:12 +03:00
def get_manager ( self ) :
if self . windowManager :
return self . windowManager
2011-07-22 21:42:20 +04:00
obj = vmmManager ( )
2010-11-24 02:54:12 +03:00
obj . connect ( " action-suspend-domain " , self . _do_suspend_domain )
obj . connect ( " action-resume-domain " , self . _do_resume_domain )
obj . connect ( " action-run-domain " , self . _do_run_domain )
obj . connect ( " action-shutdown-domain " , self . _do_shutdown_domain )
obj . connect ( " action-reboot-domain " , self . _do_reboot_domain )
obj . connect ( " action-destroy-domain " , self . _do_destroy_domain )
2013-03-17 01:59:32 +04:00
obj . connect ( " action-reset-domain " , self . _do_reset_domain )
2010-11-24 02:54:12 +03:00
obj . connect ( " action-save-domain " , self . _do_save_domain )
2010-11-24 04:13:50 +03:00
obj . connect ( " action-migrate-domain " , self . _do_show_migrate )
2013-06-18 00:29:51 +04:00
obj . connect ( " action-delete-domain " , self . _do_delete_domain )
2010-11-24 04:13:50 +03:00
obj . connect ( " action-clone-domain " , self . _do_show_clone )
2013-09-22 23:13:41 +04:00
obj . connect ( " action-show-domain " , self . _do_show_vm )
2010-11-24 02:54:12 +03:00
obj . connect ( " action-show-preferences " , self . _do_show_preferences )
obj . connect ( " action-show-create " , self . _do_show_create )
obj . connect ( " action-show-about " , self . _do_show_about )
obj . connect ( " action-show-host " , self . _do_show_host )
obj . connect ( " action-show-connect " , self . _do_show_connect )
2010-11-24 04:13:50 +03:00
obj . connect ( " action-exit-app " , self . exit_app )
2011-04-13 18:47:31 +04:00
obj . connect ( " manager-opened " , self . increment_window_counter )
obj . connect ( " manager-closed " , self . decrement_window_counter )
2011-07-23 00:43:26 +04:00
obj . connect ( " remove-conn " , self . remove_conn )
obj . connect ( " add-default-conn " , self . add_default_conn )
2011-07-22 21:42:20 +04:00
2011-07-23 00:43:26 +04:00
self . connect ( " conn-added " , obj . add_conn )
self . connect ( " conn-removed " , obj . remove_conn )
2010-11-24 02:54:12 +03:00
2014-06-26 13:51:38 +04:00
obj . set_initial_selection ( self . uri_at_startup )
2010-11-24 02:54:12 +03:00
self . windowManager = obj
return self . windowManager
2010-11-24 04:13:50 +03:00
def _do_toggle_manager ( self , ignore ) :
2010-11-24 02:54:12 +03:00
manager = self . get_manager ( )
2010-12-14 01:48:19 +03:00
if manager . is_visible ( ) :
manager . close ( )
else :
2010-11-24 02:54:12 +03:00
manager . show ( )
2010-11-24 04:13:50 +03:00
def _do_show_manager ( self , src ) :
2010-11-24 02:54:12 +03:00
try :
2011-04-13 17:27:02 +04:00
manager = self . get_manager ( )
manager . show ( )
2010-11-24 02:54:12 +03:00
except Exception , e :
2010-11-24 04:13:50 +03:00
if not src :
raise
2011-04-06 19:22:03 +04:00
src . err . show_err ( _ ( " Error launching manager: %s " ) % str ( e ) )
2010-11-24 02:54:12 +03:00
def _get_create_dialog ( self ) :
if self . windowCreate :
return self . windowCreate
2010-12-09 01:26:19 +03:00
obj = vmmCreate ( self )
2013-09-22 23:13:41 +04:00
obj . connect ( " action-show-domain " , self . _do_show_vm )
2010-11-24 02:54:12 +03:00
self . windowCreate = obj
return self . windowCreate
2010-11-24 04:13:50 +03:00
def _do_show_create ( self , src , uri ) :
2010-11-24 02:54:12 +03:00
try :
2011-04-14 16:47:42 +04:00
self . _get_create_dialog ( ) . show ( src . topwin , uri )
2010-11-24 02:54:12 +03:00
except Exception , e :
2011-04-06 19:22:03 +04:00
src . err . show_err ( _ ( " Error launching manager: %s " ) % str ( e ) )
2010-11-24 02:54:12 +03:00
2014-06-03 01:17:47 +04:00
def _do_show_migrate ( self , src , uri , connkey ) :
2010-11-24 02:54:12 +03:00
try :
2011-07-23 00:43:26 +04:00
conn = self . _lookup_conn ( uri )
2014-06-03 01:17:47 +04:00
vm = conn . get_vm ( connkey )
2010-11-24 02:54:12 +03:00
if not self . windowMigrate :
2015-04-16 18:21:34 +03:00
self . windowMigrate = vmmMigrateDialog ( self )
2010-11-24 02:54:12 +03:00
2015-04-16 18:21:34 +03:00
self . windowMigrate . show ( src . topwin , vm )
2010-11-24 02:54:12 +03:00
except Exception , e :
2011-04-06 19:22:03 +04:00
src . err . show_err ( _ ( " Error launching migrate dialog: %s " ) % str ( e ) )
2010-11-24 02:54:12 +03:00
2014-06-03 01:17:47 +04:00
def _do_show_clone ( self , src , uri , connkey ) :
conn = self . _lookup_conn ( uri )
orig_vm = conn . get_vm ( connkey )
2011-07-23 00:43:26 +04:00
clone_window = self . conns [ uri ] [ " windowClone " ]
2010-11-24 02:54:12 +03:00
try :
2012-11-08 17:15:02 +04:00
if clone_window is None :
2010-12-09 01:26:19 +03:00
clone_window = vmmCloneVM ( orig_vm )
2011-07-23 00:43:26 +04:00
self . conns [ uri ] [ " windowClone " ] = clone_window
2010-11-24 02:54:12 +03:00
else :
clone_window . set_orig_vm ( orig_vm )
2011-04-14 16:47:42 +04:00
clone_window . show ( src . topwin )
2010-11-24 02:54:12 +03:00
except Exception , e :
2011-04-06 19:22:03 +04:00
src . err . show_err ( _ ( " Error setting clone parameters: %s " ) % str ( e ) )
2010-11-24 04:13:50 +03:00
##########################################
# Window launchers from virt-manager cli #
##########################################
def show_manager ( self ) :
self . _do_show_manager ( None )
2010-11-24 22:01:51 +03:00
def show_host_summary ( self , uri ) :
self . _do_show_host ( self . get_manager ( ) , uri )
def show_domain_creator ( self , uri ) :
2014-01-19 21:03:17 +04:00
self . show_manager ( )
2010-11-24 22:01:51 +03:00
self . _do_show_create ( self . get_manager ( ) , uri )
2010-11-24 04:13:50 +03:00
2010-11-24 02:54:12 +03:00
2014-06-03 01:17:47 +04:00
def _find_vm_by_cli_str ( self , uri , clistr ) :
"""
Lookup a VM by a string passed in on the CLI . Can be either
ID , domain name , or UUID
"""
if clistr . isdigit ( ) :
clistr = int ( clistr )
for vm in self . conns [ uri ] [ " conn " ] . list_vms ( ) :
if clistr == vm . get_id ( ) :
return vm
elif clistr == vm . get_name ( ) :
return vm
elif clistr == vm . get_uuid ( ) :
return vm
def _cli_show_vm_helper ( self , uri , clistr , page ) :
src = self . get_manager ( )
vm = self . _find_vm_by_cli_str ( uri , clistr )
if not vm :
src . err . show_err ( " %s does not have VM ' %s ' " %
( uri , clistr ) , modal = True )
2014-11-17 11:46:35 +03:00
self . exit_app ( src . err )
2014-06-03 01:17:47 +04:00
return
self . _show_vm_helper ( src , uri , vm , page , True )
def show_domain_console ( self , uri , clistr ) :
self . idle_add ( self . _cli_show_vm_helper , uri , clistr , DETAILS_CONSOLE )
def show_domain_editor ( self , uri , clistr ) :
self . idle_add ( self . _cli_show_vm_helper , uri , clistr , DETAILS_CONFIG )
2010-11-24 04:13:50 +03:00
2014-06-03 01:17:47 +04:00
def show_domain_performance ( self , uri , clistr ) :
self . idle_add ( self . _cli_show_vm_helper , uri , clistr , DETAILS_PERF )
2010-11-24 02:54:12 +03:00
2013-07-07 04:03:42 +04:00
2010-11-24 02:54:12 +03:00
#######################################
# Domain actions run/destroy/save ... #
#######################################
2014-06-03 01:17:47 +04:00
def _do_save_domain ( self , src , uri , connkey ) :
2011-07-23 00:43:26 +04:00
conn = self . _lookup_conn ( uri )
2014-06-03 01:17:47 +04:00
vm = conn . get_vm ( connkey )
2009-03-08 22:14:00 +03:00
2014-01-27 02:42:24 +04:00
if not src . err . chkbox_helper ( self . config . get_confirm_poweroff ,
2011-04-15 00:43:17 +04:00
self . config . set_confirm_poweroff ,
2015-06-02 15:21:58 +03:00
text1 = _ ( " Are you sure you want to save ' %s ' ? " ) % vm . get_name ( ) ) :
2011-04-15 00:43:17 +04:00
return
2009-03-08 22:14:00 +03:00
2013-06-14 01:05:33 +04:00
_cancel_cb = None
2010-12-08 20:52:33 +03:00
if vm . getjobinfo_supported :
2013-06-14 01:05:33 +04:00
_cancel_cb = ( self . _save_cancel , vm )
2010-12-08 20:52:33 +03:00
2013-07-05 16:59:58 +04:00
def cb ( asyncjob ) :
2015-04-11 20:52:48 +03:00
vm . save ( meter = asyncjob . get_meter ( ) )
2013-09-07 04:59:01 +04:00
def finish_cb ( error , details ) :
if error is not None :
error = _ ( " Error saving domain: %s " ) % error
src . err . show_err ( error , details = details )
2013-07-05 16:59:58 +04:00
progWin = vmmAsyncJob ( cb , [ ] ,
2013-09-07 04:59:01 +04:00
finish_cb , [ ] ,
2010-12-12 21:48:20 +03:00
_ ( " Saving Virtual Machine " ) ,
_ ( " Saving virtual machine memory to disk " ) ,
2013-06-14 01:05:33 +04:00
src . topwin , cancel_cb = _cancel_cb )
2013-09-07 04:59:01 +04:00
progWin . run ( )
2007-11-27 19:31:30 +03:00
2010-12-10 17:57:42 +03:00
def _save_cancel ( self , asyncjob , vm ) :
2010-12-08 22:14:38 +03:00
logging . debug ( " Cancelling save job " )
2010-12-08 20:52:33 +03:00
if not vm :
return
try :
vm . abort_job ( )
except Exception , e :
2010-12-08 22:14:38 +03:00
logging . exception ( " Error cancelling save job " )
2010-12-10 19:47:07 +03:00
asyncjob . show_warning ( _ ( " Error cancelling save job: %s " ) % str ( e ) )
2010-12-08 20:52:33 +03:00
return
asyncjob . job_canceled = True
return
2014-06-03 01:17:47 +04:00
def _do_destroy_domain ( self , src , uri , connkey ) :
2011-07-23 00:43:26 +04:00
conn = self . _lookup_conn ( uri )
2014-06-03 01:17:47 +04:00
vm = conn . get_vm ( connkey )
2011-04-15 00:43:17 +04:00
2014-01-27 02:42:24 +04:00
if not src . err . chkbox_helper (
2013-08-09 17:23:01 +04:00
self . config . get_confirm_forcepoweroff ,
2011-04-15 00:43:17 +04:00
self . config . set_confirm_forcepoweroff ,
text1 = _ ( " Are you sure you want to force poweroff ' %s ' ? " %
vm . get_name ( ) ) ,
text2 = _ ( " This will immediately poweroff the VM without "
" shutting down the OS and may cause data loss. " ) ) :
return
2009-07-14 22:48:09 +04:00
2012-01-17 07:04:40 +04:00
logging . debug ( " Destroying vm ' %s ' " , vm . get_name ( ) )
2011-04-15 23:23:13 +04:00
vmmAsyncJob . simple_async_noshow ( vm . destroy , [ ] , src ,
_ ( " Error shutting down domain " ) )
2007-11-27 19:31:30 +03:00
2014-06-03 01:17:47 +04:00
def _do_suspend_domain ( self , src , uri , connkey ) :
2011-07-23 00:43:26 +04:00
conn = self . _lookup_conn ( uri )
2014-06-03 01:17:47 +04:00
vm = conn . get_vm ( connkey )
2009-11-19 00:11:17 +03:00
2014-01-27 02:42:24 +04:00
if not src . err . chkbox_helper ( self . config . get_confirm_pause ,
2011-04-15 00:43:17 +04:00
self . config . set_confirm_pause ,
text1 = _ ( " Are you sure you want to pause ' %s ' ? " %
vm . get_name ( ) ) ) :
return
2009-07-14 22:48:09 +04:00
2012-01-17 07:04:40 +04:00
logging . debug ( " Pausing vm ' %s ' " , vm . get_name ( ) )
2011-04-15 23:23:13 +04:00
vmmAsyncJob . simple_async_noshow ( vm . suspend , [ ] , src ,
_ ( " Error pausing domain " ) )
2009-07-14 22:48:09 +04:00
2014-06-03 01:17:47 +04:00
def _do_resume_domain ( self , src , uri , connkey ) :
2011-07-23 00:43:26 +04:00
conn = self . _lookup_conn ( uri )
2014-06-03 01:17:47 +04:00
vm = conn . get_vm ( connkey )
2009-07-14 22:48:09 +04:00
2012-01-17 07:04:40 +04:00
logging . debug ( " Unpausing vm ' %s ' " , vm . get_name ( ) )
2011-04-15 23:23:13 +04:00
vmmAsyncJob . simple_async_noshow ( vm . resume , [ ] , src ,
_ ( " Error unpausing domain " ) )
2009-07-14 22:48:09 +04:00
2014-06-03 01:17:47 +04:00
def _do_run_domain ( self , src , uri , connkey ) :
2011-07-23 00:43:26 +04:00
conn = self . _lookup_conn ( uri )
2014-06-03 01:17:47 +04:00
vm = conn . get_vm ( connkey )
2009-07-14 22:48:09 +04:00
2012-01-17 07:04:40 +04:00
logging . debug ( " Starting vm ' %s ' " , vm . get_name ( ) )
2010-12-10 22:40:08 +03:00
2014-09-12 02:01:41 +04:00
if vm . has_managed_save ( ) :
2012-07-09 00:06:16 +04:00
def errorcb ( error , details ) :
# This is run from the main thread
res = src . err . show_err (
_ ( " Error restoring domain " ) + " : " + error ,
details = details ,
text2 = _ (
" The domain could not be restored. Would you like \n "
" to remove the saved state and perform a regular \n "
" start up? " ) ,
2012-11-08 17:15:02 +04:00
dialog_type = Gtk . MessageType . WARNING ,
buttons = Gtk . ButtonsType . YES_NO ,
2013-09-07 04:16:37 +04:00
modal = True )
2012-07-09 00:06:16 +04:00
if not res :
return
try :
2014-09-12 02:01:41 +04:00
vm . remove_saved_image ( )
2014-06-03 01:17:47 +04:00
self . _do_run_domain ( src , uri , connkey )
2012-07-09 00:06:16 +04:00
except Exception , e :
src . err . show_err ( _ ( " Error removing domain state: %s " )
% str ( e ) )
# VM will be restored, which can take some time, so show progress
2010-12-12 21:48:20 +03:00
title = _ ( " Restoring Virtual Machine " )
text = _ ( " Restoring virtual machine memory from disk " )
2013-10-05 18:03:56 +04:00
vmmAsyncJob . simple_async ( vm . startup , [ ] , src ,
title , text , " " , errorcb = errorcb )
2010-12-10 22:40:08 +03:00
else :
# Regular startup
errorintro = _ ( " Error starting domain " )
2011-04-14 23:28:22 +04:00
vmmAsyncJob . simple_async_noshow ( vm . startup , [ ] , src , errorintro )
2009-04-04 00:06:46 +04:00
2014-06-03 01:17:47 +04:00
def _do_shutdown_domain ( self , src , uri , connkey ) :
2011-07-23 00:43:26 +04:00
conn = self . _lookup_conn ( uri )
2014-06-03 01:17:47 +04:00
vm = conn . get_vm ( connkey )
2009-11-19 00:11:17 +03:00
2014-01-27 02:42:24 +04:00
if not src . err . chkbox_helper ( self . config . get_confirm_poweroff ,
2011-04-15 00:43:17 +04:00
self . config . set_confirm_poweroff ,
text1 = _ ( " Are you sure you want to poweroff ' %s ' ? " %
vm . get_name ( ) ) ) :
return
2009-07-14 22:48:09 +04:00
2012-01-17 07:04:40 +04:00
logging . debug ( " Shutting down vm ' %s ' " , vm . get_name ( ) )
2011-04-15 23:23:13 +04:00
vmmAsyncJob . simple_async_noshow ( vm . shutdown , [ ] , src ,
_ ( " Error shutting down domain " ) )
2007-11-27 19:31:30 +03:00
2014-06-03 01:17:47 +04:00
def _do_reboot_domain ( self , src , uri , connkey ) :
2011-07-23 00:43:26 +04:00
conn = self . _lookup_conn ( uri )
2014-06-03 01:17:47 +04:00
vm = conn . get_vm ( connkey )
2009-11-19 00:11:17 +03:00
2014-01-27 02:42:24 +04:00
if not src . err . chkbox_helper ( self . config . get_confirm_poweroff ,
2011-04-15 00:43:17 +04:00
self . config . set_confirm_poweroff ,
text1 = _ ( " Are you sure you want to reboot ' %s ' ? " %
vm . get_name ( ) ) ) :
return
2009-07-14 22:48:09 +04:00
2012-01-17 07:04:40 +04:00
logging . debug ( " Rebooting vm ' %s ' " , vm . get_name ( ) )
2015-04-11 18:09:09 +03:00
vmmAsyncJob . simple_async_noshow ( vm . reboot , [ ] , src ,
_ ( " Error rebooting domain " ) )
2008-04-08 22:30:47 +04:00
2014-06-03 01:17:47 +04:00
def _do_reset_domain ( self , src , uri , connkey ) :
2013-03-17 01:59:32 +04:00
conn = self . _lookup_conn ( uri )
2014-06-03 01:17:47 +04:00
vm = conn . get_vm ( connkey )
2013-03-17 01:59:32 +04:00
2014-01-27 02:42:24 +04:00
if not src . err . chkbox_helper (
2013-08-09 17:23:01 +04:00
self . config . get_confirm_forcepoweroff ,
2013-03-17 01:59:32 +04:00
self . config . set_confirm_forcepoweroff ,
text1 = _ ( " Are you sure you want to force reset ' %s ' ? " %
vm . get_name ( ) ) ,
text2 = _ ( " This will immediately reset the VM without "
" shutting down the OS and may cause data loss. " ) ) :
return
logging . debug ( " Resetting vm ' %s ' " , vm . get_name ( ) )
vmmAsyncJob . simple_async_noshow ( vm . reset , [ ] , src ,
_ ( " Error resetting domain " ) )
2013-06-18 00:29:51 +04:00
2014-06-03 01:17:47 +04:00
def _do_delete_domain ( self , src , uri , connkey ) :
2013-06-18 00:29:51 +04:00
conn = self . _lookup_conn ( uri )
2014-06-03 01:17:47 +04:00
vm = conn . get_vm ( connkey )
2013-06-18 00:29:51 +04:00
2014-04-30 23:54:00 +04:00
try :
if not self . delete_dialog :
self . delete_dialog = vmmDeleteDialog ( )
self . delete_dialog . show ( vm , src . topwin )
except Exception , e :
src . err . show_err ( _ ( " Error launching delete dialog: %s " ) % str ( e ) )