[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[virt-tools-list] [PATCH 2/6] IPv6 support: update gui python processing



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 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


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]