Re-work connection dialog to support remote connections

This commit is contained in:
Daniel P. Berrange 2007-07-11 19:52:53 -04:00
parent 027bd68f68
commit 9de6fa68da
4 changed files with 251 additions and 295 deletions

View File

@ -20,6 +20,15 @@
import gobject
import gtk.glade
import os
import virtinst
import logging
HV_XEN = 0
HV_QEMU = 1
CONN_LOCAL = 0
CONN_TLS = 1
CONN_SSH = 2
class vmmConnect(gobject.GObject):
__gsignals__ = {
@ -28,27 +37,32 @@ class vmmConnect(gobject.GObject):
"cancelled": (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, ())
}
def __init__(self, config, engine):
self.__gobject_init__()
self.window = gtk.glade.XML(config.get_glade_dir() + "/vmm-open-connection.glade", "vmm-open-connection", domain="virt-manager")
self.engine = engine
self.window.get_widget("vmm-open-connection").hide()
# Not securely implemented yet by XenD/QEMU yet so disable it
self.window.get_widget("type-remote-host").set_sensitive(False)
self.window.get_widget("connect").grab_default()
self.window.signal_autoconnect({
"on_type_local_host_toggled": self.update_widget_states,
"on_type_remote_host_toggled": self.update_widget_states,
"on_type_hypervisor_changed": self.update_widget_states,
"on_connection_changed": self.update_widget_states,
"on_cancel_clicked": self.cancel,
"on_connect_clicked": self.open_connection,
"on_vmm_open_connection_delete_event": self.cancel,
})
self.window.get_widget("type-hypervisor").set_active(0)
default = virtinst.util.default_connection()
if default is None:
self.window.get_widget("hypervisor").set_active(-1)
elif default[0:3] == "xen":
self.window.get_widget("hypervisor").set_active(0)
elif default[0:4] == "qemu":
self.window.get_widget("hypervisor").set_active(1)
self.window.get_widget("connection").set_active(0)
self.window.get_widget("connect").grab_default()
def cancel(self,ignore1=None,ignore2=None):
self.close()
@ -63,39 +77,42 @@ class vmmConnect(gobject.GObject):
win.show_all()
win.present()
def update_widget_states(self, ignore=None):
type = self.window.get_widget("type-hypervisor")
local = self.window.get_widget("type-local-host")
remote = self.window.get_widget("type-remote-host")
if local.get_active():
self.window.get_widget("remote-host-options").set_sensitive(False)
def update_widget_states(self, src):
if src.get_active() > 0:
self.window.get_widget("hostname").set_sensitive(True)
else:
self.window.get_widget("remote-host-options").set_sensitive(True)
self.window.get_widget("hostname").set_sensitive(False)
def open_connection(self, src):
type = self.window.get_widget("type-hypervisor")
local = self.window.get_widget("type-local-host")
remote = self.window.get_widget("type-remote-host")
hv = self.window.get_widget("hypervisor").get_active()
conn = self.window.get_widget("connection").get_active()
host = self.window.get_widget("hostname").get_text()
uri = None
readOnly = None
if local.get_active():
if type.get_active() == 0:
uri = "xen"
if hv == -1:
pass
elif hv == HV_XEN:
if conn == CONN_LOCAL:
uri = "xen://"
if os.getuid() != 0:
readOnly = True
else:
elif conn == CONN_TLS:
uri = "xen+tls://" + host + "/"
elif conn == CONN_SSH:
uri = "xen+ssh://root@" + host + "/"
else:
if conn == CONN_LOCAL:
if os.getuid() == 0:
uri = "qemu:///system"
else:
uri = "qemu:///session"
else:
if type.get_active() == 0:
# XXX fixme these URIs should switch to the secure libvirtd when its finally written
uri = "http://" + self.window.get_widget("remote-host").get_text() + ":" + self.window.get_widget("remote-port").get_text()
else:
uri = "qemu://" + self.window.get_widget("remote-host").get_text() + ":" + self.window.get_widget("remote-port").get_text() + "/system"
elif conn == CONN_TLS:
uri = "qemu+tls://" + host + "/system"
elif conn == CONN_SSH:
uri = "qemu+ssh://root@" + host + "/system"
logging.debug("Connection to open is %s" % uri)
self.close()
self.emit("completed", uri, readOnly)

