]>
Commit | Line | Data |
---|---|---|
31f18b77 FG |
1 | """ |
2 | Task for dnsmasq configuration | |
3 | """ | |
4 | import contextlib | |
5 | import logging | |
6 | ||
7 | from teuthology import misc | |
8 | from teuthology.exceptions import ConfigError | |
9 | from teuthology import contextutil | |
10 | from util import get_remote_for_role | |
11 | ||
12 | log = logging.getLogger(__name__) | |
13 | ||
14 | @contextlib.contextmanager | |
15 | def 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 | |
48 | def 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 |