remote.run(args=['rm', path])
@contextlib.contextmanager
-def setup_dnsmasq(remote, testdir, cnames, table):
- """ configure dnsmasq on the given remote, adding each cname given """
- log.info('Configuring dnsmasq on remote %s..', remote.name)
- # banner first
- dnsmasq = ["# This file is generated by dnsmasq teuthology task", ""]
-
- # lookup previously used nameservers for the remote in the table
- servers = table.get(remote.name, {}).get('nameserver', None)
- if servers:
- log.info('Reusing nameservers: %s', servers)
- dnsmasq.extend(f"server={a}" for a in servers)
- else:
- log.info('No predefined nameservers found, using 8.8.x.x')
- dnsmasq.extend(["server=8.8.8.8", "server=8.8.4.4"])
-
+def configure_dnsmasq(remote, path, cnames):
+ """
+ configure dnsmasq on the given remote, adding each cname given
+ """
+ data = """# This file is generated by dnsmasq teuthology task
+"""
for cname, ip_address in cnames.items():
- dnsmasq.append(f"address=/{cname}/{ip_address}")
+ data += f"address=/.{cname}/{ip_address}\n"
- dnsmasq.append('')
- dnsmasq_data = "\n".join(dnsmasq)
- dnsmasq_path = '/etc/dnsmasq.d/ceph'
- remote.sudo_write_file(dnsmasq_path, dnsmasq_data)
- # restore selinux context if necessary
- remote.run(args=['sudo', 'restorecon', dnsmasq_path], check_status=False)
+ remote.sudo_write_file(path, data)
+ remote.run(args=['sudo', 'restorecon', path], check_status=False)
+ remote.sh(f'cat {path}')
+ try:
+ yield
+ finally:
+ remote.run(args=['sudo', 'rm', path])
- # restart dnsmasq
- remote.run(args=['sudo', 'systemctl', 'restart', 'dnsmasq'])
- # some pause is required for dnsmasq to become operational,
- # though, trying to just print out the config now instead
- remote.sh(f'cat {dnsmasq_path}')
- # verify dns name is set
- remote.run(args=['ping', '-c', '4', next(iter(cnames.keys()))])
+@contextlib.contextmanager
+def configure_network_manager(remote):
+ """
+ enable NetworkManager's dnsmasq plugin
+ """
+ path = '/etc/NetworkManager/conf.d/dnsmasq.conf'
+ data = """# This file is generated by dnsmasq teuthology task
+[main]
+dns=dnsmasq
+"""
+ remote.sudo_write_file(path, data)
+ remote.run(args=['sudo', 'restorecon', path], check_status=False)
+ remote.run(args=['sudo', 'systemctl', 'restart', 'NetworkManager'])
+ remote.sh(f'cat {path}')
+ try:
+ yield
+ finally:
+ remote.run(args=['sudo', 'rm', path])
+ remote.run(args=['sudo', 'systemctl', 'restart', 'NetworkManager'])
+@contextlib.contextmanager
+def configure_systemd_resolved(remote, cnames):
+ """
+ configure systemd-resolved to search for listed cnames through dnsmasq at 127.0.0.1
+ """
+ dir = '/etc/systemd/resolved.conf.d'
+ remote.sh(f'sudo mkdir {dir}')
+
+ path = dir + '/dnsmasq.conf'
+ domains = ' '.join([f'~{cname}' for cname in cnames.keys()])
+ data = f"""# This file is generated by dnsmasq teuthology task
+[Resolve]
+DNS=127.0.0.1
+Domains={domains}
+"""
+ remote.sudo_write_file(path, data)
+ remote.run(args=['sudo', 'restorecon', path], check_status=False)
+ remote.run(args=['sudo', 'systemctl', 'restart', 'dnsmasq'])
+ remote.run(args=['sudo', 'systemctl', 'restart', 'systemd-resolved'])
+ remote.sh(f'cat {path}')
try:
yield
finally:
- log.info('Removing dnsmasq configuration from remote %s..', remote.name)
- # remove /etc/dnsmasq.d/ceph
- remote.run(args=['sudo', 'rm', dnsmasq_path])
- # restart dnsmasq
- remote.run(args=['sudo', 'systemctl', 'restart', 'dnsmasq'])
+ remote.run(args=['sudo', 'rm', path])
+ remote.run(args=['sudo', 'systemctl', 'restart', 'systemd-resolved'])
+
+@contextlib.contextmanager
+def test_dns_names(remote, cnames):
+ """ verify that ping can resolve the configured names """
+ for cname in cnames.keys():
+ remote.run(args=['ping', '-c', '4', cname])
+ yield
@contextlib.contextmanager
def task(ctx, config):
remote_names[remote] = names
- testdir = misc.get_testdir(ctx)
- resolv_bak = '/'.join((testdir, 'resolv.bak'))
- resolv_tmp = '/'.join((testdir, 'resolv.tmp'))
- resolv_tbl = dict() # { remote.name -> nameserver list } lookup table
-
# run subtasks for each unique remote
subtasks = []
for remote, cnames in remote_names.items():
subtasks.extend([ lambda r=remote: install_dnsmasq(r) ])
- subtasks.extend([ lambda r=remote: backup_resolv(r, resolv_bak, resolv_tbl) ])
- subtasks.extend([ lambda r=remote: replace_resolv(r, resolv_tmp, resolv_tbl) ])
- subtasks.extend([ lambda r=remote, cn=cnames: setup_dnsmasq(r, testdir, cn, resolv_tbl) ])
+ if remote.os.package_type == 'rpm':
+ path = '/etc/NetworkManager/dnsmasq.d/ceph.conf'
+ subtasks.extend([ lambda r=remote, p=path, cn=cnames: configure_dnsmasq(r, p, cn) ])
+ subtasks.extend([ lambda r=remote: configure_network_manager(r) ])
+ else:
+ path = '/etc/dnsmasq.d/ceph.conf'
+ subtasks.extend([ lambda r=remote, p=path, cn=cnames: configure_dnsmasq(r, p, cn) ])
+ subtasks.extend([ lambda r=remote, cn=cnames: configure_systemd_resolved(r, cn) ])
+ subtasks.extend([ lambda r=remote, cn=cnames: test_dns_names(r, cn) ])
with contextutil.nested(*subtasks):
yield