View File

@ -161,37 +161,47 @@ class vmmConnection(gobject.GObject):
def get_type(self):
return self.vmm.getType()
def get_hostname(self):
hostname = "localhost"
def get_local_hostname(self):
try:
(host, aliases, ipaddrs) = gethostbyaddr(gethostname())
hostname = host
return host
except:
logging.warning("Unable to resolve local hostname for machine")
if self.get_type()[0:3] == "Xen" and self.uri == "xen" or self.uri == "Xen" or self.uri is None:
return hostname
if self.get_type() == "QEMU" and ( self.uri == "qemu:///session" or self.uri == "qemu://system"):
return hostname
try:
urlbits = urlparse(self.uri)
return urlbits.netloc
except:
return hostname
return "localhost"
def get_name(self):
if self.get_type()[0:3] == "Xen":
return "Xen: " + self.get_hostname()
elif self.get_type() == "QEMU":
if self.uri == "qemu:///session":
return "QEMU session: " + self.get_hostname()
else:
return "QEMU system: " + self.get_hostname()
else:
return self.get_type() + ":" + self.get_hostname()
try:
(scheme, netloc, path, query, fragment) = self.uri_split()
i = scheme.find("+")
if i > 0:
scheme = scheme[0:i]
if netloc == "":
netloc = self.get_local_hostname()
if scheme == "xen":
return "Xen on %s" % netloc
elif scheme == "qemu":
if path == "/session":
return "QEMU session on %s" % netloc
else:
return "QEMU system on %s" % netloc
elif scheme == "test":
return "Test on %s" % netloc
except Exception, e:
logging.warning("Cannot parse URI %s: %s" % (self.uri, str(e)))
return self.uri
def is_remote(self):
try:
(scheme, netloc, path, query, fragment) = self.uri_split()
if netloc == "":
return False
return True
except:
return True
def get_uri(self):
return self.uri
@ -578,5 +588,36 @@ class vmmConnection(gobject.GObject):
uuid.append('-')
return "".join(uuid)
# Standard python urlparse is utterly braindead - refusing to parse URIs
# in any useful fashion unless the 'scheme' is in some pre-defined white
# list. Theis functions is a hacked version of urlparse
def uri_split(self):
uri = self.uri
netloc = query = fragment = ''
i = uri.find(":")
if i > 0:
scheme, uri = uri[:i].lower(), uri[i+1:]
if uri[:2] == '//':
netloc, uri = self._splitnetloc(uri, 2)
if '#' in uri:
uri, fragment = uri.split('#', 1)
if '?' in uri:
uri, query = uri.split('?', 1)
else:
scheme = uri.lower()
return scheme, netloc, uri, query, fragment
def _splitnetloc(self, url, start=0):
for c in '/?#': # the order is important!
delim = url.find(c, start)
if delim >= 0:
break
else:
delim = len(url)
return url[start:delim], url[delim:]
gobject.type_register(vmmConnection)

View File

