Comment 5 for bug 1843634

Revision history for this message
Moustafa Moustafa (momousta) wrote :

Attached the cloud-init collected logs by a root user.
Here is the contents of the /etc/resolv.conf
; Created by cloud-init on instance boot automatically, do not edit.
;
### /etc/resolv.conf file autogenerated by netconfig!
#
# Before you change this file manually, consider to define the
# static DNS configuration using the following variables in the
# /etc/sysconfig/network/config file:
# NETCONFIG_DNS_STATIC_SEARCHLIST
# NETCONFIG_DNS_STATIC_SERVERS
# NETCONFIG_DNS_FORWARDER
# or disable DNS configuration updates via netconfig by setting:
# NETCONFIG_DNS_POLICY=''
#
# See also the netconfig(8) manual page and other documentation.
#
# Note: Manual change of this file disables netconfig too, but
# may get lost when this file contains comments or empty lines
# only, the netconfig settings are same with settings in this
# file and in case of a "netconfig update -f" call.
#
### Please remove (at least) this line when you modify the file!

And the contents of /etc/sysconfig/network/ifcfg-eth0
# Created by cloud-init on instance boot automatically, do not edit.
#
BOOTPROTO=dhcp
DEVICE=eth0
HWADDR=00:0d:3a:6e:6f:8f
NM_CONTROLLED=no
ONBOOT=yes
STARTMODE=auto
TYPE=Ethernet
USERCTL=no

Also please note that I am running "ifup eth0" to be able to ssh into the machine, but this is just a local change.

Cloud-init is writing a /etc/resolv.conf that only has commented lines and the cloud-init header, When i debugged the following code in sysconfig.py

        content = resolv_conf.ResolvConf("")
        if existing_dns_path and os.path.isfile(existing_dns_path):
            content = resolv_conf.ResolvConf(util.load_file(existing_dns_path))
        for nameserver in network_state.dns_nameservers:
            content.add_nameserver(nameserver)
        for searchdomain in network_state.dns_searchdomains:
            content.add_search_domain(searchdomain)
        if not str(content):
            return None

the content is copied from the old /etc/resolv.conf but there is no name servers or search domains that are added to the content from the network_state.

Who is responsible for adding the name server and the search domain to the network_state ?

When I manually added explicit name server and search domain from DataSourceAzure.py in the parse_network_config function as following:

            netconfig = {'version': 2, 'ethernets': {}}
            LOG.debug('Azure: generating network configuration from IMDS')
            netconfig['nameservers'] = {}
            netconfig['nameservers']['addresses'] = '168.63.129.16'
            netconfig['nameservers']['search'] = 'xkf00b0rtzgejkug4xc2pcinre.xx.internal.cloudapp.net'
            network_metadata = imds_metadata['network']

And then changed the _V2_common in network_state.py to build the name_cmd with the "address" key instead of the "addresses" key. Because the "address" key is required in the handle_nameserver function which is called from _v2_common as following:

    def _v2_common(self, cfg):
        LOG.debug('v2_common: handling config:\n%s', cfg)
        if 'nameservers' in cfg:
            search = cfg.get('nameservers').get('search', [])
            dns = cfg.get('nameservers').get('addresses', [])
            name_cmd = {'type': 'nameserver'}
            if len(search) > 0:
                name_cmd.update({'search': search})
            if len(dns) > 0:
- name_cmd.update({'addresses': dns})
+ name_cmd.update({'address': dns})
            LOG.debug('v2(nameserver) -> v1(nameserver):\n%s', name_cmd)
            self.handle_nameserver(name_cmd)

Note the requirement of the "address" key in the handle_server function
    @ensure_command_keys(['address'])
    def handle_nameserver(self, command):

With my above changes, cloud-init managed to write the correct /etc/resolv.conf which contains the name server and the search domain.