2013-10-28 00:59:46 +04:00
# Copyright (C) 2006, 2013 Red Hat, Inc.
2006-06-28 23:50:17 +04:00
# Copyright (C) 2006 Daniel P. Berrange <berrange@redhat.com>
#
2018-04-04 16:35:41 +03:00
# This work is licensed under the GNU GPLv2 or later.
2018-03-20 22:00:02 +03:00
# See the COPYING file in the top-level directory.
2006-06-28 23:50:17 +04:00
2015-04-06 23:43:44 +03:00
import glob
2014-01-27 02:42:24 +04:00
import os
2011-04-18 20:39:53 +04:00
import logging
2018-01-27 22:33:31 +03:00
import urllib . parse
2011-04-18 20:39:53 +04:00
2012-05-14 17:24:56 +04:00
from gi . repository import Gtk
2011-04-18 20:39:53 +04:00
2014-09-13 00:10:45 +04:00
from . import uiutil
from . baseclass import vmmGObjectUI
2018-03-16 04:22:14 +03:00
from . connmanager import vmmConnectionManager
2010-08-24 21:49:44 +04:00
2014-02-02 04:44:27 +04:00
( HV_QEMU ,
HV_XEN ,
HV_LXC ,
2014-04-10 21:54:37 +04:00
HV_QEMU_SESSION ,
2017-03-13 15:01:51 +03:00
HV_BHYVE ,
2018-01-10 00:02:51 +03:00
HV_VZ ,
HV_CUSTOM ) = range ( 7 )
2007-07-12 03:52:53 +04:00
2012-02-02 20:32:29 +04:00
2010-12-09 01:26:19 +03:00
class vmmConnect ( vmmGObjectUI ) :
2018-03-15 12:53:58 +03:00
@classmethod
def get_instance ( cls , parentobj ) :
try :
if not cls . _instance :
2018-03-17 23:08:20 +03:00
cls . _instance = vmmConnect ( )
2018-03-15 12:53:58 +03:00
return cls . _instance
except Exception as e :
parentobj . err . show_err (
_ ( " Error launching connect dialog: %s " ) % str ( e ) )
@classmethod
def is_initialized ( cls ) :
return bool ( cls . _instance )
2010-12-09 01:26:19 +03:00
def __init__ ( self ) :
2013-09-23 00:10:16 +04:00
vmmGObjectUI . __init__ ( self , " connect.ui " , " vmm-open-connection " )
2018-03-15 14:43:56 +03:00
self . _cleanup_on_app_close ( )
2006-06-14 18:59:40 +04:00
2013-02-16 22:31:46 +04:00
self . builder . connect_signals ( {
2010-08-24 21:49:44 +04:00
" on_hypervisor_changed " : self . hypervisor_changed ,
2010-08-24 22:56:03 +04:00
" on_connect_remote_toggled " : self . connect_remote_toggled ,
2010-08-24 23:36:06 +04:00
" on_username_entry_changed " : self . username_changed ,
2013-09-23 00:29:58 +04:00
" on_hostname_changed " : self . hostname_changed ,
2010-08-22 22:10:01 +04:00
2006-06-14 22:36:26 +04:00
" on_cancel_clicked " : self . cancel ,
2011-07-23 00:43:26 +04:00
" on_connect_clicked " : self . open_conn ,
2006-06-14 22:36:26 +04:00
" on_vmm_open_connection_delete_event " : self . cancel ,
2012-11-08 17:15:02 +04:00
} )
2006-06-14 18:59:40 +04:00
2010-08-24 22:56:03 +04:00
self . set_initial_state ( )
2008-09-02 19:36:56 +04:00
self . reset_state ( )
2007-07-12 03:52:53 +04:00
2014-01-27 02:42:24 +04:00
@staticmethod
2015-04-06 23:43:44 +03:00
def default_uri ( ) :
2014-01-27 02:42:24 +04:00
if os . path . exists ( ' /var/lib/xen ' ) :
if ( os . path . exists ( ' /dev/xen/evtchn ' ) or
os . path . exists ( " /proc/xen " ) ) :
return ' xen:/// '
if ( os . path . exists ( " /usr/bin/qemu " ) or
os . path . exists ( " /usr/bin/qemu-kvm " ) or
os . path . exists ( " /usr/bin/kvm " ) or
2015-04-06 23:43:44 +03:00
os . path . exists ( " /usr/libexec/qemu-kvm " ) or
glob . glob ( " /usr/bin/qemu-system-* " ) ) :
return " qemu:///system "
2014-12-04 13:08:57 +03:00
if ( os . path . exists ( " /usr/lib/libvirt/libvirt_lxc " ) or
os . path . exists ( " /usr/lib64/libvirt/libvirt_lxc " ) ) :
return " lxc:/// "
2014-01-27 02:42:24 +04:00
return None
2010-11-29 22:06:43 +03:00
def cancel ( self , ignore1 = None , ignore2 = None ) :
2012-02-01 03:16:54 +04:00
logging . debug ( " Cancelling open connection " )
2006-06-14 22:36:26 +04:00
self . close ( )
2006-06-14 18:59:40 +04:00
return 1
2011-04-28 22:38:16 +04:00
def close ( self , ignore1 = None , ignore2 = None ) :
2012-02-01 03:16:54 +04:00
logging . debug ( " Closing open connection " )
2010-11-30 22:33:21 +03:00
self . topwin . hide ( )
2014-02-01 18:39:52 +04:00
2006-06-14 22:36:26 +04:00
2018-03-16 04:22:14 +03:00
def show ( self , parent ) :
2012-02-01 03:16:54 +04:00
logging . debug ( " Showing open connection " )
2018-03-15 12:53:58 +03:00
if self . topwin . is_visible ( ) :
self . topwin . present ( )
return
2018-03-16 04:22:14 +03:00
self . reset_state ( )
2011-04-14 16:47:42 +04:00
self . topwin . set_transient_for ( parent )
self . topwin . present ( )
2008-09-02 19:36:56 +04:00
2011-07-24 05:16:54 +04:00
def _cleanup ( self ) :
pass
2010-08-24 22:56:03 +04:00
def set_initial_state ( self ) :
2011-07-14 21:13:13 +04:00
self . widget ( " connect " ) . grab_default ( )
2010-08-24 22:56:03 +04:00
2014-02-02 04:44:27 +04:00
combo = self . widget ( " hypervisor " )
2015-04-06 23:29:28 +03:00
# [connection ID, label]
model = Gtk . ListStore ( int , str )
def _add_hv_row ( rowid , config_name , label ) :
if ( not self . config . default_hvs or
2018-01-10 00:02:51 +03:00
not config_name or
2015-04-06 23:29:28 +03:00
config_name in self . config . default_hvs ) :
model . append ( [ rowid , label ] )
_add_hv_row ( HV_QEMU , " qemu " , " QEMU/KVM " )
2016-02-05 18:18:16 +03:00
_add_hv_row ( HV_QEMU_SESSION , " qemu " , " QEMU/KVM " + _ ( " user session " ) )
2015-04-06 23:29:28 +03:00
_add_hv_row ( HV_XEN , " xen " , " Xen " )
2016-02-05 18:18:16 +03:00
_add_hv_row ( HV_LXC , " lxc " , " LXC ( " + _ ( " Linux Containers " ) + " ) " )
2015-04-06 23:29:28 +03:00
_add_hv_row ( HV_BHYVE , " bhyve " , " Bhyve " )
2017-03-13 15:01:51 +03:00
_add_hv_row ( HV_VZ , " vz " , " Virtuozzo " )
2018-01-10 00:02:51 +03:00
_add_hv_row ( - 1 , None , " " )
_add_hv_row ( HV_CUSTOM , None , " Custom URI... " )
2014-02-02 04:44:27 +04:00
combo . set_model ( model )
2015-04-10 20:04:02 +03:00
uiutil . init_combo_text_column ( combo , 1 )
2018-01-10 00:02:51 +03:00
def sepfunc ( model , it ) :
return model [ it ] [ 0 ] == - 1
combo . set_row_separator_func ( sepfunc )
2014-02-02 04:44:27 +04:00
2008-09-02 19:36:56 +04:00
def reset_state ( self ) :
2009-03-10 05:58:05 +03:00
self . set_default_hypervisor ( )
2011-07-14 21:13:13 +04:00
self . widget ( " autoconnect " ) . set_sensitive ( True )
self . widget ( " autoconnect " ) . set_active ( True )
2018-10-07 03:55:31 +03:00
self . widget ( " hostname " ) . set_text ( " " )
2011-07-14 21:13:13 +04:00
self . widget ( " connect-remote " ) . set_active ( False )
self . widget ( " username-entry " ) . set_text ( " " )
2018-01-10 00:02:51 +03:00
self . widget ( " uri-entry " ) . set_text ( " " )
2011-07-14 21:13:13 +04:00
self . connect_remote_toggled ( self . widget ( " connect-remote " ) )
2010-08-24 21:49:44 +04:00
self . populate_uri ( )
2006-06-14 18:59:40 +04:00
2010-08-24 22:56:03 +04:00
def is_remote ( self ) :
# Whether user is requesting a remote connection
2011-07-14 21:13:13 +04:00
return self . widget ( " connect-remote " ) . get_active ( )
2010-08-24 22:56:03 +04:00
2009-03-10 05:58:05 +03:00
def set_default_hypervisor ( self ) :
2015-04-06 23:43:44 +03:00
default = self . default_uri ( )
2011-07-19 04:27:20 +04:00
if not default or default . startswith ( " qemu " ) :
2015-05-20 01:13:33 +03:00
uiutil . set_list_selection ( self . widget ( " hypervisor " ) , HV_QEMU )
2009-03-10 05:58:05 +03:00
elif default . startswith ( " xen " ) :
2015-05-20 01:13:33 +03:00
uiutil . set_list_selection ( self . widget ( " hypervisor " ) , HV_XEN )
2009-03-10 05:58:05 +03:00
2010-12-09 19:22:35 +03:00
def hostname_changed ( self , src_ignore ) :
2010-08-24 21:49:44 +04:00
self . populate_uri ( )
2014-02-02 04:44:27 +04:00
def hypervisor_changed ( self , src ) :
2015-08-09 21:01:22 +03:00
ignore = src
2015-08-09 19:27:20 +03:00
hv = uiutil . get_list_selection ( self . widget ( " hypervisor " ) )
2018-01-10 00:02:51 +03:00
is_session = hv == HV_QEMU_SESSION
is_custom = hv == HV_CUSTOM
show_remote = not is_session and not is_custom
2014-02-02 04:44:27 +04:00
uiutil . set_grid_row_visible (
self . widget ( " session-warning-box " ) , is_session )
uiutil . set_grid_row_visible (
2018-01-10 00:02:51 +03:00
self . widget ( " connect-remote " ) , show_remote )
2014-02-02 04:44:27 +04:00
uiutil . set_grid_row_visible (
2018-01-10 00:02:51 +03:00
self . widget ( " username-entry " ) , show_remote )
2014-02-02 04:44:27 +04:00
uiutil . set_grid_row_visible (
2018-01-10 00:02:51 +03:00
self . widget ( " hostname " ) , show_remote )
if not show_remote :
2014-02-02 04:44:27 +04:00
self . widget ( " connect-remote " ) . set_active ( False )
2018-01-10 00:02:51 +03:00
uiutil . set_grid_row_visible ( self . widget ( " uri-label " ) , not is_custom )
uiutil . set_grid_row_visible ( self . widget ( " uri-entry " ) , is_custom )
if is_custom :
2018-05-03 00:43:20 +03:00
label = self . widget ( " uri-label " ) . get_text ( )
self . widget ( " uri-entry " ) . set_text ( label )
2018-01-10 00:02:51 +03:00
self . widget ( " uri-entry " ) . grab_focus ( )
2010-08-24 21:49:44 +04:00
self . populate_uri ( )
2010-12-09 19:22:35 +03:00
def username_changed ( self , src_ignore ) :
2010-08-24 23:36:06 +04:00
self . populate_uri ( )
2010-12-09 19:22:35 +03:00
def connect_remote_toggled ( self , src_ignore ) :
2010-08-24 22:56:03 +04:00
is_remote = self . is_remote ( )
2011-07-14 21:13:13 +04:00
self . widget ( " hostname " ) . set_sensitive ( is_remote )
self . widget ( " autoconnect " ) . set_active ( not is_remote )
self . widget ( " username-entry " ) . set_sensitive ( is_remote )
2010-08-24 21:49:44 +04:00
2018-05-03 00:07:51 +03:00
if is_remote and not self . widget ( " username-entry " ) . get_text ( ) :
self . widget ( " username-entry " ) . set_text ( " root " )
2010-08-24 22:56:03 +04:00
self . populate_uri ( )
2010-08-24 21:49:44 +04:00
def populate_uri ( self ) :
uri = self . generate_uri ( )
2018-01-10 00:02:51 +03:00
self . widget ( " uri-label " ) . set_text ( uri )
2010-08-24 21:49:44 +04:00
def generate_uri ( self ) :
2015-05-20 00:17:53 +03:00
hv = uiutil . get_list_selection ( self . widget ( " hypervisor " ) )
2018-10-07 03:55:31 +03:00
host = self . widget ( " hostname " ) . get_text ( ) . strip ( )
2011-07-14 21:13:13 +04:00
user = self . widget ( " username-entry " ) . get_text ( )
2010-08-24 22:56:03 +04:00
is_remote = self . is_remote ( )
2006-06-14 18:59:40 +04:00
2010-08-24 21:49:44 +04:00
hvstr = " "
if hv == HV_XEN :
hvstr = " xen "
2014-02-17 19:22:24 +04:00
elif hv == HV_QEMU or hv == HV_QEMU_SESSION :
2010-08-24 21:49:44 +04:00
hvstr = " qemu "
2014-04-10 21:54:37 +04:00
elif hv == HV_BHYVE :
hvstr = " bhyve "
2017-03-13 15:01:51 +03:00
elif hv == HV_VZ :
hvstr = " vz "
2011-06-22 01:19:55 +04:00
else :
hvstr = " lxc "
2010-08-24 21:49:44 +04:00
2010-08-24 23:36:06 +04:00
addrstr = " "
if user :
2018-01-27 22:33:31 +03:00
addrstr + = urllib . parse . quote ( user ) + " @ "
2015-11-19 00:56:41 +03:00
if host . count ( " : " ) > 1 :
host = " [ %s ] " % host
2010-08-24 23:36:06 +04:00
addrstr + = host
2018-05-03 00:07:51 +03:00
if is_remote :
hoststr = " +ssh:// " + addrstr + " / "
2010-08-24 23:36:06 +04:00
else :
2018-05-03 00:07:51 +03:00
hoststr = " :/// "
2010-08-24 21:49:44 +04:00
uri = hvstr + hoststr
2017-03-13 15:01:51 +03:00
if hv in ( HV_QEMU , HV_BHYVE , HV_VZ ) :
2010-08-24 21:49:44 +04:00
uri + = " system "
2014-02-02 04:44:27 +04:00
elif hv == HV_QEMU_SESSION :
uri + = " session "
2010-08-24 21:49:44 +04:00
return uri
def validate ( self ) :
2010-08-24 22:56:03 +04:00
is_remote = self . is_remote ( )
2018-10-07 03:55:31 +03:00
host = self . widget ( " hostname " ) . get_text ( )
2010-08-24 21:49:44 +04:00
2010-08-24 22:56:03 +04:00
if is_remote and not host :
2010-08-24 21:49:44 +04:00
return self . err . val_err ( _ ( " A hostname is required for "
" remote connections. " ) )
return True
2018-03-16 04:22:14 +03:00
def _conn_open_completed ( self , conn , ConnectError ) :
if not ConnectError :
self . close ( )
self . reset_finish_cursor ( )
2018-03-17 01:00:09 +03:00
return
2018-03-16 04:22:14 +03:00
msg , details , title = ConnectError
msg + = " \n \n "
msg + = _ ( " Would you still like to remember this connection? " )
remember = self . err . show_err ( msg , details , title ,
buttons = Gtk . ButtonsType . YES_NO ,
dialog_type = Gtk . MessageType . QUESTION , modal = True )
self . reset_finish_cursor ( )
if remember :
self . close ( )
else :
vmmConnectionManager . get_instance ( ) . remove_conn ( conn . get_uri ( ) )
2011-07-23 00:43:26 +04:00
def open_conn ( self , ignore ) :
2010-08-24 21:49:44 +04:00
if not self . validate ( ) :
return
auto = False
2012-11-09 15:13:22 +04:00
if self . widget ( " autoconnect " ) . get_sensitive ( ) :
2018-03-16 04:22:14 +03:00
auto = bool ( self . widget ( " autoconnect " ) . get_active ( ) )
2018-01-10 00:02:51 +03:00
if self . widget ( " uri-label " ) . is_visible ( ) :
uri = self . generate_uri ( )
else :
uri = self . widget ( " uri-entry " ) . get_text ( )
2010-08-24 21:49:44 +04:00
2012-01-17 07:04:40 +04:00
logging . debug ( " Generate URI= %s , auto= %s " , uri , auto )
2018-03-16 04:22:14 +03:00
conn = vmmConnectionManager . get_instance ( ) . add_conn ( uri )
conn . set_autoconnect ( auto )
if conn . is_active ( ) :
return
2018-03-17 01:00:09 +03:00
conn . connect_once ( " open-completed " , self . _conn_open_completed )
2018-03-16 04:22:14 +03:00
self . set_finish_cursor ( )
conn . open ( )