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@xxxxxxxxx> --- 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 _______________________________________________ virt-tools-list mailing list virt-tools-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/virt-tools-list