]> git.proxmox.com Git - ceph.git/blame - ceph/qa/tasks/dnsmasq.py
update sources to v12.1.4
[ceph.git] / ceph / qa / tasks / dnsmasq.py
CommitLineData
31f18b77
FG
1"""
2Task for dnsmasq configuration
3"""
4import contextlib
5import logging
6
7from teuthology import misc
8from teuthology.exceptions import ConfigError
9from teuthology import contextutil
10from util import get_remote_for_role
11
12log = logging.getLogger(__name__)
13
14@contextlib.contextmanager
15def setup_dnsmasq(remote, cnames):
16 """ configure dnsmasq on the given remote, adding each cname given """
17 log.info('Configuring dnsmasq on remote %s..', remote.name)
18
19 # back up existing resolv.conf
20 resolv_conf = misc.get_file(remote, '/etc/resolv.conf')
21 # point resolv.conf to local dnsmasq
22 misc.sudo_write_file(remote, '/etc/resolv.conf',
23 "nameserver 127.0.0.1\n")
24
25 # add address entries to /etc/dnsmasq.d/ceph
26 dnsmasq = "server=8.8.8.8\nserver=8.8.4.4\n"
27 address_template = "address=/{cname}/{ip_address}\n"
28 for cname, ip_address in cnames.iteritems():
29 dnsmasq += address_template.format(cname=cname, ip_address=ip_address)
30 misc.sudo_write_file(remote, '/etc/dnsmasq.d/ceph', dnsmasq)
31
32 remote.run(args=['cat', '/etc/dnsmasq.d/ceph'])
33 # restart dnsmasq
34 remote.run(args=['sudo', 'systemctl', 'restart', 'dnsmasq'])
35 remote.run(args=['sudo', 'systemctl', 'status', 'dnsmasq'])
36 # verify dns name is set
37 remote.run(args=['ping', '-c', '4', cnames.keys()[0]])
38
39 yield
40
41 log.info('Removing dnsmasq configuration from remote %s..', remote.name)
42 # restore resolv.conf
43 misc.sudo_write_file(remote, '/etc/resolv.conf', resolv_conf)
44 # restart dnsmasq
45 remote.run(args=['sudo', 'systemctl', 'restart', 'dnsmasq'])
46
47@contextlib.contextmanager
48def task(ctx, config):
49 """
50 Configures dnsmasq to add cnames for teuthology remotes. The task expects a
51 dictionary, where each key is a role. If all cnames for that role use the
52 same address as that role, the cnames can be given as a list. For example,
53 this entry configures dnsmasq on the remote associated with client.0, adding
54 two cnames for the ip address associated with client.0:
55
56 - dnsmasq:
57 client.0:
58 - client0.example.com
59 - c0.example.com
60
61 If the addresses do not all match the given role, a dictionary can be given
62 to specify the ip address by its target role. For example:
63
64 - dnsmasq:
65 client.0:
66 client.0.example.com: client.0
67 client.1.example.com: client.1
68 """
69 # apply overrides
70 overrides = config.get('overrides', {})
71 misc.deep_merge(config, overrides.get('dnsmasq', {}))
72
73 # multiple roles may map to the same remote, so collect names by remote
74 remote_names = {}
75 for role, cnames in config.iteritems():
76 remote = get_remote_for_role(ctx, role)
77 if remote is None:
78 raise ConfigError('no remote for role %s' % role)
79
80 names = remote_names.get(remote, {})
81
82 if isinstance(cnames, list):
83 # when given a list of cnames, point to local ip
84 for cname in cnames:
85 names[cname] = remote.ip_address
86 elif isinstance(cnames, dict):
87 # when given a dict, look up the remote ip for each
88 for cname, client in cnames.iteritems():
89 r = get_remote_for_role(ctx, client)
90 if r is None:
91 raise ConfigError('no remote for role %s' % client)
92 names[cname] = r.ip_address
93
94 remote_names[remote] = names
95
96 # run a subtask for each unique remote
97 subtasks = []
98 for remote, cnames in remote_names.iteritems():
99 subtasks.extend([ lambda r=remote, cn=cnames: setup_dnsmasq(r, cn) ])
100
101 with contextutil.nested(*subtasks):
102 yield