bionic: DNS search domains lost from cloud-init to netplan
This bug was originally filed in Launchpad as LP: #1774540
Launchpad details
affected_projects = [] assignee = None assignee_name = None date_closed = None date_created = 2018-06-01T00:30:23.851349+00:00 date_fix_committed = None date_fix_released = None id = 1774540 importance = medium is_complete = False lp_url = https://bugs.launchpad.net/cloud-init/+bug/1774540 milestone = None owner = fo0bar owner_name = Ryan Finnie private = False status = confirmed submitter = fo0bar submitter_name = Ryan Finnie tags = [] duplicates = []
Launchpad user Ryan Finnie(fo0bar) wrote on 2018-06-01T00:30:23.851349+00:00
On a deployed node with a MAAS datasource, /etc/cloud/cloud.cfg.d/50-curtin-networking.cfg contains:
network: config: - id: enp1s0 mac_address: 52:54:00:9a:b4:64 mtu: 1500 name: enp1s0 subnets: - address: 10.48.7.48/21 dns_nameservers: - 10.48.0.5 gateway: 10.48.0.1 type: static type: physical - address: - 10.48.0.5 search: - bos01.canonistack.internal type: nameserver version: 1
But the generated /etc/netplan/50-cloud-init.yaml contains no search domains under nameservers for the interface:
This file is generated from information provided by
the datasource. Changes to it will not persist across an instance.
To disable cloud-init's network configuration capabilities, write a file
/etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
network: {config: disabled}
network: version: 2 ethernets: enp1s0: addresses: - 10.48.7.48/21 gateway4: 10.48.0.1 match: macaddress: 52:54:00:9a:b4:64 mtu: 1500 nameservers: addresses: - 10.48.0.5 set-name: enp1s0
Related bugs:
- bug 1750884: /etc/resolv.conf not configured correctly in Bionic, leads to no DNS resolution
Launchpad user Scott Moser(smoser) wrote on 2018-07-13T16:34:50.575083+00:00
This is related to bug 1750884. In netplan/systemd-networkd there is no such thing as "global" dns. The decision was made that although users configured dns globally for the vast majority of the last 30 years, we were not going to support that behavior any more in netplan or systemd-networkd.
Under that bug, though, cloud-init worked around by copying the 'nameserver' settings from the global section to each interface.
Curiously, though, we did not copy the search entries.
I am not sure why.
Launchpad user Ryan Harper(raharper) wrote on 2018-07-16T14:37:29.872561+00:00
The searchpath is copied. In netplan , the config namespace is:
nameservers:
- addresses: [x, y]
- search: [a, b]
The relevant code in cloudinit/net/netplan.py:
inject global nameserver values under each all interface which
has addresses and do not already have a DNS configuration
if nameservers or searchdomains:
nscfg = {'addresses': nameservers, 'search': searchdomains}
for section in [ethernets, wifis, bonds, bridges, vlans]:
for _name, cfg in section.items():
if 'nameservers' in cfg or 'addresses' not in cfg:
continue
cfg.update({'nameservers': nscfg})
Note the nscfg contains both the nameservers and the searchdomains.
Launchpad user Scott Moser(smoser) wrote on 2018-07-16T16:09:10.049710+00:00
@Ryan,
I marked this confirmed because the issue reproduces with current master and 'net-convert.py'. I think the issue here is that the subnet had dns_nameservers. but 'search' was only declared at the global level.
The patch http://paste.ubuntu.com/p/k3hjFPv5qD/ will fix this issue.
$ cat my.cfg network: config:
- id: enp1s0
mac_address: 52:54:00:9a:b4:64
mtu: 1500
name: enp1s0
subnets:
- address: 10.48.7.48/21
dns_nameservers:
- 10.48.0.5 gateway: 10.48.0.1 type: static type: physical
- address: 10.48.7.48/21
dns_nameservers:
- address:
- 10.48.0.5 search:
- bos01.canonistack.internal type: nameserver version: 1
$ PYTHONPATH=$PWD ./tools/net-convert.py --network-data=my.cfg --kind=yaml -d out.d --output-kind=netplan
$ cat out.d/etc/netplan/50-cloud-init.yaml
network: version: 2 ethernets: enp1s0: addresses: - 10.48.7.48/21 gateway4: 10.48.0.1 match: macaddress: 52:54:00:9a:b4:64 mtu: 1500 nameservers: addresses: - 10.48.0.5 set-name: enp1s0
It looks like the attached patch fixes the issue but was never merged. I've cleaned up the patch, and I see this output which appears to correct the issue:
network:
config:
- id: enp1s0
mac_address: 52:54:00:9a:b4:64
mtu: 1500
name: enp1s0
subnets:
- address: 10.48.7.48/21
dns_nameservers:
- 10.48.0.5
gateway: 10.48.0.1
type: static
type: physical
- address:
- 10.48.0.5
search:
- bos01.canonistack.internal
type: nameserver
version: 1
the patch:
diff --git a/cloudinit/net/netplan.py b/cloudinit/net/netplan.py
index 43dce4477..620cfd77b 100644
--- a/cloudinit/net/netplan.py
+++ b/cloudinit/net/netplan.py
@@ -535,9 +535,14 @@ class Renderer(renderer.Renderer):
nscfg = {"addresses": nameservers, "search": searchdomains}
for section in [ethernets, wifis, bonds, bridges, vlans]:
for _name, cfg in section.items():
- if "nameservers" in cfg or "addresses" not in cfg:
+ if "addresses" not in cfg:
continue
- cfg.update({"nameservers": nscfg})
+ if "nameservers" not in cfg:
+ cfg["nameservers"] = nscfg.copy()
+ else:
+ for k, v in nscfg.items():
+ if not cfg["nameservers"].get(k):
+ cfg["nameservers"][k] = v
# workaround yaml dictionary key sorting when dumping
def _render_section(name, section):
Setting this to new to re-triage since we have a bug and an attached fix.