2012-07-08 23:05:28 +04:00
#
# Copyright (C) 2012 Red Hat, Inc.
# Copyright (C) 2012 Cole Robinson <crobinso@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
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA.
#
2013-04-12 01:16:33 +04:00
# pylint: disable=E0611
2013-04-16 21:38:19 +04:00
from gi . repository import Gio
2012-05-14 17:24:56 +04:00
from gi . repository import Gtk
2013-04-12 01:16:33 +04:00
# pylint: enable=E0611
2012-07-08 23:05:28 +04:00
import logging
import time
import traceback
from virtManager . asyncjob import vmmAsyncJob
#############################
# PackageKit lookup helpers #
#############################
2013-04-13 22:34:52 +04:00
2012-07-08 23:38:52 +04:00
def check_packagekit ( errbox , packages , ishv ) :
2012-07-08 23:05:28 +04:00
"""
Returns None when we determine nothing useful .
Returns ( success , did we just install libvirt ) otherwise .
"""
if not packages :
logging . debug ( " No PackageKit packages to search for. " )
return
logging . debug ( " Asking PackageKit what ' s installed locally. " )
try :
2013-04-16 21:38:19 +04:00
bus = Gio . bus_get_sync ( Gio . BusType . SYSTEM , None )
pk_control = Gio . DBusProxy . new_sync ( bus , 0 , None ,
" org.freedesktop.PackageKit " ,
" /org/freedesktop/PackageKit " ,
" org.freedesktop.PackageKit " , None )
2012-07-08 23:05:28 +04:00
except Exception :
logging . exception ( " Couldn ' t connect to packagekit " )
return
2012-07-08 23:38:52 +04:00
if ishv :
msg = _ ( " Searching for available hypervisors... " )
else :
msg = _ ( " Checking for installed package ' %s ' " ) % packages [ 0 ]
2013-06-14 01:37:12 +04:00
cancellable = Gio . Cancellable ( )
2012-07-08 23:05:28 +04:00
progWin = vmmAsyncJob ( _do_async_search ,
2013-06-14 01:37:12 +04:00
[ bus , pk_control , packages , cancellable ] , msg , msg ,
errbox . get_parent ( ) , async = False ,
cancel_cb = [ _cancel_search , cancellable ] )
2012-07-08 23:05:28 +04:00
error , ignore = progWin . run ( )
if error :
return
2013-04-13 21:41:59 +04:00
found = progWin . get_extra_data ( )
2012-07-08 23:05:28 +04:00
2013-04-12 00:32:00 +04:00
not_found = [ x for x in packages if x not in found ]
2012-07-08 23:05:28 +04:00
logging . debug ( " Missing packages: %s " , not_found )
do_install = not_found
if not do_install :
if not not_found :
# Got everything we wanted, try to connect
logging . debug ( " All packages found locally. " )
2012-07-08 23:38:52 +04:00
return [ ]
2012-07-08 23:05:28 +04:00
else :
logging . debug ( " No packages are available for install. " )
return
2012-07-08 23:38:52 +04:00
missing = reduce ( lambda x , y : x + " \n " + y , do_install , " " )
if ishv :
msg = ( _ ( " The following packages are not installed: \n %s \n \n "
" These are required to create KVM guests locally. \n "
" Would you like to install them now? " ) % missing )
title = _ ( " Packages required for KVM usage " )
else :
msg = _ ( " The following packages are not installed: \n %s \n \n "
" Would you like to install them now? " % missing )
title = _ ( " Recommended package installs " )
2012-07-08 23:05:28 +04:00
2012-07-08 23:38:52 +04:00
ret = errbox . yes_no ( title , msg )
2012-07-08 23:05:28 +04:00
if not ret :
logging . debug ( " Package install declined. " )
return
try :
packagekit_install ( do_install )
except Exception , e :
errbox . show_err ( _ ( " Error talking to PackageKit: %s " ) % str ( e ) )
return
2012-07-08 23:38:52 +04:00
return do_install
2012-07-08 23:05:28 +04:00
2013-04-13 22:34:52 +04:00
2013-06-14 01:37:12 +04:00
def _cancel_search ( asyncjob , cancellable ) :
cancellable . cancel ( )
asyncjob . job_cancelled = True
def _do_async_search ( asyncjob , bus , pk_control , packages , cancellable ) :
2012-07-08 23:05:28 +04:00
found = [ ]
try :
for name in packages :
2013-06-14 01:37:12 +04:00
ret_found = packagekit_search ( bus , pk_control , name , packages ,
cancellable )
2012-07-08 23:05:28 +04:00
found + = ret_found
except Exception , e :
2013-06-14 01:37:12 +04:00
if cancellable . is_cancelled ( ) :
logging . debug ( " Package search cancelled by user " )
asyncjob . set_error ( " Package search cancelled by user " )
else :
logging . exception ( " Error searching for installed packages " )
asyncjob . set_error ( str ( e ) , " " . join ( traceback . format_exc ( ) ) )
2012-07-08 23:05:28 +04:00
2013-04-13 21:41:59 +04:00
asyncjob . set_extra_data ( found )
2012-07-08 23:05:28 +04:00
2013-04-13 22:34:52 +04:00
2012-07-08 23:05:28 +04:00
def packagekit_install ( package_list ) :
2013-04-16 21:38:19 +04:00
bus = Gio . bus_get_sync ( Gio . BusType . SESSION , None )
pk_control = Gio . DBusProxy . new_sync ( bus , 0 , None ,
" org.freedesktop.PackageKit " ,
" /org/freedesktop/PackageKit " ,
" org.freedesktop.PackageKit.Modify " , None )
2012-07-08 23:05:28 +04:00
# Set 2 hour timeout
2013-04-16 21:38:19 +04:00
timeout = 1000 * 60 * 60 * 2
2012-07-08 23:05:28 +04:00
logging . debug ( " Installing packages: %s " , package_list )
2013-04-16 21:38:19 +04:00
pk_control . InstallPackageNames ( " (uass) " , 0 ,
2012-12-20 21:51:45 +04:00
package_list , " hide-confirm-search " ,
2012-07-08 23:05:28 +04:00
timeout = timeout )
2013-04-13 22:34:52 +04:00
2013-06-14 01:37:12 +04:00
def packagekit_search ( bus , pk_control , package_name , packages , cancellable ) :
2013-04-16 21:38:19 +04:00
tid = pk_control . CreateTransaction ( )
pk_trans = Gio . DBusProxy . new_sync ( bus , 0 , None ,
" org.freedesktop.PackageKit " , tid ,
2013-06-14 01:37:12 +04:00
" org.freedesktop.PackageKit.Transaction " ,
cancellable )
2012-07-08 23:05:28 +04:00
found = [ ]
def package ( info , package_id , summary ) :
ignore = info
ignore = summary
found_name = str ( package_id . split ( " ; " ) [ 0 ] )
if found_name in packages :
found . append ( found_name )
def error ( code , details ) :
raise RuntimeError ( " PackageKit search failure: %s %s " %
( code , details ) )
def finished ( ignore , runtime_ignore ) :
2012-05-14 17:24:56 +04:00
Gtk . main_quit ( )
2012-07-08 23:05:28 +04:00
2013-04-16 21:38:19 +04:00
def signal_cb ( proxy , sender , signal , args ) :
ignore = proxy
sender = proxy
if signal == " Finished " :
finished ( * args )
elif signal == " ErrorCode " :
error ( * args )
elif signal == " Package " :
package ( * args )
2012-07-08 23:05:28 +04:00
2013-04-16 21:38:19 +04:00
pk_trans . connect ( " g-signal " , signal_cb )
pk_trans . SearchNames ( " (tas) " , 2 * * 2 , [ package_name ] )
2012-07-08 23:05:28 +04:00
# Call main() so this function is synchronous
2012-05-14 17:24:56 +04:00
Gtk . main ( )
2012-07-08 23:05:28 +04:00
return found
###################
# Service helpers #
###################
2013-04-13 22:34:52 +04:00
2012-07-08 23:05:28 +04:00
def start_libvirtd ( ) :
"""
Connect to systemd and start libvirtd if required
"""
logging . debug ( " Trying to start libvirtd through systemd " )
unitname = " libvirtd.service "
try :
2013-04-16 21:38:19 +04:00
bus = Gio . bus_get_sync ( Gio . BusType . SYSTEM , None )
2012-07-08 23:05:28 +04:00
except :
logging . exception ( " Error getting system bus handle " )
return
try :
2013-04-16 21:38:19 +04:00
systemd = Gio . DBusProxy . new_sync ( bus , 0 , None ,
2012-07-08 23:05:28 +04:00
" org.freedesktop.systemd1 " ,
2013-04-16 21:38:19 +04:00
" /org/freedesktop/systemd1 " ,
" org.freedesktop.systemd1.Manager " , None )
2012-07-08 23:05:28 +04:00
except :
logging . exception ( " Couldn ' t connect to systemd " )
return
try :
2013-04-16 21:38:19 +04:00
unitpath = systemd . GetUnit ( " (s) " , unitname )
unit = Gio . DBusProxy . new_sync ( bus , 0 , None ,
" org.freedesktop.systemd1 " , unitpath ,
" org.freedesktop.systemd1.Unit " , None )
state = unit . get_cached_property ( " ActiveState " )
2012-07-08 23:05:28 +04:00
logging . debug ( " libvirtd state= %s " , state )
2013-04-16 21:38:19 +04:00
if str ( state ) . lower ( ) . strip ( " ' " ) == " active " :
2012-07-08 23:05:28 +04:00
logging . debug ( " libvirtd already active, not starting " )
return True
except :
logging . exception ( " Failed to lookup libvirtd status " )
return
# Connect to system-config-services and offer to start
try :
2012-10-29 04:18:51 +04:00
logging . debug ( " libvirtd not running, asking system-config-services "
" to start it " )
2013-04-16 21:38:19 +04:00
scs = Gio . DBusProxy . new_sync ( bus , 0 , None ,
2012-07-08 23:05:28 +04:00
" org.fedoraproject.Config.Services " ,
2013-04-16 21:38:19 +04:00
" /org/fedoraproject/Config/Services/systemd1 " ,
" org.freedesktop.systemd1.Manager " , None )
scs . StartUnit ( " (ss) " , unitname , " replace " )
2012-07-08 23:05:28 +04:00
time . sleep ( 2 )
2012-10-29 04:18:51 +04:00
logging . debug ( " Starting libvirtd appeared to succeed " )
2012-07-08 23:05:28 +04:00
return True
except :
logging . exception ( " Failed to talk to system-config-services " )