host: Allow renaming virtual networks
This commit is contained in:
parent
74e8fff069
commit
369a17160a
25
ui/host.ui
25
ui/host.ui
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.15.4 on Fri Sep 27 14:12:46 2013 -->
|
||||
<!-- Generated with glade 3.16.0 on Sun Sep 29 11:40:23 2013 -->
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 3.0 -->
|
||||
<object class="GtkAccelGroup" id="accelgroup1"/>
|
||||
|
@ -715,7 +715,7 @@
|
|||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">DNS Domain:</property>
|
||||
<property name="label" translatable="yes">Domain:</property>
|
||||
<property name="use_markup">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
|
@ -726,18 +726,29 @@
|
|||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="net-name">
|
||||
<object class="GtkLabel" id="label5">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label"><b>Name</b></property>
|
||||
<property name="use_markup">True</property>
|
||||
<property name="selectable">True</property>
|
||||
<property name="label" translatable="yes">Name:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
<property name="width">2</property>
|
||||
<property name="width">1</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="net-name">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<signal name="changed" handler="on_net_name_changed" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
<property name="width">1</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
|
|
@ -716,46 +716,12 @@ class vmmConnection(vmmGObject):
|
|||
# Libvirt object creation methods #
|
||||
###################################
|
||||
|
||||
def create_network(self, xml, start=True, autostart=True):
|
||||
# Define network
|
||||
net = self._backend.networkDefineXML(xml)
|
||||
|
||||
def restore(self, frm):
|
||||
self._backend.restore(frm)
|
||||
try:
|
||||
if start:
|
||||
net.create()
|
||||
net.setAutostart(autostart)
|
||||
os.remove(frm)
|
||||
except:
|
||||
net.undefine()
|
||||
raise
|
||||
|
||||
return net
|
||||
|
||||
def rename_vm(self, domainobj, origxml, newxml):
|
||||
# Undefine old domain
|
||||
domainobj.delete()
|
||||
|
||||
newobj = None
|
||||
try:
|
||||
try:
|
||||
# Redefine new domain
|
||||
newobj = self.define_domain(newxml)
|
||||
except Exception, renameerr:
|
||||
try:
|
||||
logging.exception("Error defining new name XML")
|
||||
newobj = self.define_domain(origxml)
|
||||
except Exception, fixerr:
|
||||
logging.exception("Failed to redefine original domain!")
|
||||
raise RuntimeError(
|
||||
_("Domain rename failed. Attempting to recover also "
|
||||
"failed.\n\n"
|
||||
"Original error: %s\n\n"
|
||||
"Recover error: %s" %
|
||||
(str(renameerr), str(fixerr))))
|
||||
raise
|
||||
finally:
|
||||
if newobj:
|
||||
# Reinsert handle into new domain
|
||||
domainobj.change_name_backend(newobj)
|
||||
logging.debug("Couldn't remove save file '%s' for restore", frm)
|
||||
|
||||
def define_domain(self, xml):
|
||||
return self._backend.defineXML(xml)
|
||||
|
@ -766,13 +732,53 @@ class vmmConnection(vmmGObject):
|
|||
def define_interface(self, xml):
|
||||
return self._backend.interfaceDefineXML(xml, 0)
|
||||
|
||||
def restore(self, frm):
|
||||
self._backend.restore(frm)
|
||||
def create_network(self, xml, start=True, autostart=True):
|
||||
net = self.define_network(xml)
|
||||
try:
|
||||
os.remove(frm)
|
||||
if start:
|
||||
net.create()
|
||||
net.setAutostart(autostart)
|
||||
except:
|
||||
logging.debug("Couldn't remove save file '%s' used for restore",
|
||||
frm)
|
||||
net.undefine()
|
||||
raise
|
||||
|
||||
return net
|
||||
|
||||
def _rename_helper(self, objtype, define_cb, obj, origxml, newxml):
|
||||
# Undefine the original object
|
||||
obj.delete()
|
||||
|
||||
newobj = None
|
||||
try:
|
||||
try:
|
||||
# Redefine new domain
|
||||
newobj = define_cb(newxml)
|
||||
except Exception, renameerr:
|
||||
try:
|
||||
logging.exception("Error defining new name %s XML",
|
||||
objtype)
|
||||
newobj = define_cb(origxml)
|
||||
except Exception, fixerr:
|
||||
logging.exception("Failed to redefine original %s!",
|
||||
objtype)
|
||||
raise RuntimeError(
|
||||
_("%s rename failed. Attempting to recover also "
|
||||
"failed.\n\n"
|
||||
"Original error: %s\n\n"
|
||||
"Recover error: %s" %
|
||||
(objtype, str(renameerr), str(fixerr))))
|
||||
raise
|
||||
finally:
|
||||
if newobj:
|
||||
# Reinsert handle into new obj
|
||||
obj.change_name_backend(newobj)
|
||||
|
||||
def rename_vm(self, obj, origxml, newxml):
|
||||
return self._rename_helper("domain", self.define_domain,
|
||||
obj, origxml, newxml)
|
||||
def rename_network(self, obj, origxml, newxml):
|
||||
return self._rename_helper("network", self.define_network,
|
||||
obj, origxml, newxml)
|
||||
|
||||
|
||||
####################
|
||||
|
|
|
@ -328,10 +328,6 @@ class vmmDomain(vmmLibvirtObject):
|
|||
def status(self):
|
||||
return self.lastStatus
|
||||
|
||||
def change_name_backend(self, newbackend):
|
||||
# Used for changing the domain object after a rename
|
||||
self._backend = newbackend
|
||||
|
||||
def get_cloning(self):
|
||||
return self.cloning
|
||||
def set_cloning(self, val):
|
||||
|
@ -399,29 +395,10 @@ class vmmDomain(vmmLibvirtObject):
|
|||
# Persistent XML change APIs #
|
||||
##############################
|
||||
|
||||
# Rename
|
||||
def define_name(self, newname):
|
||||
# Do this, so that _xmlobj_to_define has original inactive XML
|
||||
self._invalidate_xml()
|
||||
|
||||
guest = self._get_xmlobj_to_define()
|
||||
if guest.name == newname:
|
||||
return
|
||||
|
||||
if self.is_active():
|
||||
raise RuntimeError(_("Cannot rename an active guest"))
|
||||
|
||||
logging.debug("Changing guest name to '%s'", newname)
|
||||
origxml = guest.get_xml_config()
|
||||
guest.name = newname
|
||||
newxml = guest.get_xml_config()
|
||||
|
||||
try:
|
||||
self.conn.rename_vm(self, origxml, newxml)
|
||||
finally:
|
||||
self._invalidate_xml()
|
||||
|
||||
self.emit("config-changed")
|
||||
return self._define_name_helper("domain",
|
||||
self.conn.rename_vm,
|
||||
newname)
|
||||
|
||||
# Device Add/Remove
|
||||
def add_device(self, devobj):
|
||||
|
|
|
@ -43,6 +43,9 @@ from virtManager.graphwidgets import Sparkline
|
|||
INTERFACE_PAGE_INFO = 0
|
||||
INTERFACE_PAGE_ERROR = 1
|
||||
|
||||
(EDIT_NET_NAME,
|
||||
EDIT_NET_AUTOSTART) = range(2)
|
||||
|
||||
|
||||
class vmmHost(vmmGObjectUI):
|
||||
__gsignals__ = {
|
||||
|
@ -70,6 +73,8 @@ class vmmHost(vmmGObjectUI):
|
|||
self.volmenu = None
|
||||
self._in_refresh = False
|
||||
|
||||
self.net_active_edits = []
|
||||
|
||||
self.cpu_usage_graph = None
|
||||
self.memory_usage_graph = None
|
||||
self.init_conn_state()
|
||||
|
@ -91,9 +96,11 @@ class vmmHost(vmmGObjectUI):
|
|||
"on_net_delete_clicked": self.delete_network,
|
||||
"on_net_stop_clicked": self.stop_network,
|
||||
"on_net_start_clicked": self.start_network,
|
||||
"on_net_autostart_toggled": self.net_autostart_changed,
|
||||
"on_net_apply_clicked": self.net_apply,
|
||||
"on_net_list_changed": self.net_selected,
|
||||
"on_net_autostart_toggled": self.net_autostart_changed,
|
||||
"on_net_name_changed": (lambda *x:
|
||||
self.enable_net_apply(x, EDIT_NET_NAME)),
|
||||
|
||||
"on_pool_add_clicked" : self.add_pool,
|
||||
"on_vol_add_clicked" : self.add_vol,
|
||||
|
@ -462,19 +469,34 @@ class vmmHost(vmmGObjectUI):
|
|||
|
||||
logging.debug("Applying changes for network '%s'", net.get_name())
|
||||
try:
|
||||
auto = self.widget("net-autostart").get_active()
|
||||
net.set_autostart(auto)
|
||||
if EDIT_NET_AUTOSTART in self.net_active_edits:
|
||||
auto = self.widget("net-autostart").get_active()
|
||||
net.set_autostart(auto)
|
||||
if EDIT_NET_NAME in self.net_active_edits:
|
||||
net.define_name(self.widget("net-name").get_text())
|
||||
self.repopulate_networks()
|
||||
except Exception, e:
|
||||
self.err.show_err(_("Error setting net autostart: %s") % str(e))
|
||||
return
|
||||
finally:
|
||||
self.disable_net_apply()
|
||||
|
||||
def disable_net_apply(self):
|
||||
self.net_active_edits = []
|
||||
self.widget("net-apply").set_sensitive(False)
|
||||
|
||||
def enable_net_apply(self, *arglist):
|
||||
edittype = arglist[-1]
|
||||
self.widget("net-apply").set_sensitive(True)
|
||||
if edittype not in self.net_active_edits:
|
||||
self.net_active_edits.append(edittype)
|
||||
|
||||
def net_autostart_changed(self, src_ignore):
|
||||
auto = self.widget("net-autostart").get_active()
|
||||
self.widget("net-autostart").set_label(auto and
|
||||
_("On Boot") or
|
||||
_("Never"))
|
||||
self.widget("net-apply").set_sensitive(True)
|
||||
self.enable_net_apply(EDIT_NET_AUTOSTART)
|
||||
|
||||
def current_network(self):
|
||||
sel = self.widget("net-list").get_selection()
|
||||
|
@ -516,7 +538,7 @@ class vmmHost(vmmGObjectUI):
|
|||
try:
|
||||
net = self.conn.get_net(selected[0].get_value(selected[1], 0))
|
||||
except KeyError:
|
||||
self.widget("net-apply").set_sensitive(False)
|
||||
self.disable_net_apply()
|
||||
return
|
||||
except Exception, e:
|
||||
logging.exception(e)
|
||||
|
@ -527,8 +549,8 @@ class vmmHost(vmmGObjectUI):
|
|||
except Exception, e:
|
||||
logging.exception(e)
|
||||
self.set_net_error_page(_("Error selecting network: %s") % e)
|
||||
|
||||
self.widget("net-apply").set_sensitive(False)
|
||||
finally:
|
||||
self.disable_net_apply()
|
||||
|
||||
def _populate_net_ipv4_state(self, net):
|
||||
(netstr,
|
||||
|
@ -592,8 +614,8 @@ class vmmHost(vmmGObjectUI):
|
|||
active = net.is_active()
|
||||
|
||||
self.widget("net-details").set_sensitive(True)
|
||||
self.widget("net-name").set_markup(
|
||||
"<b>Network %s:</b>" % net.get_name())
|
||||
self.widget("net-name").set_text(net.get_name())
|
||||
self.widget("net-name").set_editable(not active)
|
||||
self.widget("net-device").set_text(net.get_bridge_device() or "")
|
||||
self.widget("net-name-domain").set_text(net.get_name_domain() or "")
|
||||
uihelpers.set_grid_row_visible(self.widget("net-name-domain"),
|
||||
|
@ -643,7 +665,7 @@ class vmmHost(vmmGObjectUI):
|
|||
self.widget("net-ipv6-route").set_text("")
|
||||
self.widget("net-ipv6-forwarding").set_text(
|
||||
_("Isolated network"))
|
||||
self.widget("net-apply").set_sensitive(False)
|
||||
self.disable_net_apply()
|
||||
|
||||
def repopulate_networks(self, src_ignore=None, uuid_ignore=None):
|
||||
self.populate_networks(self.widget("net-list").get_model())
|
||||
|
|
|
@ -78,6 +78,30 @@ class vmmLibvirtObject(vmmGObject):
|
|||
def get_key(self):
|
||||
return self._key
|
||||
|
||||
def change_name_backend(self, newbackend):
|
||||
# Used for changing the backing object after a rename
|
||||
self._backend = newbackend
|
||||
|
||||
def _define_name_helper(self, objtype, rename_cb, newname):
|
||||
oldname = self.get_xmlobj().name
|
||||
self._invalidate_xml()
|
||||
xmlobj = self._get_xmlobj_to_define()
|
||||
if xmlobj.name == newname:
|
||||
return
|
||||
|
||||
logging.debug("Changing %s name from %s to %s",
|
||||
objtype, oldname, newname)
|
||||
origxml = xmlobj.get_xml_config()
|
||||
xmlobj.name = newname
|
||||
newxml = xmlobj.get_xml_config()
|
||||
|
||||
try:
|
||||
rename_cb(self, origxml, newxml)
|
||||
finally:
|
||||
self._invalidate_xml()
|
||||
|
||||
self.emit("config-changed")
|
||||
|
||||
|
||||
#############################################################
|
||||
# Functions that should probably be overridden in sub class #
|
||||
|
|
|
@ -107,6 +107,11 @@ class vmmNetwork(vmmLibvirtObject):
|
|||
def tick(self):
|
||||
self._set_active(self._backend_get_active())
|
||||
|
||||
def define_name(self, newname):
|
||||
return self._define_name_helper("network",
|
||||
self.conn.rename_network,
|
||||
newname)
|
||||
|
||||
|
||||
###############
|
||||
# XML parsing #
|
||||
|
|
Loading…
Reference in New Issue