IPv6 support v2: update the create network wizard

With this patch, basic IPv6 support has been added to
the network creation wizard.  It includes changes to
both the glade-3 ui and the related python code.  There
have been some significant changes made to both files for
IPv6 support and some additional capabilities.

This update includes the fix so color will work in the
network creation wizard.

Besides basic IPv6 support, this includes optionally
specifying a DNS domain name and enabling IPv6 internal
routing if no IPv6 address is specified.
.
Signed-off-by: Gene Czarcinski <gene@czarc.net>
This commit is contained in:
Gene Czarcinski 2013-03-29 14:38:29 -04:00 committed by Cole Robinson
parent 73629b76b2
commit 61f8e39700
2 changed files with 2027 additions and 721 deletions

File diff suppressed because it is too large Load Diff

View File

@ -32,8 +32,8 @@ from virtManager.baseclass import vmmGObjectUI
PAGE_INTRO = 0
PAGE_NAME = 1
PAGE_IPV4 = 2
PAGE_DHCP = 3
PAGE_FORWARDING = 4
PAGE_IPV6 = 3
PAGE_MISC = 4
PAGE_SUMMARY = 5
@ -52,10 +52,16 @@ class vmmCreateNetwork(vmmGObjectUI):
"on_net_name_activate": self.forward,
"on_net_forward_toggled" : self.change_forward_type,
"on_net_network_changed": self.change_network,
"on_net_dhcp_enable_toggled": self.change_dhcp_enable,
"on_net_dhcp_start_changed": self.change_dhcp_start,
"on_net_dhcp_end_changed": self.change_dhcp_end,
"on_net-ipv4-enable_toggled" : self.change_ipv4_enable,
"on_net-ipv4-network_changed": self.change_network,
"on_net-dhcpv4-enable_toggled": self.change_dhcpv4_enable,
"on_net-dhcpv4-start_changed": self.change_dhcpv4_start,
"on_net-dhcpv4-end_changed": self.change_dhcpv4_end,
"on_net-ipv6-enable_toggled" : self.change_ipv6_enable,
"on_net-ipv6-network_changed": self.change_ipv6_network,
"on_net-dhcpv6-enable_toggled": self.change_dhcpv6_enable,
"on_net-dhcpv6-start_changed": self.change_dhcpv6_start,
"on_net-dhcpv6-end_changed": self.change_dhcpv6_end,
})
self.bind_escape_key_close()
@ -86,7 +92,7 @@ class vmmCreateNetwork(vmmGObjectUI):
notebook = self.widget("create-pages")
notebook.set_show_tabs(False)
black = Gdk.Color.parse("#000")[1]
black = Gdk.Color.parse("#000")[1]
for num in range(PAGE_SUMMARY + 1):
name = "page" + str(num) + "-title"
self.widget(name).modify_bg(Gtk.StateType.NORMAL, black)
@ -123,14 +129,28 @@ class vmmCreateNetwork(vmmGObjectUI):
self.page_changed(None, None, 0)
self.widget("net-name").set_text("")
self.widget("net-network").set_text("192.168.100.0/24")
self.widget("net-dhcp-enable").set_active(True)
self.widget("net-dhcp-start").set_text("")
self.widget("net-dhcp-end").set_text("")
self.widget("net-name").set_sensitive(True)
self.widget("net-domain-name").set_text("")
self.widget("net-domain-name").set_sensitive(True)
self.widget("net-ipv4-enable").set_active(True)
self.widget("net-ipv4-network").set_text("192.168.100.0/24")
self.widget("net-ipv4-network").set_sensitive(True)
self.widget("net-dhcpv4-enable").set_active(True)
self.widget("net-dhcpv4-start").set_text("192.168.100.128")
self.widget("net-dhcpv4-end").set_text("192.168.100.254")
self.widget("net-dhcpv4-start").set_sensitive(True)
self.widget("net-dhcpv4-end").set_sensitive(True)
self.widget("net-ipv6-enable").set_active(False)
self.widget("net-ipv6-network").set_text("")
self.widget("net-ipv6-network").set_sensitive(True)
self.widget("net-dhcpv6-enable").set_active(False)
self.widget("net-dhcpv6-start").set_text("")
self.widget("net-dhcpv6-end").set_text("")
self.widget("net-forward-none").set_active(True)
self.widget("net-forward").set_active(0)
self.widget("net-forward-mode").set_active(0)
self.widget("net-enable-ipv6-networking").set_active(False)
def forward(self, ignore=None):
@ -145,6 +165,52 @@ class vmmCreateNetwork(vmmGObjectUI):
notebook = self.widget("create-pages")
notebook.prev_page()
def change_ipv4_enable(self, src):
white = Gdk.Color.parse("#f0f0f0")[1]
net4 = self.widget("net-ipv4-network")
start4 = self.widget("net-dhcpv4-start")
end4 = self.widget("net-dhcpv4-end")
if self.get_config_ipv4_enable():
net4.set_sensitive(True)
net4.set_text("")
net4.modify_bg(Gtk.StateType.NORMAL, white)
if self.get_config_dhcpv4_enable():
start4.set_sensitive(True)
end4.set_sensitive(True)
else:
net4.set_text("")
start4.set_text("")
end4.set_text("")
net4.set_sensitive(False)
start4.set_sensitive(False)
end4.set_sensitive(False)
net4.modify_bg(Gtk.StateType.NORMAL, white)
start4.modify_bg(Gtk.StateType.NORMAL, white)
end4.modify_bg(Gtk.StateType.NORMAL, white)
def change_ipv6_enable(self, src):
white = Gdk.Color.parse("#f0f0f0")[1]
net6 = self.widget("net-ipv6-network")
start6 = self.widget("net-dhcpv6-start")
end6 = self.widget("net-dhcpv6-end")
if self.get_config_ipv6_enable():
net6.set_sensitive(True)
net6.set_text("")
net6.modify_bg(Gtk.StateType.NORMAL, white)
if self.get_config_dhcpv6_enable():
start6.set_sensitive(True)
end6.set_sensitive(True)
else:
net6.set_text("")
start6.set_text("")
end6.set_text("")
net6.set_sensitive(False)
start6.set_sensitive(False)
end6.set_sensitive(False)
net6.modify_bg(Gtk.StateType.NORMAL, white)
start6.modify_bg(Gtk.StateType.NORMAL, white)
end6.modify_bg(Gtk.StateType.NORMAL, white)
def change_network(self, src):
ip = self.get_config_ip4()
green = Gdk.Color.parse("#c0ffc0")[1]
@ -154,61 +220,182 @@ class vmmCreateNetwork(vmmGObjectUI):
# No IP specified or invalid IP
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("")
src.modify_bg(Gtk.StateType.NORMAL, red)
self.widget("net-info-gateway").set_text("")
self.widget("net-info-size").set_text("")
self.widget("net-info-type").set_text("")
self.widget("net-dhcpv4-start").set_text("")
self.widget("net-dhcpv4-end").set_text("")
return
# FIXME: handle other networks and not just private?
# We've got a valid IP
if ip.numhosts < 16 or not ip.is_private:
src.modify_base(gtk.STATE_NORMAL, red)
src.modify_bg(Gtk.StateType.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))
src.modify_bg(Gtk.StateType.NORMAL, green)
if ip.prefixlen == 32:
self.widget("net-info-gateway").set_text("")
else:
self.widget("net-info-gateway").set_text(str(ip.network + 1))
self.widget("net-info-size").set_text(_("%d addresses") %
(ip.numhosts))
if ip.is_private:
self.widget("net-info-type").set_text(_("Private"))
elif ip.is_reserved:
self.widget("net-info-type").set_text(_("Reserved"))
else:
self.widget("net-info-type").set_text(_("Other"))
self.widget("net-info-type").set_text(_("Other/Public"))
def change_dhcp_enable(self, src):
val = src.get_active()
self.widget("net-dhcp-start").set_sensitive(val)
self.widget("net-dhcp-end").set_sensitive(val)
if self.get_config_dhcpv4_enable():
self.widget("net-dhcpv4-start").set_sensitive(True)
self.widget("net-dhcpv4-end").set_sensitive(True)
start = int(ip.numhosts / 2)
end = int(ip.numhosts - 2)
self.widget("net-dhcpv4-start").set_text(str(ip.network + start))
self.widget("net-dhcpv4-end").set_text(str(ip.network + end))
else:
self.widget("net-dhcpv4-start").set_sensitive(False)
self.widget("net-dhcpv4-end").set_sensitive(False)
def change_dhcp_start(self, src):
start = self.get_config_dhcp_start()
self.change_dhcp(src, start)
def change_dhcp_end(self, src):
end = self.get_config_dhcp_end()
self.change_dhcp(src, end)
def change_dhcp(self, src, addr):
ip = self.get_config_ip4()
def change_ipv6_network(self, src):
ip = self.get_config_ip6()
green = Gdk.Color.parse("#c0ffc0")[1]
red = Gdk.Color.parse("#ffc0c0")[1]
black = Gdk.Color.parse("#000000")[1]
src.modify_text(Gtk.StateType.NORMAL, black)
if addr is None or not ip.overlaps(addr):
# No IP specified or invalid IP
if ip is None or ip.version != 6:
src.modify_bg(Gtk.StateType.NORMAL, red)
self.widget("net-info-gateway-ip6").set_text("")
self.widget("net-info-type-ip6").set_text("")
self.widget("net-dhcpv6-start").set_text("")
self.widget("net-dhcpv6-end").set_text("")
return
if ip.prefixlen != 64 or not ip.is_private:
src.modify_bg(Gtk.StateType.NORMAL, red)
else:
src.modify_bg(Gtk.StateType.NORMAL, green)
if ip.prefixlen != 64:
self.widget("net-info-gateway-ip6").set_text("")
else:
self.widget("net-info-gateway-ip6").set_text(str(ip.network + 1))
if ip.is_private:
self.widget("net-info-type-ip6").set_text(_("Private"))
elif ip.is_reserved:
self.widget("net-info-type-ip6").set_text(_("Reserved"))
elif ip.is_unspecified:
self.widget("net-info-type-ip6").set_text(_("Unspecified"))
else:
self.widget("net-info-type-ip6").set_text(_("Other/Public"))
if self.get_config_dhcpv6_enable():
self.widget("net-dhcpv6-start").set_sensitive(True)
self.widget("net-dhcpv6-end").set_sensitive(True)
start = 256
end = 512 - 1
self.widget("net-dhcpv6-start").set_text(str(ip.network + start))
self.widget("net-dhcpv6-end").set_text(str(ip.network + end))
else:
self.widget("net-dhcpv6-start").set_sensitive(False)
self.widget("net-dhcpv6-end").set_sensitive(False)
def change_dhcpv4_enable(self, src):
white = Gdk.Color.parse("#f0f0f0")[1]
start4 = self.widget("net-dhcpv4-start")
end4 = self.widget("net-dhcpv4-end")
start4.modify_bg(Gtk.StateType.NORMAL, white)
end4.modify_bg(Gtk.StateType.NORMAL, white)
start4.set_text("")
end4.set_text("")
if not self.get_config_dhcpv4_enable():
start4.set_sensitive(False)
end4.set_sensitive(False)
else:
start4.set_sensitive(True)
end4.set_sensitive(True)
ip = self.get_config_ip4()
if ip:
start = int(ip.numhosts / 2)
end = int(ip.numhosts - 2)
start4.set_text(str(ip.network + start))
end4.set_text(str(ip.network + end))
def change_dhcpv4_start(self, src):
start = self.get_config_dhcpv4_start()
self.change_dhcpv4(src, start)
def change_dhcpv4_end(self, src):
end = self.get_config_dhcpv4_end()
self.change_dhcpv4(src, end)
def change_dhcpv4(self, src, addr):
ip = self.get_config_ip4()
black = Gdk.Color.parse("#000000")[1]
src.modify_text(Gtk.StateType.NORMAL, black)
if not ip:
return
if addr is None:
white = Gdk.Color.parse("#f0f0f0")[1]
src.modify_bg(Gtk.StateType.NORMAL, white)
elif not ip.overlaps(addr):
red = Gdk.Color.parse("#ffc0c0")[1]
src.modify_base(Gtk.StateType.NORMAL, red)
src.modify_bg(Gtk.StateType.NORMAL, red)
else:
green = Gdk.Color.parse("#c0ffc0")[1]
src.modify_base(Gtk.StateType.NORMAL, green)
src.modify_bg(Gtk.StateType.NORMAL, green)
def change_dhcpv6_enable(self, src):
white = Gdk.Color.parse("#f0f0f0")[1]
start6 = self.widget("net-dhcpv6-start")
end6 = self.widget("net-dhcpv6-end")
start6.modify_bg(Gtk.StateType.NORMAL, white)
end6.modify_bg(Gtk.StateType.NORMAL, white)
start6.set_text("")
end6.set_text("")
if not self.get_config_dhcpv6_enable():
start6.set_sensitive(False)
end6.set_sensitive(False)
else:
start6.set_sensitive(True)
end6.set_sensitive(True)
ip = self.get_config_ip6()
if ip:
start = 256
end = 512 - 1
start6.set_text(str(ip.network + start))
end6.set_text(str(ip.network + end))
def change_dhcpv6_start(self, src):
start = self.get_config_dhcpv6_start()
self.change_dhcpv6(src, start)
def change_dhcpv6_end(self, src):
end = self.get_config_dhcpv6_end()
self.change_dhcpv6(src, end)
def change_dhcpv6(self,src,addr):
ip = self.get_config_ip6()
black = Gdk.Color.parse("#000000")[1]
src.modify_text(Gtk.StateType.NORMAL, black)
if not ip:
return
if addr is None:
white = Gdk.Color.parse("#f0f0f0")[1]
src.modify_bg(Gtk.StateType.NORMAL, white)
elif not ip.overlaps(addr):
red = Gdk.Color.parse("#ffc0c0")[1]
src.modify_bg(Gtk.StateType.NORMAL, red)
else:
green = Gdk.Color.parse("#c0ffc0")[1]
src.modify_bg(Gtk.StateType.NORMAL, green)
def change_forward_type(self, src_ignore):
skip_fwd = self.widget("net-forward-none").get_active()
@ -219,20 +406,44 @@ class vmmCreateNetwork(vmmGObjectUI):
def get_config_name(self):
return self.widget("net-name").get_text()
def get_config_domain_name(self):
return self.widget("net-domain-name").get_text()
def get_config_ip4(self):
if not self.get_config_ipv4_enable():
return None
try:
return ipaddr.IPNetwork(self.widget("net-network").get_text())
return ipaddr.IPNetwork(self.widget("net-ipv4-network").get_text())
except:
return None
def get_config_dhcp_start(self):
def get_config_dhcpv4_start(self):
try:
return ipaddr.IPNetwork(self.widget("net-dhcp-start").get_text())
return ipaddr.IPNetwork(self.widget("net-dhcpv4-start").get_text())
except:
return None
def get_config_dhcp_end(self):
def get_config_dhcpv4_end(self):
try:
return ipaddr.IPNetwork(self.widget("net-dhcp-end").get_text())
return ipaddr.IPNetwork(self.widget("net-dhcpv4-end").get_text())
except:
return None
def get_config_ip6(self):
if not self.get_config_ipv6_enable():
return None
try:
return ipaddr.IPNetwork(self.widget("net-ipv6-network").get_text())
except:
return None
def get_config_dhcpv6_start(self):
try:
return ipaddr.IPNetwork(self.widget("net-dhcpv6-start").get_text())
except:
return None
def get_config_dhcpv6_end(self):
try:
return ipaddr.IPNetwork(self.widget("net-dhcpv6-end").get_text())
except:
return None
@ -250,53 +461,167 @@ class vmmCreateNetwork(vmmGObjectUI):
mode = mode_w.get_model()[mode_w.get_active()][1]
return [name, mode]
def get_config_dhcp_enable(self):
return self.widget("net-dhcp-enable").get_active()
def get_config_ipv4_enable(self):
return self.widget("net-ipv4-enable").get_active()
def get_config_ipv6_enable(self):
return self.widget("net-ipv6-enable").get_active()
def get_config_dhcpv4_enable(self):
return self.widget("net-dhcpv4-enable").get_active()
def get_config_dhcpv6_enable(self):
return self.widget("net-dhcpv6-enable").get_active()
def populate_summary(self):
dodhcp = self.get_config_dhcp_enable()
self.widget("summary-name").set_text(self.get_config_name())
self.widget("summary-domain").set_text(self.get_config_domain_name())
self.widget("summary-ip4-network").set_text("");
self.widget("summary-ip4-gateway").set_text("");
self.widget("summary-ip6-network").set_text("");
self.widget("summary-ip6-gateway").set_text("");
ip = self.get_config_ip4()
self.widget("summary-ip4-network").set_text(str(ip))
self.widget("summary-ip4-gateway").set_text(str(ip.network + 1))
self.widget("summary-ip4-netmask").set_text(str(ip.netmask))
if ip:
self.widget("label-ip4-gateway").show()
self.widget("summary-ip4-gateway").show()
self.widget("label-ip4-network").set_text(_("Network:"))
self.widget("summary-ip4-network").set_text(str(ip))
self.widget("summary-ip4-gateway").set_text(str(ip.network + 1))
else:
self.widget("label-ip4-gateway").hide()
self.widget("summary-ip4-gateway").hide()
self.widget("label-ip4-network").set_text("IPv4 Network:")
self.widget("summary-ip4-network").set_text("Not Defined")
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.network))
self.widget("summary-dhcp-end").set_text(str(end.network))
self.widget("label-dhcp-start").set_text(_("Start address:"))
if ip and self.get_config_dhcpv4_enable():
self.widget("label-dhcp-end").show()
self.widget("summary-dhcp-end").show()
start = self.get_config_dhcpv4_start()
end = self.get_config_dhcpv4_end()
self.widget("label-dhcp-start").set_text("Start Address:")
if start and end:
self.widget("summary-dhcp-start").set_text(str(start.network))
self.widget("summary-dhcp-end").set_text(str(end.network))
else:
self.widget("summary-dhcp-start").set_text("?")
self.widget("summary-dhcp-end").set_text("?")
else:
self.widget("label-dhcp-start").set_text(_("Status:"))
self.widget("label-dhcp-end").hide()
self.widget("summary-dhcp-end").hide()
self.widget("label-dhcp-start").set_text(_("DHCPv4 Status:"))
self.widget("summary-dhcp-start").set_text(_("Disabled"))
forward_txt = ""
dev, mode = self.get_config_forwarding()
forward_txt = vmmNetwork.pretty_desc(mode, dev)
self.widget("summary-forwarding").set_text(forward_txt)
self.widget("summary-ipv4-forwarding").set_text(forward_txt)
def populate_dhcp(self):
ip = self.get_config_ip4()
start = int(ip.numhosts / 2)
end = int(ip.numhosts - 2)
ip = self.get_config_ip6()
if ip:
self.widget("label-ip6-gateway").show()
self.widget("summary-ip6-gateway").show()
self.widget("label-ip6-network").set_text(_("Network:"))
self.widget("summary-ip6-network").set_text(str(ip))
self.widget("summary-ip6-gateway").set_text(str(ip.network + 1))
else:
self.widget("label-ip6-gateway").hide()
self.widget("summary-ip6-gateway").hide()
self.widget("label-ip6-network").set_text(_("IPV6 Network:"))
self.widget("summary-ip6-network").set_text(_("Not Defined"))
if self.widget("net-dhcp-start").get_text() == "":
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.network + end))
if ip and self.get_config_dhcpv6_enable():
self.widget("label-dhcpv6-end").show()
self.widget("summary-dhcpv6-end").show()
start = self.get_config_dhcpv6_start()
end = self.get_config_dhcpv6_end()
self.widget("label-dhcpv6-start").set_text("Start Address:")
if start and end:
self.widget("summary-dhcpv6-start").set_text(str(start.network))
self.widget("summary-dhcpv6-end").set_text(str(end.network))
else:
self.widget("summary-dhcpv6-start").set_text("?")
self.widget("summary-dhcpv6-end").set_text("?")
else:
self.widget("label-dhcpv6-end").hide()
self.widget("summary-dhcpv6-end").hide()
self.widget("label-dhcpv6-start").set_text(_("DHCPv6 Status:"))
self.widget("summary-dhcpv6-start").set_text(_("Disabled"))
if ip:
self.widget("summary-ipv6-forwarding").set_text("Routed network")
else:
if self.widget("net-enable-ipv6-networking").get_active():
self.widget("summary-ipv6-forwarding").set_text("Isolated network, internal routing only")
else:
self.widget("summary-ipv6-forwarding").set_text("Isolated network")
def populate_ipv4(self):
if not self.get_config_ipv4_enable():
self.widget("net-ipv4-network").set_text("")
self.widget("net-dhcpv4-end").set_text("")
self.widget("net-dhcpv4-start").set_text("")
self.widget("net-ipv4-network").set_sensitive(False)
self.widget("net-dhcpv4-start").set_sensitive(False)
self.widget("net-dhcpv4-end").set_sensitive(False)
return
self.widget("net-ipv4-network").set_sensitive(True)
if not self.get_config_dhcpv4_enable():
self.widget("net-dhcpv4-end").set_text("")
self.widget("net-dhcpv4-start").set_text("")
self.widget("net-dhcpv4-start").set_sensitive(False)
self.widget("net-dhcpv4-end").set_sensitive(False)
return
else:
ip = self.get_config_ip4()
if ip:
start = int(ip.numhosts / 2)
end = int(ip.numhosts - 2)
if self.widget("net-dhcpv4-start").get_text() == "":
self.widget("net-dhcpv4-start").set_text(str(ip.network + start))
self.widget("net-dhcpv4-end").set_text(str(ip.network + end))
self.widget("net-dhcpv4-start").set_sensitive(True)
self.widget("net-dhcpv4-end").set_sensitive(True)
def populate_ipv6(self):
if not self.get_config_ipv6_enable():
self.widget("net-ipv6-network").set_text("")
self.widget("net-dhcpv6-end").set_text("")
self.widget("net-dhcpv6-start").set_text("")
self.widget("net-ipv6-network").set_sensitive(False)
self.widget("net-dhcpv6-start").set_sensitive(False)
self.widget("net-dhcpv6-end").set_sensitive(False)
return
self.widget("net-ipv6-network").set_sensitive(True)
if not self.get_config_dhcpv6_enable():
self.widget("net-dhcpv6-end").set_text("")
self.widget("net-dhcpv6-start").set_text("")
self.widget("net-dhcpv6-start").set_sensitive(False)
self.widget("net-dhcpv6-end").set_sensitive(False)
return
else:
ip = self.get_config_ip6()
if ip:
start = 256
end = 512 - 1
if self.widget("net-dhcpv6-start").get_text() == "":
self.widget("net-dhcpv6-start").set_text(str(ip.network + start))
self.widget("net-dhcpv6-end").set_text(str(ip.network + end))
self.widget("net-dhcpv6-start").set_sensitive(True)
self.widget("net-dhcpv6-end").set_sensitive(True)
def page_changed(self, ignore1, ignore2, page_number):
if page_number == PAGE_NAME:
name_widget = self.widget("net-name")
name_widget.set_sensitive(True)
name_widget.grab_focus()
elif page_number == PAGE_DHCP:
self.populate_dhcp()
elif page_number == PAGE_IPV4:
self.populate_ipv4()
elif page_number == PAGE_IPV6:
self.populate_ipv6()
elif page_number == PAGE_SUMMARY:
self.populate_summary()
@ -316,30 +641,53 @@ class vmmCreateNetwork(vmmGObjectUI):
def finish(self, ignore=None):
name = self.get_config_name()
ip = self.get_config_ip4()
start = self.get_config_dhcp_start()
end = self.get_config_dhcp_end()
dev, mode = self.get_config_forwarding()
xml = "<network>\n"
if self.widget("net-enable-ipv6-networking").get_active():
xml = "<network ipv6='yes'>\n"
else:
xml = "<network>\n"
xml += " <name>%s</name>\n" % name
domain_name = self.get_config_domain_name()
if len(domain_name) != 0:
xml += " <domain name='%s' />\n" % domain_name
if mode:
if dev is not None:
xml += " <forward mode='%s' dev='%s'/>\n" % (mode, dev)
else:
xml += " <forward mode='%s'/>\n" % mode
xml += " <ip address='%s' netmask='%s'>\n" % (str(ip.network + 1),
if self.get_config_ipv4_enable():
ip = self.get_config_ip4()
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.network),
str(end.network))
xml += " </dhcp>\n"
if self.get_config_dhcpv4_enable():
start = self.get_config_dhcpv4_start()
end = self.get_config_dhcpv4_end()
xml += " <dhcp>\n"
xml += " <range start='%s' end='%s'/>\n" % (str(start.network),
str(end.network))
xml += " </dhcp>\n"
xml += " </ip>\n"
if self.get_config_ipv6_enable():
ip = self.get_config_ip6()
xml += " <ip family='ipv6' address='%s' prefix='%s'>\n" % (str(ip.network + 1),
str(ip.prefixlen))
if self.get_config_dhcpv6_enable():
start = self.get_config_dhcpv6_start()
end = self.get_config_dhcpv6_end()
xml += " <dhcp>\n"
xml += " <range start='%s' end='%s'/>\n" % (str(start.network),
str(end.network))
xml += " </dhcp>\n"
xml += " </ip>\n"
xml += " </ip>\n"
xml += "</network>\n"
logging.debug("Generated network XML:\n" + xml)
@ -354,11 +702,14 @@ class vmmCreateNetwork(vmmGObjectUI):
self.close()
def validate_name(self):
name = self.widget("net-name").get_text()
name_widget = self.widget("net-name")
name = name_widget.get_text()
if len(name) > 50 or len(name) == 0:
return self.err.val_err(_("Invalid Network Name"),
retcode = self.err.val_err(_("Invalid Network Name"),
_("Network name must be non-blank and less than "
"50 characters"))
name_widget.grab_focus()
return retcode
if re.match("^[a-zA-Z0-9_]*$", name) is None:
return self.err.val_err(_("Invalid Network Name"),
_("Network name may contain alphanumeric and '_' "
@ -366,6 +717,8 @@ class vmmCreateNetwork(vmmGObjectUI):
return True
def validate_ipv4(self):
if not self.get_config_ipv4_enable():
return True
ip = self.get_config_ip4()
if ip is None:
return self.err.val_err(_("Invalid Network Address"),
@ -386,32 +739,82 @@ class vmmCreateNetwork(vmmGObjectUI):
if not res:
return False
enabled = self.get_config_dhcpv4_enable()
if enabled:
start = self.get_config_dhcpv4_start()
end = self.get_config_dhcpv4_end()
if enabled and start is None:
return self.err.val_err(_("Invalid DHCP Address"),
_("The DHCP start address could not be understood"))
if enabled and end is None:
return self.err.val_err(_("Invalid DHCP Address"),
_("The DHCP end address could not be understood"))
if enabled and not ip.overlaps(start):
return self.err.val_err(_("Invalid DHCP Address"),
(_("The DHCP start address is not with the network %s") %
(str(ip))))
if enabled and not ip.overlaps(end):
return self.err.val_err(_("Invalid DHCP Address"),
(_("The DHCP end address is not with the network %s") %
(str(ip))))
return True
def validate_dhcp(self):
ip = self.get_config_ip4()
start = self.get_config_dhcp_start()
end = self.get_config_dhcp_end()
enabled = self.widget("net-dhcp-enable").get_active()
def validate_ipv6(self):
if not self.get_config_ipv6_enable():
return True
ip = self.get_config_ip6()
if ip is None:
return self.err.val_err(_("Invalid Network Address"),
_("The network address could not be understood"))
if enabled and start is None:
return self.err.val_err(_("Invalid DHCP Address"),
_("The DHCP start address could not be understood"))
if enabled and end is None:
return self.err.val_err(_("Invalid DHCP Address"),
_("The DHCP end address could not be understood"))
if ip.version != 6:
return self.err.val_err(_("Invalid Network Address"),
_("The network must be an IPv6 address"))
if ip.prefixlen != 64:
return self.err.val_err(_("Invalid Network Address"),
_("For libvirt, the IPv6 network prefix must be 64"))
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?"))
if not res:
return False
enabled = self.get_config_dhcpv6_enable()
if enabled:
start = self.get_config_dhcpv6_start()
end = self.get_config_dhcpv6_end()
if start is None:
return self.err.val_err(_("Invalid DHCPv6 Address"),
_("The DHCPv6 start address could not be understood"))
if end is None:
return self.err.val_err(_("Invalid DHCPv6 Address"),
_("The DHCPv6 end address could not be understood"))
if not ip.overlaps(start):
return self.err.val_err(_("Invalid DHCPv6 Address"),
(_("The DHCPv6 start address is not with the network %s") %
(str(ip))))
if not ip.overlaps(end):
return self.err.val_err(_("Invalid DHCPv6 Address"),
(_("The DHCPv6 end address is not with the network %s") %
(str(ip))))
if enabled and not ip.overlaps(start):
return self.err.val_err(_("Invalid DHCP Address"),
(_("The DHCP start address is not with the network %s") %
(str(ip))))
if enabled and not ip.overlaps(end):
return self.err.val_err(_("Invalid DHCP Address"),
(_("The DHCP end address is not with the network %s") %
(str(ip))))
return True
def validate_forwarding(self):
def validate_miscellaneous(self):
domain_name = self.widget("net-domain-name").get_text()
if len(domain_name) > 0:
if len(domain_name) > 16:
return self.err.val_err(_("Invalid Domain Name"),
_("Domain name must be less than 17 characters"))
if re.match("^[a-zA-Z0-9_]*$", domain_name) is None:
return self.err.val_err(_("Invalid Domain Name"),
_("Domain name may contain alphanumeric and '_' "
"characters only"))
if not self.widget("net-forward-dev").get_active():
return True
@ -426,8 +829,8 @@ class vmmCreateNetwork(vmmGObjectUI):
return self.validate_name()
elif page_num == PAGE_IPV4:
return self.validate_ipv4()
elif page_num == PAGE_DHCP:
return self.validate_dhcp()
elif page_num == PAGE_FORWARDING:
return self.validate_forwarding()
elif page_num == PAGE_IPV6:
return self.validate_ipv6()
elif page_num == PAGE_MISC:
return self.validate_miscellaneous()
return True