← Back to team overview

cloud-init-dev team mailing list archive

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