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:
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.
Attached the cloud-init collected logs by a root user. network/ config file: DNS_STATIC_ SEARCHLIST DNS_STATIC_ SERVERS DNS_FORWARDER DNS_POLICY= ''
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/
# NETCONFIG_
# NETCONFIG_
# NETCONFIG_
# or disable DNS configuration updates via netconfig by setting:
# NETCONFIG_
#
# 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 00:0d:3a: 6e:6f:8f
# Created by cloud-init on instance boot automatically, do not edit.
#
BOOTPROTO=dhcp
DEVICE=eth0
HWADDR=
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 ("") isfile( existing_ dns_path) : conf.ResolvConf (util.load_ file(existing_ dns_path) ) state.dns_ nameservers:
content. add_nameserver( nameserver) state.dns_ searchdomains:
content. add_search_ domain( searchdomain)
if existing_dns_path and os.path.
content = resolv_
for nameserver in network_
for searchdomain in network_
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:
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) 'nameservers' ).get(' search' , []) 'nameservers' ).get(' addresses' , [])
name_ cmd = {'type': 'nameserver'}
name_ cmd.update( {'search' : search}) update( {'addresses' : dns}) update( {'address' : dns})
LOG. debug(' v2(nameserver) -> v1(nameserver) :\n%s', name_cmd)
self. handle_ nameserver( name_cmd)
if 'nameservers' in cfg:
search = cfg.get(
dns = cfg.get(
if len(search) > 0:
if len(dns) > 0:
- name_cmd.
+ name_cmd.
Note the requirement of the "address" key in the handle_server function command_ keys([' address' ]) nameserver( self, command):
@ensure_
def handle_
With my above changes, cloud-init managed to write the correct /etc/resolv.conf which contains the name server and the search domain.