[virt-tools-list] [PATCH 2/6] IPv6 support: update gui python processing
Gene Czarcinski
gene at czarc.net
Tue Mar 26 11:05:57 UTC 2013
Update the gui processing programs. Some of this is
also used by the Tui interface. With this patch, all needs for
IPy.py in the gui portion of virt-manager have been removed and
replaced with ipaddr from the prython-ipaddr package. These updates
also implement network display.
Currently, createnet.py only handles IPv4 network
creation.
Signed-off-by: Gene Czarcinski <gene at czarc.net>
---
virtManager/createnet.py | 67 +++++++++++----------
virtManager/host.py | 32 +++++++++-
virtManager/network.py | 151 +++++++++++++++++++++++++++++++++++++----------
3 files changed, 184 insertions(+), 66 deletions(-)
diff --git a/virtManager/createnet.py b/virtManager/createnet.py
index 79dd249..846cfbf 100644
--- a/virtManager/createnet.py
+++ b/virtManager/createnet.py
@@ -21,7 +21,7 @@
import logging
import re
-from IPy import IP
+import ipaddr
from gi.repository import Gtk
from gi.repository import Gdk
@@ -153,7 +153,7 @@ class vmmCreateNetwork(vmmGObjectUI):
src.modify_text(Gtk.StateType.NORMAL, black)
# No IP specified or invalid IP
- if ip is None or ip.version() != 4:
+ if ip is None or ip.version != 4:
src.modify_base(Gtk.StateType.NORMAL, red)
self.widget("net-info-netmask").set_text("")
self.widget("net-info-broadcast").set_text("")
@@ -162,26 +162,25 @@ class vmmCreateNetwork(vmmGObjectUI):
self.widget("net-info-type").set_text("")
return
+ # FIXME: handle other networks and not just private?
# We've got a valid IP
- if ip.len() < 4 or ip.iptype() != "PRIVATE":
- src.modify_base(Gtk.StateType.NORMAL, red)
+ if ip.numhosts < 16 or not ip.is_private:
+ src.modify_base(gtk.STATE_NORMAL, red)
else:
src.modify_base(Gtk.StateType.NORMAL, green)
- self.widget("net-info-netmask").set_text(str(ip.netmask()))
- self.widget("net-info-broadcast").set_text(str(ip.broadcast()))
+ self.widget("net-info-netmask").set_text(str(ip.netmask))
+ self.widget("net-info-broadcast").set_text(str(ip.broadcast))
- if ip.len() <= 1:
+ if ip.prefixlen == 32:
self.widget("net-info-gateway").set_text("")
else:
- self.widget("net-info-gateway").set_text(str(ip[1]))
+ self.widget("net-info-gateway").set_text(str(ip.network + 1))
self.widget("net-info-size").set_text(_("%d addresses") %
- (ip.len()))
+ (ip.numhosts))
- if ip.iptype() == "PUBLIC":
- self.widget("net-info-type").set_text(_("Public"))
- elif ip.iptype() == "PRIVATE":
+ if ip.is_private:
self.widget("net-info-type").set_text(_("Private"))
- elif ip.iptype() == "RESERVED":
+ elif ip.is_reserved:
self.widget("net-info-type").set_text(_("Reserved"))
else:
self.widget("net-info-type").set_text(_("Other"))
@@ -192,8 +191,8 @@ class vmmCreateNetwork(vmmGObjectUI):
self.widget("net-dhcp-end").set_sensitive(val)
def change_dhcp_start(self, src):
- end = self.get_config_dhcp_start()
- self.change_dhcp(src, end)
+ start = self.get_config_dhcp_start()
+ self.change_dhcp(src, start)
def change_dhcp_end(self, src):
end = self.get_config_dhcp_end()
@@ -222,18 +221,18 @@ class vmmCreateNetwork(vmmGObjectUI):
def get_config_ip4(self):
try:
- return IP(self.widget("net-network").get_text())
+ return ipaddr.IPNetwork(self.widget("net-network").get_text())
except:
return None
def get_config_dhcp_start(self):
try:
- return IP(self.widget("net-dhcp-start").get_text())
+ return ipaddr.IPNetwork(self.widget("net-dhcp-start").get_text())
except:
return None
def get_config_dhcp_end(self):
try:
- return IP(self.widget("net-dhcp-end").get_text())
+ return ipaddr.IPNetwork(self.widget("net-dhcp-end").get_text())
except:
return None
@@ -260,16 +259,16 @@ class vmmCreateNetwork(vmmGObjectUI):
ip = self.get_config_ip4()
self.widget("summary-ip4-network").set_text(str(ip))
- self.widget("summary-ip4-gateway").set_text(str(ip[1]))
- self.widget("summary-ip4-netmask").set_text(str(ip.netmask()))
+ self.widget("summary-ip4-gateway").set_text(str(ip.network + 1))
+ self.widget("summary-ip4-netmask").set_text(str(ip.netmask))
self.widget("label-dhcp-end").set_property("visible", dodhcp)
self.widget("summary-dhcp-end").set_property("visible", dodhcp)
if dodhcp:
start = self.get_config_dhcp_start()
end = self.get_config_dhcp_end()
- self.widget("summary-dhcp-start").set_text(str(start))
- self.widget("summary-dhcp-end").set_text(str(end))
+ self.widget("summary-dhcp-start").set_text(str(start.network))
+ self.widget("summary-dhcp-end").set_text(str(end.network))
self.widget("label-dhcp-start").set_text(_("Start address:"))
self.widget("label-dhcp-end").show()
self.widget("summary-dhcp-end").show()
@@ -284,13 +283,13 @@ class vmmCreateNetwork(vmmGObjectUI):
def populate_dhcp(self):
ip = self.get_config_ip4()
- start = int(ip.len() / 2)
- end = ip.len() - 2
+ start = int(ip.numhosts / 2)
+ end = int(ip.numhosts - 2)
if self.widget("net-dhcp-start").get_text() == "":
- self.widget("net-dhcp-start").set_text(str(ip[start]))
+ self.widget("net-dhcp-start").set_text(str(ip.network + start))
if self.widget("net-dhcp-end").get_text() == "":
- self.widget("net-dhcp-end").set_text(str(ip[end]))
+ self.widget("net-dhcp-end").set_text(str(ip.network + end))
def page_changed(self, ignore1, ignore2, page_number):
if page_number == PAGE_NAME:
@@ -331,13 +330,13 @@ class vmmCreateNetwork(vmmGObjectUI):
else:
xml += " <forward mode='%s'/>\n" % mode
- xml += " <ip address='%s' netmask='%s'>\n" % (str(ip[1]),
- str(ip.netmask()))
+ xml += " <ip address='%s' netmask='%s'>\n" % (str(ip.network + 1),
+ str(ip.netmask))
if self.get_config_dhcp_enable():
xml += " <dhcp>\n"
- xml += " <range start='%s' end='%s'/>\n" % (str(start),
- str(end))
+ xml += " <range start='%s' end='%s'/>\n" % (str(start.network),
+ str(end.network))
xml += " </dhcp>\n"
xml += " </ip>\n"
@@ -372,15 +371,15 @@ class vmmCreateNetwork(vmmGObjectUI):
return self.err.val_err(_("Invalid Network Address"),
_("The network address could not be understood"))
- if ip.version() != 4:
+ if ip.version != 4:
return self.err.val_err(_("Invalid Network Address"),
_("The network must be an IPv4 address"))
- if ip.len() < 4:
+ if ip.numhosts < 16:
return self.err.val_err(_("Invalid Network Address"),
- _("The network prefix must be at least /4 (16 addresses)"))
+ _("The network prefix must be at least /28 (16 addresses)"))
- if ip.iptype() != "PRIVATE":
+ if not ip.is_private:
res = self.err.yes_no(_("Check Network Address"),
_("The network should normally use a private IPv4 "
"address. Use this non-private address anyway?"))
diff --git a/virtManager/host.py b/virtManager/host.py
index ff50f82..e4502b6 100644
--- a/virtManager/host.py
+++ b/virtManager/host.py
@@ -544,14 +544,37 @@ class vmmHost(vmmGObjectUI):
self.widget("net-autostart").set_active(autostart)
self.widget("net-autostart").set_label(autolabel)
- network = net.get_ipv4_network()
+ result = net.get_ipv4_network()
+ network = result[0]
+ dhcp = result[1]
+ route = result[2]
self.widget("net-ip4-network").set_text(str(network))
- dhcp = net.get_ipv4_dhcp_range()
start = dhcp and str(dhcp[0]) or _("Disabled")
end = dhcp and str(dhcp[1]) or _("Disabled")
self.widget("net-ip4-dhcp-start").set_text(start)
self.widget("net-ip4-dhcp-end").set_text(end)
+ if route and route[0] and route[1]:
+ routeVia = str(route[0]) + " via " + str(route[1])
+ else:
+ routeVia = _("None")
+ self.widget("net-ip4-route-via").set_text(routeVia)
+
+ result = net.get_ipv6_network()
+ network = result[0]
+ dhcp = result[1]
+ route = result[2]
+ self.widget("net-ip6-network").set_text(str(network))
+
+ start = dhcp and str(dhcp[0]) or _("Disabled")
+ end = dhcp and str(dhcp[1]) or _("Disabled")
+ self.widget("net-ip6-dhcp-start").set_text(start)
+ self.widget("net-ip6-dhcp-end").set_text(end)
+ if route and route[0] and route[1]:
+ routeVia = str(route[0]) + " via " + str(route[1])
+ else:
+ routeVia = "None"
+ self.widget("net-ip6-route-via").set_text(routeVia)
forward, ignore = net.get_ipv4_forward()
iconsize = Gtk.IconSize.MENU
@@ -579,10 +602,15 @@ class vmmHost(vmmGObjectUI):
self.widget("net-ip4-network").set_text("")
self.widget("net-ip4-dhcp-start").set_text("")
self.widget("net-ip4-dhcp-end").set_text("")
+ self.widget("net-ip4-route-via").set_text("")
self.widget("net-ip4-forwarding-icon").set_from_stock(
Gtk.STOCK_DISCONNECT, Gtk.IconSize.MENU)
self.widget("net-ip4-forwarding").set_text(
_("Isolated virtual network"))
+ self.widget("net-ip6-network").set_text("")
+ self.widget("net-ip6-dhcp-start").set_text("")
+ self.widget("net-ip6-dhcp-end").set_text("")
+ self.widget("net-ip6-route-via").set_text("")
self.widget("net-apply").set_sensitive(False)
def repopulate_networks(self, src_ignore, uuid_ignore):
diff --git a/virtManager/network.py b/virtManager/network.py
index 13a16e3..3d85799 100644
--- a/virtManager/network.py
+++ b/virtManager/network.py
@@ -18,9 +18,9 @@
# MA 02110-1301 USA.
#
-from IPy import IP
-
from virtManager import util
+import ipaddr
+import libxml2
from virtManager.libvirtobject import vmmLibvirtObject
class vmmNetwork(vmmLibvirtObject):
@@ -97,27 +97,127 @@ class vmmNetwork(vmmLibvirtObject):
return self.net.autostart()
def get_ipv4_network(self):
+ doc = None
+ ret = None
+ goodNode = None
+ dhcpstart = None
+ dhcpend = None
+ routeAddr = None
+ routeVia = None
xml = self.get_xml()
- if util.xpath(xml, "/network/ip") is None:
- return None
- addrStr = util.xpath(xml, "/network/ip/@address")
- netmaskStr = util.xpath(xml, "/network/ip/@netmask")
- prefix = util.xpath(xml, "/network/ip/@prefix")
-
- if prefix:
- prefix = int(prefix)
- binstr = ((prefix * "1") + ((32 - prefix) * "0"))
- netmaskStr = str(IP(int(binstr, base=2)))
-
- if netmaskStr:
- netmask = IP(netmaskStr)
- gateway = IP(addrStr)
- network = IP(gateway.int() & netmask.int())
- ret = IP(str(network) + "/" + netmaskStr)
+ doc = libxml2.parseDoc(xml)
+ nodes = doc.xpathEval('//ip')
+ for node in nodes:
+ family = node.xpathEval('string(./@family)')
+ if not family or family == 'ipv4':
+ dhcp = node.xpathEval('string(./dhcp)')
+ if dhcp:
+ dhcpstart = node.xpathEval('string(./dhcp/range[1]/@start)')
+ dhcpend = node.xpathEval('string(./dhcp/range[1]/@end)')
+ goodNode = node
+ break
+
+ for node in nodes:
+ family = node.xpathEval('string(./@family)')
+ if not family or family == 'ipv4':
+ routeVia = node.xpathEval('string(./@via)')
+ if routeVia:
+ routeAddr = node.xpathEval('string(./@address)')
+ break;
+
+ if goodNode == None:
+ for node in nodes:
+ family = node.xpathEval('string(./@family)')
+ if not family or family == 'ipv4':
+ tmp = node.xpathEval('string(./@via)')
+ if tmp:
+ continue
+ goodNode = node;
+ break
+
+ if goodNode:
+ addrStr = goodNode.xpathEval('string(./@address)')
+ netmaskStr = goodNode.xpathEval('string(./@netmask)')
+ prefix = goodNode.xpathEval('string(./@prefix)')
+ if prefix:
+ prefix = int(prefix)
+ ret = str(ipaddr.IPNetwork(str(addrStr) + "/" + str(prefix)).masked())
+ elif netmaskStr:
+ netmask = ipaddr.IPAddress(netmaskStr)
+ network = ipaddr.IPAddress(addrStr)
+ ret = str(ipaddr.IPNetwork(str(network) + "/" + str(netmask)).masked())
+ else:
+ ret = str(ipaddr.IPNetwork(str(addrStr)))
+ if doc:
+ doc.freeDoc()
+ if dhcpstart and dhcpend:
+ dhcp = [str(ipaddr.IPAddress(dhcpstart)), str(ipaddr.IPAddress(dhcpend))]
else:
- ret = IP(str(addrStr))
-
- return ret
+ dhcp = None
+ if routeAddr and routeVia:
+ route = [str(ipaddr.IPAddress(routeAddr)), str(ipaddr.IPAddress(routeVia))]
+ else:
+ route = None
+ return [ret, dhcp, route]
+
+ def get_ipv6_network(self):
+ doc = None
+ ret = None
+ goodNode = None
+ dhcpstart = None
+ dhcpend = None
+ routeAddr = None
+ routeVia = None
+ xml = self.get_xml()
+ doc = libxml2.parseDoc(xml)
+ nodes = doc.xpathEval('//ip')
+ for node in nodes:
+ family = node.xpathEval('string(./@family)')
+ if family and family == 'ipv6':
+ dhcp = node.xpathEval('string(./dhcp)')
+ if dhcp:
+ dhcpstart = node.xpathEval('string(./dhcp/range[1]/@start)')
+ dhcpend = node.xpathEval('string(./dhcp/range[1]/@end)')
+ goodNode = node
+ break
+
+ for node in nodes:
+ family = node.xpathEval('string(./@family)')
+ if family and family == 'ipv6':
+ routeVia = node.xpathEval('string(./@via)')
+ if routeVia:
+ routeAddr = node.xpathEval('string(./@address)')
+ break;
+
+ if goodNode == None:
+ for node in nodes:
+ family = node.xpathEval('string(./@family)')
+ if family and family == 'ipv6':
+ tmp = node.xpathEval('string(./@via)')
+ if tmp:
+ continue
+ goodNode = node;
+ break
+
+ if goodNode:
+ addrStr = goodNode.xpathEval('string(./@address)')
+ prefix = goodNode.xpathEval('string(./@prefix)')
+ if prefix:
+ prefix = int(prefix)
+ ret = str(ipaddr.IPNetwork(str(addrStr) + "/" + str(prefix)).masked())
+ else:
+ ret = str(ipaddr.IPNetwork(str(addrStr)))
+ if doc:
+ doc.freeDoc()
+ if dhcpstart and dhcpend:
+ dhcp = [str(ipaddr.IPAddress(dhcpstart)), str(ipaddr.IPAddress(dhcpend))]
+ else:
+ dhcp = None
+ if routeAddr and routeVia:
+ route = [str(ipaddr.IPAddress(routeAddr)), str(ipaddr.IPAddress(routeVia))]
+ else:
+ route = None
+ return [ret, dhcp, route]
def get_ipv4_forward(self):
xml = self.get_xml()
@@ -125,15 +225,6 @@ class vmmNetwork(vmmLibvirtObject):
forwardDev = util.xpath(xml, "/network/forward/@dev")
return [fw, forwardDev]
- def get_ipv4_dhcp_range(self):
- xml = self.get_xml()
- dhcpstart = util.xpath(xml, "/network/ip/dhcp/range[1]/@start")
- dhcpend = util.xpath(xml, "/network/ip/dhcp/range[1]/@end")
- if not dhcpstart or not dhcpend:
- return None
-
- return [IP(dhcpstart), IP(dhcpend)]
-
def pretty_forward_mode(self):
forward, forwardDev = self.get_ipv4_forward()
return vmmNetwork.pretty_desc(forward, forwardDev)
--
1.8.1.4
More information about the virt-tools-list
mailing list