write one resolv config
When systemd-resolved is enabled dns info is only written to /etc/systemd/resolved.conf. If systemd-resolved is not enabled dns info is only written to /etc/resolv.conf. We do not write to /etc/resolv.conf if systemd-resolved is enabled because /etc/resolv.conf is a symlink pointing to ../run/systemd/resolve/stub-resolv.conf. This target file does not exist before systemd-resolved is run so glean would fail with: 'FileNotFoundError: [Errno 2] No such file or directory: '/etc/resolv.conf' Change-Id: I644e0b50cfb7bb00a108160b99c0c1359d6a9dd4 Signed-off-by: Matthew Thode <mthode@mthode.org>
This commit is contained in:
parent
4826490245
commit
a39e9b3d21
23
glean/cmd.py
23
glean/cmd.py
|
@ -945,15 +945,26 @@ def write_debian_interfaces(interfaces, sys_interfaces):
|
|||
|
||||
|
||||
def write_dns_info(dns_servers):
|
||||
# will fail on non-systemd systems (what we want)
|
||||
# will exit 1 if not enabled (what we want)
|
||||
# will exit 0 if enabled (or indirectly enabled)
|
||||
resolved_enabled = os.system('systemctl is-enabled systemd-resolved')
|
||||
resolve_confs = {}
|
||||
resolv_nameservers = ""
|
||||
for server in dns_servers:
|
||||
resolv_nameservers += "nameserver {0}\n".format(server)
|
||||
resolve_confs['/etc/resolv.conf'] = resolv_nameservers
|
||||
# set up resolved if available
|
||||
if os.path.isfile('/etc/systemd/resolved.conf'):
|
||||
# write resolv.conf if the file can be written to (if symlink is pointing
|
||||
# to a non-existant file, writing will fail), will return false if the
|
||||
# pointer is incomplete
|
||||
if resolved_enabled != 0:
|
||||
log.debug("resolved not in use, writing to /etc/resolv.conf")
|
||||
resolv_nameservers = ""
|
||||
for server in dns_servers:
|
||||
resolv_nameservers += "nameserver {0}\n".format(server)
|
||||
resolve_confs['/etc/resolv.conf'] = resolv_nameservers
|
||||
# set up resolved if enabled
|
||||
if resolved_enabled == 0:
|
||||
log.debug("resolved in use, writing to /etc/systemd/resolved.conf")
|
||||
# read the existing config so we only overwrite what's needed
|
||||
resolved_conf = configparser.ConfigParser()
|
||||
resolved_conf.optionxform = str
|
||||
resolved_conf.read('/etc/systemd/resolved.conf')
|
||||
# create config section if not created
|
||||
if not resolved_conf.has_section('Resolve'):
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
### Write /etc/resolv.conf
|
||||
nameserver 72.3.128.241
|
||||
nameserver 72.3.128.240
|
||||
### Write /etc/systemd/resolved.conf
|
||||
[Resolve]
|
||||
DNS = 72.3.128.241 72.3.128.240
|
||||
|
||||
### Write /etc/systemd/network/eth0.network
|
||||
# Automatically generated, do not edit
|
||||
[Match]
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
### Write /etc/resolv.conf
|
||||
nameserver 69.20.0.196
|
||||
nameserver 69.20.0.164
|
||||
### Write /etc/systemd/resolved.conf
|
||||
[Resolve]
|
||||
DNS = 69.20.0.196 69.20.0.164
|
||||
|
||||
### Write /etc/systemd/network/eth0.network
|
||||
# Automatically generated, do not edit
|
||||
[Match]
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
### Write /etc/resolv.conf
|
||||
nameserver 69.20.0.196
|
||||
nameserver 69.20.0.164
|
||||
### Write /etc/systemd/resolved.conf
|
||||
[Resolve]
|
||||
DNS = 69.20.0.196 69.20.0.164
|
||||
|
||||
### Write /etc/systemd/network/eth0.network
|
||||
# Automatically generated, do not edit
|
||||
[Match]
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
### Write /etc/resolv.conf
|
||||
nameserver 72.3.128.241
|
||||
nameserver 72.3.128.240
|
||||
### Write /etc/systemd/resolved.conf
|
||||
[Resolve]
|
||||
DNS = 72.3.128.241 72.3.128.240
|
||||
|
||||
### Write /etc/systemd/network/eth0.network
|
||||
# Automatically generated, do not edit
|
||||
[Match]
|
||||
|
|
|
@ -142,6 +142,13 @@ class TestGlean(base.BaseTestCase):
|
|||
return False
|
||||
return real_path_exists(path)
|
||||
|
||||
def os_system_side_effect(self, distro, command):
|
||||
if distro.lower() != 'networkd' and \
|
||||
command == 'systemctl is-enabled systemd-resolved':
|
||||
return 3
|
||||
else:
|
||||
return 0
|
||||
|
||||
@mock.patch('subprocess.call', return_value=0, new_callable=mock.Mock)
|
||||
@mock.patch('os.fsync', return_value=0, new_callable=mock.Mock)
|
||||
@mock.patch('os.unlink', return_value=0, new_callable=mock.Mock)
|
||||
|
@ -183,6 +190,10 @@ class TestGlean(base.BaseTestCase):
|
|||
self.os_listdir_side_effect, provider)
|
||||
mock_open.side_effect = functools.partial(
|
||||
self.open_side_effect, provider)
|
||||
# we want os.system to return False for specific commands if
|
||||
# running networkd
|
||||
mock_os_system.side_effect = functools.partial(
|
||||
self.os_system_side_effect, distro)
|
||||
|
||||
# default args
|
||||
argv = ['--hostname']
|
||||
|
@ -234,6 +245,9 @@ class TestGlean(base.BaseTestCase):
|
|||
if skip_dns and '/etc/resolv.conf' in dest:
|
||||
self.assertNotIn(dest, self.file_handle_mocks)
|
||||
continue
|
||||
if skip_dns and '/etc/systemd/resolved.conf' in dest:
|
||||
self.assertNotIn(dest, self.file_handle_mocks)
|
||||
continue
|
||||
self.assertIn(dest, self.file_handle_mocks)
|
||||
write_handle = self.file_handle_mocks[dest].write
|
||||
write_handle.assert_called_once_with(content)
|
||||
|
@ -279,6 +293,10 @@ class TestGlean(base.BaseTestCase):
|
|||
self._assert_distro_provider(self.distro, self.style,
|
||||
'eth0', skip_dns=True)
|
||||
|
||||
def test_glean_systemd_resolved(self):
|
||||
with mock.patch('glean.systemlock.Lock'):
|
||||
self._assert_distro_provider(self.distro, self.style, 'eth0')
|
||||
|
||||
def test_glean_skip_dns(self):
|
||||
with mock.patch('glean.systemlock.Lock'):
|
||||
self._assert_distro_provider(
|
||||
|
|
Loading…
Reference in New Issue