connection: Allow setting a custom 'pretty name' (bz 784701)
We've had multiple requests over the years for something similar. People might have to connect to multiple IP addresses, or really large hostnames, that become difficult to distinguish in the UI. Add a field in the host details page that allows setting a custom name, and store it in gsettings.
This commit is contained in:
parent
4781ad6cd6
commit
3d2afbaf6f
|
@ -27,6 +27,17 @@
|
|||
</key>
|
||||
</schema>
|
||||
|
||||
|
||||
<!-- Relocatable per conn schema -->
|
||||
<schema id="org.virt-manager.virt-manager.connection">
|
||||
<key name="pretty-name" type="s">
|
||||
<default>''</default>
|
||||
<summary>Custom connection description</summary>
|
||||
<description>Custom connection description, used in the manager window. If empty, the app generates a default on demand.</description>
|
||||
</key>
|
||||
</schema>
|
||||
|
||||
|
||||
<schema id="org.virt-manager.virt-manager"
|
||||
path="/org/virt-manager/virt-manager/">
|
||||
|
||||
|
|
101
ui/host.ui
101
ui/host.ui
|
@ -130,14 +130,12 @@
|
|||
<property name="can_focus">False</property>
|
||||
<property name="left_padding">20</property>
|
||||
<child>
|
||||
<object class="GtkTable" id="table1">
|
||||
<object class="GtkGrid" id="table1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="border_width">3</property>
|
||||
<property name="n_rows">4</property>
|
||||
<property name="n_columns">2</property>
|
||||
<property name="column_spacing">6</property>
|
||||
<property name="row_spacing">3</property>
|
||||
<property name="column_spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label6">
|
||||
<property name="visible">True</property>
|
||||
|
@ -146,10 +144,8 @@
|
|||
<property name="xalign">1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"/>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -160,10 +156,8 @@
|
|||
<property name="xalign">1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"/>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -177,10 +171,7 @@
|
|||
</object>
|
||||
<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="y_options"/>
|
||||
<property name="top_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -192,23 +183,20 @@
|
|||
</object>
|
||||
<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 name="top_attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label71">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Connection URI:</property>
|
||||
<property name="label" translatable="yes">Libvirt URI:</property>
|
||||
<property name="lines">1</property>
|
||||
<property name="xalign">1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"/>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -222,25 +210,7 @@
|
|||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"/>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label72">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">A_utoconnect:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="mnemonic_widget">config-autoconnect</property>
|
||||
<property name="xalign">1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"/>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -255,11 +225,48 @@
|
|||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"/>
|
||||
<property name="top_attach">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="overview-name">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="max_width_chars">30</property>
|
||||
<signal name="changed" handler="on_overview_name_changed" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label8">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">_Name:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="mnemonic_widget">overview-name</property>
|
||||
<property name="lines">1</property>
|
||||
<property name="xalign">1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label72">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">A_utoconnect:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="mnemonic_widget">config-autoconnect</property>
|
||||
<property name="xalign">1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
|
|
|
@ -50,15 +50,32 @@ class SettingsWrapper(object):
|
|||
return settingskey, value
|
||||
|
||||
def make_vm_settings(self, key):
|
||||
"""
|
||||
Initialize per-VM relocatable schema if necessary
|
||||
"""
|
||||
settingskey = self._parse_key(key)[0]
|
||||
|
||||
if settingskey in self._settingsmap:
|
||||
return True
|
||||
|
||||
schema = self._root + ".vm"
|
||||
path = "/" + self._root.replace(".", "/") + key.rsplit("/", 1)[0] + "/"
|
||||
self._settingsmap[settingskey] = Gio.Settings.new_with_path(schema,
|
||||
path)
|
||||
self._settingsmap[settingskey] = Gio.Settings.new_with_path(
|
||||
schema, path)
|
||||
return True
|
||||
|
||||
def make_conn_settings(self, key):
|
||||
"""
|
||||
Initialize per-conn relocatable schema if necessary
|
||||
"""
|
||||
settingskey = self._parse_key(key)[0]
|
||||
if settingskey in self._settingsmap:
|
||||
return True
|
||||
|
||||
schema = self._root + ".connection"
|
||||
path = "/" + self._root.replace(".", "/") + key.rsplit("/", 1)[0] + "/"
|
||||
print schema, path
|
||||
self._settingsmap[settingskey] = Gio.Settings.new_with_path(
|
||||
schema, path)
|
||||
return True
|
||||
|
||||
def _find_settings(self, key):
|
||||
|
@ -212,6 +229,11 @@ class vmmConfig(object):
|
|||
def get_objects(self):
|
||||
return self._objects[:]
|
||||
|
||||
|
||||
#####################################
|
||||
# Wrappers for setting per-VM value #
|
||||
#####################################
|
||||
|
||||
def _make_pervm_key(self, uuid, key):
|
||||
return "/vms/%s%s" % (uuid.replace("-", ""), key)
|
||||
|
||||
|
@ -232,6 +254,30 @@ class vmmConfig(object):
|
|||
return self.conf.get(key)
|
||||
|
||||
|
||||
########################################
|
||||
# Wrappers for setting per-conn values #
|
||||
########################################
|
||||
|
||||
def _make_perconn_key(self, uri, key):
|
||||
return "/conns/%s%s" % (uri.replace("/", ""), key)
|
||||
|
||||
def listen_perconn(self, uri, key, *args, **kwargs):
|
||||
key = self._make_perconn_key(uri, key)
|
||||
self.conf.make_conn_settings(key)
|
||||
return self.conf.notify_add(key, *args, **kwargs)
|
||||
|
||||
def set_perconn(self, uri, key, *args, **kwargs):
|
||||
key = self._make_perconn_key(uri, key)
|
||||
self.conf.make_conn_settings(key)
|
||||
ret = self.conf.set(key, *args, **kwargs)
|
||||
return ret
|
||||
|
||||
def get_perconn(self, uri, key):
|
||||
key = self._make_perconn_key(uri, key)
|
||||
self.conf.make_conn_settings(key)
|
||||
return self.conf.get(key)
|
||||
|
||||
|
||||
###################
|
||||
# General helpers #
|
||||
###################
|
||||
|
|
|
@ -191,6 +191,10 @@ class vmmConnection(vmmGObject):
|
|||
self.record = []
|
||||
self.hostinfo = None
|
||||
|
||||
self.add_gsettings_handle(
|
||||
self._on_config_pretty_name_changed(
|
||||
self._config_pretty_name_changed_cb))
|
||||
|
||||
self._init_virtconn()
|
||||
|
||||
|
||||
|
@ -368,6 +372,8 @@ class vmmConnection(vmmGObject):
|
|||
Return a pretty label for use in the manager view, and various
|
||||
connection lists.
|
||||
"""
|
||||
if self._get_config_pretty_name():
|
||||
return self._get_config_pretty_name()
|
||||
if self._backend.fake_name():
|
||||
return self._backend.fake_name()
|
||||
|
||||
|
@ -811,11 +817,6 @@ class vmmConnection(vmmGObject):
|
|||
# Connection closing/opening methods #
|
||||
######################################
|
||||
|
||||
def get_autoconnect(self):
|
||||
return self.config.get_conn_autoconnect(self.get_uri())
|
||||
def set_autoconnect(self, val):
|
||||
self.config.set_conn_autoconnect(self.get_uri(), val)
|
||||
|
||||
def _schedule_close(self):
|
||||
self._closing = True
|
||||
self.idle_add(self.close)
|
||||
|
@ -1351,3 +1352,23 @@ class vmmConnection(vmmGObject):
|
|||
return self.disk_read_rate() + self.disk_write_rate()
|
||||
def disk_io_max_rate(self):
|
||||
return self._get_record_helper("diskMaxRate")
|
||||
|
||||
|
||||
###########################
|
||||
# Per-conn config helpers #
|
||||
###########################
|
||||
|
||||
def get_autoconnect(self):
|
||||
return self.config.get_conn_autoconnect(self.get_uri())
|
||||
def set_autoconnect(self, val):
|
||||
self.config.set_conn_autoconnect(self.get_uri(), val)
|
||||
|
||||
def set_config_pretty_name(self, value):
|
||||
self.config.set_perconn(self.get_uri(), "/pretty-name", value)
|
||||
def _get_config_pretty_name(self):
|
||||
return self.config.get_perconn(self.get_uri(), "/pretty-name")
|
||||
def _on_config_pretty_name_changed(self, *args, **kwargs):
|
||||
return self.config.listen_perconn(self.get_uri(), "/pretty-name",
|
||||
*args, **kwargs)
|
||||
def _config_pretty_name_changed_cb(self):
|
||||
self.emit("state-changed")
|
||||
|
|
|
@ -60,9 +60,7 @@ class vmmHost(vmmGObjectUI):
|
|||
vmmGObjectUI.__init__(self, "host.ui", "vmm-host")
|
||||
self.conn = conn
|
||||
|
||||
self.title = conn.get_pretty_desc() + " " + self.topwin.get_title()
|
||||
self.topwin.set_title(self.title)
|
||||
|
||||
self._orig_title = self.topwin.get_title()
|
||||
self.ICON_RUNNING = "state_running"
|
||||
self.ICON_SHUTOFF = "state_shutoff"
|
||||
|
||||
|
@ -107,6 +105,7 @@ class vmmHost(vmmGObjectUI):
|
|||
"on_interface_apply_clicked" : (lambda *x: self.interface_apply()),
|
||||
"on_interface_list_changed": self.interface_selected,
|
||||
|
||||
"on_overview_name_changed": self._overview_name_changed,
|
||||
"on_config_autoconnect_toggled": self.toggle_autoconnect,
|
||||
|
||||
"on_qos_inbound_average_changed": (lambda *x:
|
||||
|
@ -325,6 +324,12 @@ class vmmHost(vmmGObjectUI):
|
|||
|
||||
def conn_state_changed(self, ignore1=None):
|
||||
conn_active = self.conn.is_active()
|
||||
|
||||
self.topwin.set_title(
|
||||
self.conn.get_pretty_desc() + " " + self._orig_title)
|
||||
if not self.widget("overview-name").has_focus():
|
||||
self.widget("overview-name").set_text(self.conn.get_pretty_desc())
|
||||
|
||||
self.widget("menu_file_restore_saved").set_sensitive(conn_active)
|
||||
self.widget("net-add").set_sensitive(conn_active and
|
||||
self.conn.is_network_capable())
|
||||
|
@ -356,13 +361,17 @@ class vmmHost(vmmGObjectUI):
|
|||
if self.addnet:
|
||||
self.addnet.close()
|
||||
|
||||
def _overview_name_changed(self, src):
|
||||
src = self.widget("overview-name")
|
||||
self.conn.set_config_pretty_name(src.get_text())
|
||||
|
||||
def toggle_autoconnect(self, src):
|
||||
self.conn.set_autoconnect(src.get_active())
|
||||
|
||||
|
||||
# -------------------------
|
||||
# Virtual Network functions
|
||||
# -------------------------
|
||||
#############################
|
||||
# Virtual Network functions #
|
||||
#############################
|
||||
|
||||
def delete_network(self, src_ignore):
|
||||
net = self.current_network()
|
||||
|
|
|
@ -804,10 +804,9 @@ class vmmManager(vmmGObjectUI):
|
|||
|
||||
it = model.iter_next(it)
|
||||
|
||||
def conn_state_changed(self, conn, newname=None):
|
||||
def conn_state_changed(self, conn):
|
||||
row = self.rows[conn.get_uri()]
|
||||
if newname:
|
||||
row[ROW_SORT_KEY] = newname
|
||||
row[ROW_SORT_KEY] = conn.get_pretty_desc()
|
||||
row[ROW_MARKUP] = self._build_conn_markup(conn, row[ROW_SORT_KEY])
|
||||
row[ROW_IS_CONN_CONNECTED] = not conn.is_disconnected()
|
||||
row[ROW_COLOR] = self._build_conn_color(conn)
|
||||
|
|
Loading…
Reference in New Issue