cloud-init-dev team mailing list archive
-
cloud-init-dev team
-
Mailing list archive
-
Message #00567
Re: [Merge] lp:~shraddha-pandhe/cloud-init/cloud-init-ipv6-support into lp:cloud-init
Diff comments:
> === modified file 'cloudinit/distros/net_util.py'
> --- cloudinit/distros/net_util.py 2014-01-24 21:20:54 +0000
> +++ cloudinit/distros/net_util.py 2014-11-21 22:24:21 +0000
> @@ -113,6 +113,10 @@
> for info in ifaces:
> if 'iface' not in info:
> continue
> + use_ipv6 = False
> + # Check if current device has an ipv6 IP
> + if 'inet6' in info['iface']:
> + use_ipv6 = True
> iface_details = info['iface'].split(None)
> dev_name = None
> if len(iface_details) >= 1:
> @@ -122,6 +126,7 @@
> if not dev_name:
> continue
> iface_info = {}
> + iface_info['ipv6'] = {}
> if len(iface_details) >= 3:
> proto_type = iface_details[2].strip().lower()
> # Seems like this can be 'loopback' which we don't
> @@ -129,26 +134,39 @@
> if proto_type in ['dhcp', 'static']:
> iface_info['bootproto'] = proto_type
> # These can just be copied over
> - for k in ['netmask', 'address', 'gateway', 'broadcast']:
> - if k in info:
> - val = info[k].strip().lower()
> - if val:
> - iface_info[k] = val
> - # Name server info provided??
> - if 'dns-nameservers' in info:
> - iface_info['dns-nameservers'] = info['dns-nameservers'].split()
> - # Name server search info provided??
> - if 'dns-search' in info:
> - iface_info['dns-search'] = info['dns-search'].split()
> - # Is any mac address spoofing going on??
> - if 'hwaddress' in info:
> - hw_info = info['hwaddress'].lower().strip()
> - hw_split = hw_info.split(None, 1)
> - if len(hw_split) == 2 and hw_split[0].startswith('ether'):
> - hw_addr = hw_split[1]
> - if hw_addr:
> - iface_info['hwaddress'] = hw_addr
> - real_ifaces[dev_name] = iface_info
> + if use_ipv6:
> + for k in ['address', 'gateway']:
> + if k in info:
> + val = info[k].strip().lower()
> + if val:
> + iface_info['ipv6'][k] = val
> + else:
> + for k in ['netmask', 'address', 'gateway', 'broadcast']:
> + if k in info:
> + val = info[k].strip().lower()
> + if val:
> + iface_info[k] = val
> + # Name server info provided??
> + if 'dns-nameservers' in info:
> + iface_info['dns-nameservers'] = info['dns-nameservers'].split()
> + # Name server search info provided??
> + if 'dns-search' in info:
> + iface_info['dns-search'] = info['dns-search'].split()
> + # Is any mac address spoofing going on??
> + if 'hwaddress' in info:
> + hw_info = info['hwaddress'].lower().strip()
> + hw_split = hw_info.split(None, 1)
> + if len(hw_split) == 2 and hw_split[0].startswith('ether'):
> + hw_addr = hw_split[1]
> + if hw_addr:
> + iface_info['hwaddress'] = hw_addr
> +
> + # If ipv6 is enabled, device will have multiple IPs.
> + # Update the dictionary instead of overwriting it
> + if dev_name in real_ifaces:
> + real_ifaces[dev_name].update(iface_info)
> + else:
> + real_ifaces[dev_name] = iface_info
> # Check for those that should be started on boot via 'auto'
> for (cmd, args) in entries:
> if cmd == 'auto':
> @@ -160,4 +178,6 @@
> dev_name = args[0].strip().lower()
> if dev_name in real_ifaces:
> real_ifaces[dev_name]['auto'] = True
> + if cmd == 'iface' and 'inet6' in args:
> + real_ifaces[dev_name]['inet6'] = True
indentation seems off here. to many spaces?
> return real_ifaces
>
> === modified file 'cloudinit/distros/rhel.py'
> --- cloudinit/distros/rhel.py 2014-10-17 19:32:41 +0000
> +++ cloudinit/distros/rhel.py 2014-11-21 22:24:21 +0000
> @@ -71,6 +71,7 @@
> nameservers = []
> searchservers = []
> dev_names = entries.keys()
> + use_ipv6 = False
> for (dev, info) in entries.iteritems():
> net_fn = self.network_script_tpl % (dev)
> net_cfg = {
> @@ -83,6 +84,13 @@
> 'MACADDR': info.get('hwaddress'),
> 'ONBOOT': _make_sysconfig_bool(info.get('auto')),
> }
> + if info.get('inet6'):
> + use_ipv6 = True
> + net_cfg.update({
> + 'IPV6INIT': _make_sysconfig_bool(True),
> + 'IPV6ADDR': info.get('ipv6').get('address'),
> + 'IPV6_DEFAULTGW': info.get('ipv6').get('gateway'),
> + })
> rhel_util.update_sysconfig_file(net_fn, net_cfg)
> if 'dns-nameservers' in info:
> nameservers.extend(info['dns-nameservers'])
> @@ -95,6 +103,10 @@
> net_cfg = {
> 'NETWORKING': _make_sysconfig_bool(True),
> }
> + # If IPv6 interface present, enable ipv6 networking
> + if use_ipv6:
> + net_cfg['NETWORKING_IPV6'] = _make_sysconfig_bool(True)
> + net_cfg['IPV6_AUTOCONF'] = _make_sysconfig_bool(False)
> rhel_util.update_sysconfig_file(self.network_conf_fn, net_cfg)
> return dev_names
>
>
> === modified file 'cloudinit/netinfo.py'
> --- cloudinit/netinfo.py 2014-09-12 21:22:29 +0000
> +++ cloudinit/netinfo.py 2014-11-21 22:24:21 +0000
> @@ -72,6 +72,7 @@
> "bcast:": "bcast", "broadcast": "bcast",
> "mask:": "mask", "netmask": "mask",
> "hwaddr": "hwaddr", "ether": "hwaddr",
> + "scope": "scope",
> }
> for origfield, field in ifconfigfields.items():
> target = "%s%s" % (field, fieldpost)
> @@ -96,7 +97,12 @@
>
> def route_info():
> (route_out, _err) = util.subp(["netstat", "-rn"])
> - routes = []
> + (route_out6, _err6) = util.subp(["netstat", "-A inet6", "-n"])
> +
> + routes = {}
> + routes['ipv4'] = []
> + routes['ipv6'] = []
> +
> entries = route_out.splitlines()[1:]
> for line in entries:
> if not line:
> @@ -132,7 +138,26 @@
> 'iface': toks[7],
> }
>
> - routes.append(entry)
> + routes['ipv4'].append(entry)
> +
> + entries6 = route_out6.splitlines()[1:]
> + for line in entries6:
> + if not line:
> + continue
> + toks = line.split()
> +
> + if (len(toks) < 6 or toks[0] == "Kernel" or
> + toks[0] == "Proto" or toks[0] == "Active"):
> + continue
> + entry = {
> + 'proto': toks[0],
> + 'recv-q': toks[1],
> + 'send-q': toks[2],
> + 'local address': toks[3],
> + 'foreign address': toks[4],
> + 'state': toks[5],
> + }
> + routes['ipv6'].append(entry)
> return routes
>
>
> @@ -156,10 +181,12 @@
> lines.append(util.center("Net device info failed", '!', 80))
> netdev = None
> if netdev is not None:
> - fields = ['Device', 'Up', 'Address', 'Mask', 'Hw-Address']
> + fields = ['Device', 'Up', 'Address', 'Mask', 'Scope', 'Hw-Address']
> tbl = PrettyTable(fields)
> for (dev, d) in netdev.iteritems():
> - tbl.add_row([dev, d["up"], d["addr"], d["mask"], d["hwaddr"]])
> + tbl.add_row([dev, d["up"], d["addr"], d["mask"], ".", d["hwaddr"]])
> + if d["addr6"]:
> + tbl.add_row([dev, d["up"], d["addr6"], ".", d["scope6"], d["hwaddr"]])
> netdev_s = tbl.get_string()
> max_len = len(max(netdev_s.splitlines(), key=len))
> header = util.center("Net device info", "+", max_len)
> @@ -176,15 +203,30 @@
> util.logexc(LOG, "Route info failed: %s" % e)
> routes = None
> if routes is not None:
> - fields = ['Route', 'Destination', 'Gateway',
> + fields_v4 = ['Route', 'Destination', 'Gateway',
> 'Genmask', 'Interface', 'Flags']
> - tbl = PrettyTable(fields)
> - for (n, r) in enumerate(routes):
> +
> + if routes.get('ipv6') is not None:
> + fields_v6 = ['Route', 'Proto', 'Recv-Q', 'Send-Q', 'Local Address',
> + 'Foreign Address', 'State']
> +
> + tbl_v4 = PrettyTable(fields_v4)
> + for (n, r) in enumerate(routes.get('ipv4')):
> route_id = str(n)
> - tbl.add_row([route_id, r['destination'],
> + tbl_v4.add_row([route_id, r['destination'],
> r['gateway'], r['genmask'],
> r['iface'], r['flags']])
> - route_s = tbl.get_string()
> + route_s = tbl_v4.get_string()
> + if fields_v6:
> + tbl_v6 = PrettyTable(fields_v6)
> + for (n, r) in enumerate(routes.get('ipv6')):
> + route_id = str(n)
> + tbl_v6.add_row([route_id, r['proto'],
> + r['recv-q'], r['send-q'],
> + r['local address'], r['foreign address'],
> + r['state']])
> + route_s = route_s + tbl_v6.get_string()
> +
> max_len = len(max(route_s.splitlines(), key=len))
> header = util.center("Route info", "+", max_len)
> lines.extend([header, route_s])
>
> === modified file 'tests/unittests/test_distros/test_netconfig.py'
> --- tests/unittests/test_distros/test_netconfig.py 2014-10-11 01:54:28 +0000
> +++ tests/unittests/test_distros/test_netconfig.py 2014-11-21 22:24:21 +0000
> @@ -30,6 +30,24 @@
> iface eth1 inet dhcp
> '''
>
> +BASE_NET_CFG_IPV6 = '''
> +auto lo
> +iface lo inet loopback
> +
> +auto eth0
> +iface eth0 inet static
> + address 192.168.1.5
> + netmask 255.255.255.0
> + network 192.168.0.0
> + broadcast 192.168.1.0
> + gateway 192.168.1.254
> +
> +iface eth0 inet6 static
> + address 2607:f0d0:1002:0011::2
> + netmask 64
> + gateway 2607:f0d0:1002:0011::1
> +'''
> +
>
> class WriteBuffer(object):
> def __init__(self):
> @@ -174,6 +192,81 @@
> self.assertCfgEquals(expected_buf, str(write_buf))
> self.assertEquals(write_buf.mode, 0644)
>
> + def test_write_ipv6_rhel(self):
> + rh_distro = self._get_distro('rhel')
> + write_mock = self.mocker.replace(util.write_file,
> + spec=False, passthrough=False)
> + load_mock = self.mocker.replace(util.load_file,
> + spec=False, passthrough=False)
> + exists_mock = self.mocker.replace(os.path.isfile,
> + spec=False, passthrough=False)
> +
> + write_bufs = {}
> +
> + def replace_write(filename, content, mode=0644, omode="wb"):
> + buf = WriteBuffer()
> + buf.mode = mode
> + buf.omode = omode
> + buf.write(content)
> + write_bufs[filename] = buf
> +
> + exists_mock(mocker.ARGS)
> + self.mocker.count(0, None)
> + self.mocker.result(False)
> +
> + load_mock(mocker.ARGS)
> + self.mocker.count(0, None)
> + self.mocker.result('')
> +
> + for _i in range(0, 2):
> + write_mock(mocker.ARGS)
> + self.mocker.call(replace_write)
> +
> + write_mock(mocker.ARGS)
> + self.mocker.call(replace_write)
> +
> + self.mocker.replay()
> + rh_distro.apply_network(BASE_NET_CFG_IPV6, False)
> +
> + self.assertEquals(len(write_bufs), 3)
> + self.assertIn('/etc/sysconfig/network-scripts/ifcfg-lo', write_bufs)
> + write_buf = write_bufs['/etc/sysconfig/network-scripts/ifcfg-lo']
> + expected_buf = '''
> +DEVICE="lo"
> +ONBOOT=yes
> +'''
> + self.assertCfgEquals(expected_buf, str(write_buf))
> + self.assertEquals(write_buf.mode, 0644)
> +
> + self.assertIn('/etc/sysconfig/network-scripts/ifcfg-eth0', write_bufs)
> + write_buf = write_bufs['/etc/sysconfig/network-scripts/ifcfg-eth0']
> + expected_buf = '''
> +DEVICE="eth0"
> +BOOTPROTO="static"
> +NETMASK="255.255.255.0"
> +IPADDR="192.168.1.5"
> +ONBOOT=yes
> +GATEWAY="192.168.1.254"
> +BROADCAST="192.168.1.0"
> +IPV6INIT=yes
> +IPV6ADDR="2607:f0d0:1002:0011::2"
> +IPV6_DEFAULTGW="2607:f0d0:1002:0011::1"
> +'''
> + self.assertCfgEquals(expected_buf, str(write_buf))
> + self.assertEquals(write_buf.mode, 0644)
> +
> + self.assertIn('/etc/sysconfig/network', write_bufs)
> + write_buf = write_bufs['/etc/sysconfig/network']
> + expected_buf = '''
> +# Created by cloud-init v. 0.7
> +NETWORKING=yes
> +NETWORKING_IPV6=yes
> +IPV6_AUTOCONF=no
> +'''
> + self.assertCfgEquals(expected_buf, str(write_buf))
> + self.assertEquals(write_buf.mode, 0644)
> +
> +
> def test_simple_write_freebsd(self):
> fbsd_distro = self._get_distro('freebsd')
> util_mock = self.mocker.replace(util.write_file,
>
--
https://code.launchpad.net/~shraddha-pandhe/cloud-init/cloud-init-ipv6-support/+merge/242547
Your team cloud init development team is requested to review the proposed merge of lp:~shraddha-pandhe/cloud-init/cloud-init-ipv6-support into lp:cloud-init.
References