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