diff --git a/backend.py b/backend.py index e676a3e..0c33e1b 100644 --- a/backend.py +++ b/backend.py @@ -1625,15 +1625,16 @@ def configureNetworking(mounts, admin_iface, admin_bridge, admin_config, hn_conf print >>mc, "NETMASK='%s'" % admin_config.netmask if admin_config.gateway: print >>mc, "GATEWAY='%s'" % admin_config.gateway - if manual_nameservers: - print >>mc, "DNS='%s'" % (','.join(nameservers),) - if domain: - print >>mc, "DOMAIN='%s'" % domain print >>mc, "MODEV6='%s'" % netinterface.NetInterface.getModeStr(admin_config.modev6) if admin_config.modev6 == netinterface.NetInterface.Static: print >>mc, "IPv6='%s'" % admin_config.ipv6addr if admin_config.ipv6_gateway: print >>mc, "IPv6_GATEWAY='%s'" % admin_config.ipv6_gateway + if admin_config.isStatic(): + if manual_nameservers: + print >>mc, "DNS='%s'" % (','.join(nameservers),) + if domain: + print >>mc, "DOMAIN='%s'" % domain if admin_config.vlan: print >>mc, "VLAN='%d'" % admin_config.vlan mc.close() @@ -1676,12 +1677,18 @@ def configureNetworking(mounts, admin_iface, admin_bridge, admin_config, hn_conf # now we need to write /etc/sysconfig/network nfd = open("%s/etc/sysconfig/network" % mounts["root"], "w") nfd.write("NETWORKING=yes\n") + ipv6_conf = open("%s/etc/sysctl.d/91-net-ipv6.conf" % mounts["root"], "w") if admin_config.modev6: nfd.write("NETWORKING_IPV6=yes\n") util.runCmd2(['chroot', mounts['root'], 'systemctl', 'enable', 'ip6tables']) + for i in ['all', 'default']: + ipv6_conf.write('net.ipv6.conf.%s.disable_ipv6=0\n' % i) else: nfd.write("NETWORKING_IPV6=no\n") + for i in ['all', 'default']: + ipv6_conf.write('net.ipv6.conf.%s.disable_ipv6=1\n' % i) netutil.disable_ipv6_module(mounts["root"]) + ipv6_conf.close() nfd.write("IPV6_AUTOCONF=no\n") nfd.write('NTPSERVERARGS="iburst prefer"\n') nfd.close() diff --git a/netinterface.py b/netinterface.py index 47a9716..a83e0a1 100644 --- a/netinterface.py +++ b/netinterface.py @@ -48,26 +48,31 @@ def __init__(self, mode, hwaddr, ipaddr=None, netmask=None, gateway=None, assert ipaddr assert netmask - self.mode = mode + ipv6 = ipaddr.find(':') > -1 if ipaddr else False + self.hwaddr = hwaddr - if mode == self.Static: - self.ipaddr = ipaddr - self.netmask = netmask - self.gateway = gateway - self.dns = dns - self.domain = domain - else: + if ipv6: + self.mode = None self.ipaddr = None self.netmask = None self.gateway = None - self.dns = None - self.domain = None - self.vlan = vlan - # Initialise IPv6 to None. - self.modev6 = None - self.ipv6addr = None - self.ipv6_gateway = None + self.modev6 = mode + self.ipv6addr = ipaddr + "/" + netmask if mode == self.Static else None + self.ipv6_gateway = gateway if mode == self.Static else None + else: + self.modev6 = None + self.ipv6addr = None + self.ipv6_gateway = None + + self.mode = mode + self.ipaddr = ipaddr if mode == self.Static else None + self.netmask = netmask if mode == self.Static else None + self.gateway = gateway if mode == self.Static else None + + self.dns = dns if mode == self.Static else None + self.domain = domain if mode == self.Static else None + self.vlan = vlan def __repr__(self): hw = "hwaddr = '%s' " % self.hwaddr @@ -132,7 +137,7 @@ def valid(self): def isStatic(self): """ Returns true if a static interface configuration is represented. """ - return self.mode == self.Static + return self.mode == self.Static or (self.mode == None and self.modev6 == self.Static) def isVlan(self): return self.vlan is not None @@ -151,13 +156,12 @@ def writeDebStyleInterface(self, iface, f): # Debian style interfaces are only used for the installer; dom0 only uses CentOS style # IPv6 is only enabled through answerfiles and so is not supported here. - assert self.modev6 is None - assert self.mode + assert self.modev6 or self.mode iface_vlan = self.getInterfaceName(iface) if self.mode == self.DHCP: f.write("iface %s inet dhcp\n" % iface_vlan) - else: + elif self.mode == self.Static: # CA-11825: broadcast needs to be determined for non-standard networks bcast = self.getBroadcast() f.write("iface %s inet static\n" % iface_vlan) @@ -168,32 +172,55 @@ def writeDebStyleInterface(self, iface, f): if self.gateway: f.write(" gateway %s\n" % self.gateway) + if self.modev6 == self.DHCP: + f.write("iface %s inet6 dhcp\n" % iface_vlan) + elif self.modev6 == self.Static: + f.write("iface %s inet6 static\n" % iface_vlan) + f.write(" address %s\n" % self.ipv6addr) + if self.ipv6_gateway: + f.write(" gateway %s\n" % self.ipv6_gateway) + def writeRHStyleInterface(self, iface): """ Write a RedHat-style configuration entry for this interface to file object f using interface name iface. """ - assert self.modev6 is None - assert self.mode + assert self.modev6 or self.mode iface_vlan = self.getInterfaceName(iface) f = open('/etc/sysconfig/network-scripts/ifcfg-%s' % iface_vlan, 'w') f.write("DEVICE=%s\n" % iface_vlan) f.write("ONBOOT=yes\n") - if self.mode == self.DHCP: + if self.mode == self.DHCP or self.modev6 == self.DHCP: f.write("BOOTPROTO=dhcp\n") f.write("PERSISTENT_DHCLIENT=1\n") else: + f.write("BOOTPROTO=none\n") + + if self.mode == self.Static: # CA-11825: broadcast needs to be determined for non-standard networks bcast = self.getBroadcast() - f.write("BOOTPROTO=none\n") f.write("IPADDR=%s\n" % self.ipaddr) if bcast is not None: f.write("BROADCAST=%s\n" % bcast) f.write("NETMASK=%s\n" % self.netmask) if self.gateway: f.write("GATEWAY=%s\n" % self.gateway) + + if self.modev6: + f.write("NETWORKING_IPV6=yes\n") + f.write("IPV6INIT=yes\n") + f.write("IPV6_AUTOCONF=no\n") + if self.modev6 == self.DHCP: + f.write("DHCPV6C=yes\n") + elif self.modev6 == self.Static: + f.write("IPV6ADDR=%s\n" % self.ipv6addr) + if self.ipv6_gateway: + prefix = self.ipv6addr.split("/")[1] + f.write("IPV6_DEFAULTGW=%s/%s\n" % (self.ipv6_gateway, prefix)) + if self.vlan: f.write("VLAN=yes\n") + f.close() diff --git a/netutil.py b/netutil.py index 00ec707..1c46020 100644 --- a/netutil.py +++ b/netutil.py @@ -147,7 +147,11 @@ def interfaceUp(interface): if rc != 0: return False inets = filter(lambda x: x.startswith(" inet "), out.split("\n")) - return len(inets) == 1 + if len(inets) == 1: + return True + + inet6s = filter(lambda x: x.startswith(" inet6 "), out.split("\n")) + return len(inet6s) > 1 # Not just the fe80:: address # work out if a link is up: def linkUp(interface): @@ -236,15 +240,9 @@ def valid_vlan(vlan): return True def valid_ip_addr(addr): - if not re.match('^\d+\.\d+\.\d+\.\d+$', addr): - return False - els = addr.split('.') - if len(els) != 4: - return False - for el in els: - if int(el) > 255: - return False - return True + ipv4_re = '^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}' + ipv6_re = '^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))' + return re.match(ipv4_re, addr) or re.match(ipv6_re, addr) def network(ipaddr, netmask): ip = map(int,ipaddr.split('.',3)) diff --git a/tui/network.py b/tui/network.py index 4ad1c23..8b0e22d 100644 --- a/tui/network.py +++ b/tui/network.py @@ -23,124 +23,289 @@ from snack import * def get_iface_configuration(nic, txt=None, defaults=None, include_dns=False): + def choose_primary_address_type(nic): + gf = GridFormHelp(tui.screen, 'Networking', 'Address type', 1, 8) + txt = "Choose an address type for %s (%s)" % (nic.name, nic.hwaddr) + text = TextboxReflowed(45, txt) + + b = [("Ok", "ok"), ("Back", "back")] + buttons = ButtonBar(tui.screen, b) + + # IPv4 by default + ipv4_rb = SingleRadioButton("IPv4", None, 1) + ipv6_rb = SingleRadioButton("IPv6 (Static only)", ipv4_rb, 0) + dual_rb = SingleRadioButton("Dual stack (IPv4 primary)", ipv6_rb, 0) + + gf.add(text, 0, 0, padding=(0, 0, 0, 1)) + gf.add(ipv4_rb, 0, 2, anchorLeft=True) + gf.add(ipv6_rb, 0, 3, anchorLeft=True) + gf.add(dual_rb, 0, 4, anchorLeft=True) + gf.add(buttons, 0, 5, growx=1) + + loop = True + direction = LEFT_BACKWARDS + address_type = None + while loop: + result = gf.run() + if buttons.buttonPressed(result) == 'back': + loop = False + elif buttons.buttonPressed(result) == 'ok': + value = None + if ipv4_rb.selected(): + value = "ipv4" + elif ipv6_rb.selected(): + value = "ipv6" + elif dual_rb.selected(): + value = "dual" + loop = False + direction = RIGHT_FORWARDS + address_type = value + + tui.screen.popWindow() + return direction, address_type + + def get_ipv4_configuration(nic, txt, defaults, include_dns): + def use_vlan_cb_change(): + vlan_field.setFlags(FLAG_DISABLED, vlan_cb.value()) + + def dhcp_change(): + for x in [ ip_field, gateway_field, subnet_field, dns_field ]: + x.setFlags(FLAG_DISABLED, not dhcp_rb.selected()) + + gf = GridFormHelp(tui.screen, 'Networking', 'ifconfig', 1, 8) + if txt is None: + txt = "Configuration for %s (%s)" % (nic.name, nic.hwaddr) + text = TextboxReflowed(45, txt) + b = [("Ok", "ok"), ("Back", "back")] + buttons = ButtonBar(tui.screen, b) + + ip_field = Entry(16) + subnet_field = Entry(16) + gateway_field = Entry(16) + dns_field = Entry(16) + vlan_field = Entry(16) + + if defaults and defaults.isStatic(): + # static configuration defined previously + dhcp_rb = SingleRadioButton("Automatic configuration (DHCP)", None, 0) + dhcp_rb.setCallback(dhcp_change, ()) + static_rb = SingleRadioButton("Static configuration:", dhcp_rb, 1) + static_rb.setCallback(dhcp_change, ()) + if defaults.ipaddr: + ip_field.set(defaults.ipaddr) + if defaults.netmask: + subnet_field.set(defaults.netmask) + if defaults.gateway: + gateway_field.set(defaults.gateway) + if defaults.dns: + dns_field.set(defaults.dns[0]) + else: + dhcp_rb = SingleRadioButton("Automatic configuration (DHCP)", None, 1) + dhcp_rb.setCallback(dhcp_change, ()) + static_rb = SingleRadioButton("Static configuration:", dhcp_rb, 0) + static_rb.setCallback(dhcp_change, ()) + ip_field.setFlags(FLAG_DISABLED, False) + subnet_field.setFlags(FLAG_DISABLED, False) + gateway_field.setFlags(FLAG_DISABLED, False) + dns_field.setFlags(FLAG_DISABLED, False) + + vlan_cb = Checkbox("Use VLAN:", defaults.isVlan() if defaults else False) + vlan_cb.setCallback(use_vlan_cb_change, ()) + if defaults and defaults.isVlan(): + vlan_field.set(str(defaults.vlan)) + else: + vlan_field.setFlags(FLAG_DISABLED, False) + + ip_text = Textbox(15, 1, "IP Address:") + subnet_text = Textbox(15, 1, "Subnet mask:") + gateway_text = Textbox(15, 1, "Gateway:") + dns_text = Textbox(15, 1, "Nameserver:") + vlan_text = Textbox(15, 1, "VLAN (1-4094):") + + entry_grid = Grid(2, include_dns and 4 or 3) + entry_grid.setField(ip_text, 0, 0) + entry_grid.setField(ip_field, 1, 0) + entry_grid.setField(subnet_text, 0, 1) + entry_grid.setField(subnet_field, 1, 1) + entry_grid.setField(gateway_text, 0, 2) + entry_grid.setField(gateway_field, 1, 2) + if include_dns: + entry_grid.setField(dns_text, 0, 3) + entry_grid.setField(dns_field, 1, 3) + + vlan_grid = Grid(2, 1) + vlan_grid.setField(vlan_text, 0, 0) + vlan_grid.setField(vlan_field, 1, 0) + + gf.add(text, 0, 0, padding=(0, 0, 0, 1)) + gf.add(dhcp_rb, 0, 2, anchorLeft=True) + gf.add(static_rb, 0, 3, anchorLeft=True) + gf.add(entry_grid, 0, 4, padding=(0, 0, 0, 1)) + gf.add(vlan_cb, 0, 5, anchorLeft=True) + gf.add(vlan_grid, 0, 6, padding=(0, 0, 0, 1)) + gf.add(buttons, 0, 7, growx=1) + + loop = True + while loop: + result = gf.run() + + if buttons.buttonPressed(result) in ['ok', None]: + # validate input + msg = '' + if static_rb.selected(): + if not netutil.valid_ip_addr(ip_field.value()): + msg = 'IP Address' + elif not netutil.valid_ip_addr(subnet_field.value()): + msg = 'Subnet mask' + elif gateway_field.value() != '' and not netutil.valid_ip_addr(gateway_field.value()): + msg = 'Gateway' + elif dns_field.value() != '' and not netutil.valid_ip_addr(dns_field.value()): + msg = 'Nameserver' + if vlan_cb.selected(): + if not netutil.valid_vlan(vlan_field.value()): + msg = 'VLAN' + if msg != '': + tui.progress.OKDialog("Networking", "Invalid %s, please check the field and try again." % msg) + else: + loop = False + else: + loop = False - def use_vlan_cb_change(): - vlan_field.setFlags(FLAG_DISABLED, vlan_cb.value()) - - def dhcp_change(): - for x in [ ip_field, gateway_field, subnet_field, dns_field ]: - x.setFlags(FLAG_DISABLED, not dhcp_rb.selected()) - - gf = GridFormHelp(tui.screen, 'Networking', 'ifconfig', 1, 8) - if txt is None: - txt = "Configuration for %s (%s)" % (nic.name, nic.hwaddr) - text = TextboxReflowed(45, txt) - b = [("Ok", "ok"), ("Back", "back")] - buttons = ButtonBar(tui.screen, b) - - ip_field = Entry(16) - subnet_field = Entry(16) - gateway_field = Entry(16) - dns_field = Entry(16) - vlan_field = Entry(16) - - if defaults and defaults.isStatic(): - # static configuration defined previously - dhcp_rb = SingleRadioButton("Automatic configuration (DHCP)", None, 0) - dhcp_rb.setCallback(dhcp_change, ()) - static_rb = SingleRadioButton("Static configuration:", dhcp_rb, 1) - static_rb.setCallback(dhcp_change, ()) - if defaults.ipaddr: - ip_field.set(defaults.ipaddr) - if defaults.netmask: - subnet_field.set(defaults.netmask) - if defaults.gateway: - gateway_field.set(defaults.gateway) - if defaults.dns: - dns_field.set(defaults.dns[0]) - else: - dhcp_rb = SingleRadioButton("Automatic configuration (DHCP)", None, 1) - dhcp_rb.setCallback(dhcp_change, ()) - static_rb = SingleRadioButton("Static configuration:", dhcp_rb, 0) - static_rb.setCallback(dhcp_change, ()) - ip_field.setFlags(FLAG_DISABLED, False) - subnet_field.setFlags(FLAG_DISABLED, False) - gateway_field.setFlags(FLAG_DISABLED, False) - dns_field.setFlags(FLAG_DISABLED, False) - - vlan_cb = Checkbox("Use VLAN:", defaults.isVlan() if defaults else False) - vlan_cb.setCallback(use_vlan_cb_change, ()) - if defaults and defaults.isVlan(): - vlan_field.set(str(defaults.vlan)) - else: - vlan_field.setFlags(FLAG_DISABLED, False) - - ip_text = Textbox(15, 1, "IP Address:") - subnet_text = Textbox(15, 1, "Subnet mask:") - gateway_text = Textbox(15, 1, "Gateway:") - dns_text = Textbox(15, 1, "Nameserver:") - vlan_text = Textbox(15, 1, "VLAN (1-4094):") - - entry_grid = Grid(2, include_dns and 4 or 3) - entry_grid.setField(ip_text, 0, 0) - entry_grid.setField(ip_field, 1, 0) - entry_grid.setField(subnet_text, 0, 1) - entry_grid.setField(subnet_field, 1, 1) - entry_grid.setField(gateway_text, 0, 2) - entry_grid.setField(gateway_field, 1, 2) - if include_dns: - entry_grid.setField(dns_text, 0, 3) - entry_grid.setField(dns_field, 1, 3) - - vlan_grid = Grid(2, 1) - vlan_grid.setField(vlan_text, 0, 0) - vlan_grid.setField(vlan_field, 1, 0) - - gf.add(text, 0, 0, padding=(0, 0, 0, 1)) - gf.add(dhcp_rb, 0, 2, anchorLeft=True) - gf.add(static_rb, 0, 3, anchorLeft=True) - gf.add(entry_grid, 0, 4, padding=(0, 0, 0, 1)) - gf.add(vlan_cb, 0, 5, anchorLeft=True) - gf.add(vlan_grid, 0, 6, padding=(0, 0, 0, 1)) - gf.add(buttons, 0, 7, growx=1) - - loop = True - while loop: - result = gf.run() - - if buttons.buttonPressed(result) in ['ok', None]: - # validate input - msg = '' - if static_rb.selected(): + tui.screen.popWindow() + + if buttons.buttonPressed(result) == 'back': return LEFT_BACKWARDS, None + + vlan_value = int(vlan_field.value()) if vlan_cb.selected() else None + if bool(dhcp_rb.selected()): + answers = NetInterface(NetInterface.DHCP, nic.hwaddr, vlan=vlan_value) + else: + answers = NetInterface(NetInterface.Static, nic.hwaddr, ip_field.value(), + subnet_field.value(), gateway_field.value(), + dns_field.value(), vlan=vlan_value) + return RIGHT_FORWARDS, answers + + def get_ipv6_configuration(nic, txt, defaults, include_dns): + def use_vlan_cb_change(): + vlan_field.setFlags(FLAG_DISABLED, vlan_cb.value()) + + gf = GridFormHelp(tui.screen, 'Networking', 'ifconfigv6', 1, 8) + if txt is None: + txt = "Configuration for %s (%s)" % (nic.name, nic.hwaddr) + text = TextboxReflowed(45, txt) + b = [("Ok", "ok"), ("Back", "back")] + buttons = ButtonBar(tui.screen, b) + + ip_field = Entry(25) + subnet_field = Entry(25) + gateway_field = Entry(25) + dns_field = Entry(25) + vlan_field = Entry(25) + + if defaults: + if defaults.ipv6addr: + ip6addr, netmask = defaults.ipv6addr.split("/") + ip_field.set(ip6addr) + subnet_field.set(netmask) + if defaults.ipv6_gateway: + gateway_field.set(defaults.ipv6_gateway) + if defaults.dns: + dns_field.set(defaults.dns[0]) + + vlan_cb = Checkbox("Use VLAN:", defaults.isVlan() if defaults else False) + vlan_cb.setCallback(use_vlan_cb_change, ()) + if defaults and defaults.isVlan(): + vlan_field.set(str(defaults.vlan)) + else: + vlan_field.setFlags(FLAG_DISABLED, False) + + ip_text = Textbox(15, 1, "IPv6 Address:") + subnet_text = Textbox(15, 1, "CIDR (4-128):") + gateway_text = Textbox(15, 1, "Gateway:") + dns_text = Textbox(15, 1, "Nameserver:") + vlan_text = Textbox(15, 1, "VLAN (1-4094):") + + entry_grid = Grid(2, include_dns and 4 or 3) + entry_grid.setField(ip_text, 0, 0) + entry_grid.setField(ip_field, 1, 0) + entry_grid.setField(subnet_text, 0, 1) + entry_grid.setField(subnet_field, 1, 1) + entry_grid.setField(gateway_text, 0, 2) + entry_grid.setField(gateway_field, 1, 2) + if include_dns: + entry_grid.setField(dns_text, 0, 3) + entry_grid.setField(dns_field, 1, 3) + + vlan_grid = Grid(2, 1) + vlan_grid.setField(vlan_text, 0, 0) + vlan_grid.setField(vlan_field, 1, 0) + + gf.add(text, 0, 0, padding=(0, 0, 0, 1)) + gf.add(entry_grid, 0, 2, padding=(0, 0, 0, 1)) + gf.add(vlan_cb, 0, 3, anchorLeft=True) + gf.add(vlan_grid, 0, 4, padding=(0, 0, 0, 1)) + gf.add(buttons, 0, 5, growx=1) + + loop = True + while loop: + result = gf.run() + + if buttons.buttonPressed(result) in ['ok', None]: + # validate input + msg = '' + subnet_value = int(subnet_field.value()) if not netutil.valid_ip_addr(ip_field.value()): - msg = 'IP Address' - elif not netutil.valid_ip_addr(subnet_field.value()): - msg = 'Subnet mask' + msg = 'IPv6 Address' + elif subnet_value > 128 or subnet_value < 4: + msg = 'CIDR' elif gateway_field.value() != '' and not netutil.valid_ip_addr(gateway_field.value()): msg = 'Gateway' elif dns_field.value() != '' and not netutil.valid_ip_addr(dns_field.value()): msg = 'Nameserver' - if vlan_cb.selected(): - if not netutil.valid_vlan(vlan_field.value()): - msg = 'VLAN' - if msg != '': - tui.progress.OKDialog("Networking", "Invalid %s, please check the field and try again." % msg) + if vlan_cb.selected(): + if not netutil.valid_vlan(vlan_field.value()): + msg = 'VLAN' + if msg != '': + tui.progress.OKDialog("Networking", "Invalid %s, please check the field and try again." % msg) + else: + loop = False else: loop = False - else: - loop = False - tui.screen.popWindow() + tui.screen.popWindow() - if buttons.buttonPressed(result) == 'back': return LEFT_BACKWARDS, None + if buttons.buttonPressed(result) == 'back': return LEFT_BACKWARDS, None - vlan_value = int(vlan_field.value()) if vlan_cb.selected() else None - if bool(dhcp_rb.selected()): - answers = NetInterface(NetInterface.DHCP, nic.hwaddr, vlan=vlan_value) - else: + vlan_value = int(vlan_field.value()) if vlan_cb.selected() else None answers = NetInterface(NetInterface.Static, nic.hwaddr, ip_field.value(), - subnet_field.value(), gateway_field.value(), - dns_field.value(), vlan=vlan_value) + subnet_field.value(), gateway_field.value(), + dns_field.value(), vlan=vlan_value) + + return RIGHT_FORWARDS, answers + + direction, address_type = choose_primary_address_type(nic) + if direction == LEFT_BACKWARDS: + return LEFT_BACKWARDS, None + + answers = None + if address_type in ["ipv4", "dual"]: + direction, answers = get_ipv4_configuration(nic, txt, defaults, include_dns) + if direction == LEFT_BACKWARDS: + return LEFT_BACKWARDS, None + + if address_type in ["ipv6", "dual"]: + direction, answers_ipv6 = get_ipv6_configuration(nic, txt, defaults, include_dns) + if direction == LEFT_BACKWARDS: + return LEFT_BACKWARDS, None + + if answers == None: + answers = answers_ipv6 + else: + answers.modev6 = answers_ipv6.modev6 + answers.ipv6addr = answers_ipv6.ipv6addr + answers.ipv6_gateway = answers_ipv6.ipv6_gateway + if answers_ipv6.dns != None: + answers.dns = answers_ipv6.dns if answers.dns == None else answers.dns + "," + answers_ipv6.dns + return RIGHT_FORWARDS, answers def select_netif(text, conf, offer_existing=False, default=None): diff --git a/tui/repo.py b/tui/repo.py index a3ad3a7..7ecbc71 100644 --- a/tui/repo.py +++ b/tui/repo.py @@ -153,7 +153,7 @@ def get_url_location(answers, require_base_repo, is_main_install): if answers['source-address'].getPassword() is not None: passwd_field.set(answers['source-address'].getPassword()) else: - url_field.set('http://mirrors.xcp-ng.org/netinstall/8.2') + url_field.set('http://mirrors.xcp-ng.org/netinstall/8.2.1') done = False while not done: diff --git a/upgrade.py b/upgrade.py index 0456867..8634888 100644 --- a/upgrade.py +++ b/upgrade.py @@ -496,6 +496,12 @@ def completeUpgrade(self, mounts, prev_install, target_disk, backup_partnum, log nfd.write("NETWORKING_IPV6=no\n") nfd.close() netutil.disable_ipv6_module(mounts["root"]) + else: + # Enable IPV6 + ipv6_conf = open("%s/etc/sysctl.d/91-net-ipv6.conf" % mounts["root"], "w") + for i in ['all', 'default']: + ipv6_conf.write('net.ipv6.conf.%s.disable_ipv6=0\n' % i) + ipv6_conf.close() # handle the conversion of devices from aacraid to smartpqi primary_disk = self.source.getInventoryValue("PRIMARY_DISK")