@ -143,258 +143,156 @@
</child>
<child>
<widget class="GtkVBox" id="vbox12">
<widget class="GtkTable" id="table1">
<property name="border_width">6</property>
<property name="visible">True</property>
<property name="n_rows">3</property>
<property name="n_columns">2</property>
<property name="homogeneous">False</property>
<property name="spacing">3</property>
<property name="row_spacing">3</property>
<property name="column_spacing">3</property>
<child>
<widget class="GtkAlignment" id="alignment12">
<widget class="GtkEntry" id="hostname">
<property name="visible">True</property>
<property name="xalign">0.5</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char">•</property>
<property name="activates_default">False</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkComboBox" id="connection">
<property name="visible">True</property>
<property name="items" translatable="yes">Local
Remote SSL/TLS with x509 certificate
Remote tunnel over SSH</property>
<property name="add_tearoffs">False</property>
<property name="focus_on_click">True</property>
<signal name="changed" handler="on_connection_changed" last_modification_time="Wed, 11 Jul 2007 22:34:03 GMT"/>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">fill</property>
<property name="y_options">fill</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label89">
<property name="visible">True</property>
<property name="label" translatable="yes">Hostname:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">1</property>
<property name="yalign">0.5</property>
<property name="xscale">0.5</property>
<property name="yscale">1</property>
<property name="top_padding">3</property>
<property name="bottom_padding">0</property>
<property name="left_padding">0</property>
<property name="right_padding">0</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox13">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkLabel" id="label88">
<property name="visible">True</property>
<property name="label" translatable="yes">Connection:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">1</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label87">
<property name="visible">True</property>
<property name="label" translatable="yes">Hypervisor:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">1</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label87">
<property name="visible">True</property>
<property name="label" translatable="yes">Hypervisor:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">1</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkComboBox" id="type-hypervisor">
<property name="visible">True</property>
<property name="items" translatable="yes">Xen
<child>
<widget class="GtkComboBox" id="hypervisor">
<property name="visible">True</property>
<property name="items" translatable="yes">Xen
QEMU</property>
<property name="add_tearoffs">False</property>
<property name="focus_on_click">True</property>
<signal name="changed" handler="on_type_hypervisor_changed" last_modification_time="Mon, 19 Feb 2007 22:04:06 GMT"/>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
</child>
<property name="add_tearoffs">False</property>
<property name="focus_on_click">True</property>
<signal name="changed" handler="on_type_hypervisor_changed" last_modification_time="Mon, 19 Feb 2007 22:04:06 GMT"/>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkHSeparator" id="hseparator3">
<property name="visible">True</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkVBox" id="vbox12">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkRadioButton" id="type-local-host">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">_Local host</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="active">False</property>
<property name="inconsistent">False</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_type_local_host_toggled" last_modification_time="Mon, 19 Feb 2007 22:04:15 GMT"/>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkRadioButton" id="type-remote-host">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">_Remote host</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="active">False</property>
<property name="inconsistent">False</property>
<property name="draw_indicator">True</property>
<property name="group">type-local-host</property>
<signal name="toggled" handler="on_type_remote_host_toggled" last_modification_time="Mon, 19 Feb 2007 22:04:21 GMT"/>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkTable" id="remote-host-options">
<property name="border_width">3</property>
<property name="visible">True</property>
<property name="n_rows">1</property>
<property name="n_columns">4</property>
<property name="homogeneous">False</property>
<property name="row_spacing">3</property>
<property name="column_spacing">3</property>
<child>
<widget class="GtkEntry" id="remote-xen-port">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char">*</property>
<property name="activates_default">False</property>
</widget>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="remote-xen-host">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char">*</property>
<property name="activates_default">False</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label84">
<property name="visible">True</property>
<property name="label" translatable="yes">_Port:</property>
<property name="use_underline">True</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="mnemonic_widget">remote-xen-port</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label85">
<property name="visible">True</property>
<property name="label" translatable="yes">_Host:</property>
<property name="use_underline">True</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="mnemonic_widget">remote-xen-host</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="x_options">fill</property>
<property name="y_options">fill</property>
</packing>
</child>
</widget>

View File

@ -21,7 +21,7 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
Requires: pygtk2 >= 1.99.12-6
Requires: gnome-python2-gconf >= 1.99.11-7
# Absolutely require this version or newer
Requires: libvirt-python >= 0.2.0-1
Requires: libvirt-python >= 0.3.0-1
# Definitely does not work with earlier due to python API changes
Requires: dbus-python >= 0.61
# Might work with earlier, but this is what we've tested