From b33bcd58e568d8ca5a98bfc8dc29ff5b09f38b2d Mon Sep 17 00:00:00 2001 From: Mark McLoughlin Date: Fri, 23 Nov 2012 12:38:15 +0000 Subject: [PATCH] Make nova-dhcpbridge use CONFIG_FILE over FLAGFILE nova-dhcpbridge's FLAGFILE environment variable is one of the few remaining references we have to "flags". Switching to use a new environment variable is easy, but we need to take care that when you upgrade the code the compute and network services might not be restarted immediately. If this happens, the services may launch a new dnsmasq (so rootwrap needs to continue to support FLAGFILE) or an existing dnsmasq might run the lease script (so the script needs to support FLAGFILE). Change-Id: Ieb55daa2507abb8327c7f5a2ef2f682740f31a5d --- bin/nova-dhcpbridge | 7 +++++-- nova/rootwrap/filters.py | 11 +++++++++-- nova/tests/test_nova_rootwrap.py | 15 +++++++++++---- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/bin/nova-dhcpbridge b/bin/nova-dhcpbridge index 1aaecc5b7..8ff2fac49 100755 --- a/bin/nova-dhcpbridge +++ b/bin/nova-dhcpbridge @@ -95,8 +95,11 @@ def init_leases(network_id): def main(): """Parse environment and arguments and call the approproate action.""" - argv = config.parse_args(sys.argv, - default_config_files=[os.environ['FLAGFILE']]) + try: + config_file = os.environ['CONFIG_FILE'] + except KeyError: + config_file = os.environ['FLAGFILE'] + argv = config.parse_args(sys.argv, default_config_files=[config_file]) logging.setup("nova") if int(os.environ.get('TESTING', '0')): diff --git a/nova/rootwrap/filters.py b/nova/rootwrap/filters.py index 52808d9ec..46a812e5d 100644 --- a/nova/rootwrap/filters.py +++ b/nova/rootwrap/filters.py @@ -72,9 +72,11 @@ class RegExpFilter(CommandFilter): class DnsmasqFilter(CommandFilter): """Specific filter for the dnsmasq call (which includes env)""" + CONFIG_FILE_ARG = 'CONFIG_FILE' + def match(self, userargs): if (userargs[0] == 'env' and - userargs[1].startswith('FLAGFILE=') and + userargs[1].startswith(self.CONFIG_FILE_ARG) and userargs[2].startswith('NETWORK_ID=') and userargs[3] == 'dnsmasq'): return True @@ -86,11 +88,16 @@ class DnsmasqFilter(CommandFilter): def get_environment(self, userargs): env = os.environ.copy() - env['FLAGFILE'] = userargs[1].split('=')[-1] + env[self.CONFIG_FILE_ARG] = userargs[1].split('=')[-1] env['NETWORK_ID'] = userargs[2].split('=')[-1] return env +class DeprecatedDnsmasqFilter(DnsmasqFilter): + """Variant of dnsmasq filter to support old-style FLAGFILE""" + CONFIG_FILE_ARG = 'FLAGFILE' + + class KillFilter(CommandFilter): """Specific filter for the kill calls. 1st argument is the user to run /bin/kill under diff --git a/nova/tests/test_nova_rootwrap.py b/nova/tests/test_nova_rootwrap.py index 420a086eb..135a5e46e 100644 --- a/nova/tests/test_nova_rootwrap.py +++ b/nova/tests/test_nova_rootwrap.py @@ -54,15 +54,22 @@ class RootwrapTestCase(test.TestCase): filtermatch = wrapper.match_filter(self.filters, invalid) self.assertTrue(filtermatch is None) - def test_DnsmasqFilter(self): - usercmd = ['env', 'FLAGFILE=A', 'NETWORK_ID=foobar', 'dnsmasq', 'foo'] - f = filters.DnsmasqFilter("/usr/bin/dnsmasq", "root") + def _test_DnsmasqFilter(self, filter_class, config_file_arg): + usercmd = ['env', config_file_arg + '=A', 'NETWORK_ID=foobar', + 'dnsmasq', 'foo'] + f = filter_class("/usr/bin/dnsmasq", "root") self.assertTrue(f.match(usercmd)) self.assertEqual(f.get_command(usercmd), ['/usr/bin/dnsmasq', 'foo']) env = f.get_environment(usercmd) - self.assertEqual(env.get('FLAGFILE'), 'A') + self.assertEqual(env.get(config_file_arg), 'A') self.assertEqual(env.get('NETWORK_ID'), 'foobar') + def test_DnsmasqFilter(self): + self._test_DnsmasqFilter(filters.DnsmasqFilter, 'CONFIG_FILE') + + def test_DeprecatedDnsmasqFilter(self): + self._test_DnsmasqFilter(filters.DeprecatedDnsmasqFilter, 'FLAGFILE') + def test_KillFilter(self): if not os.path.exists("/proc/%d" % os.getpid()): self.skipTest("Test requires /proc filesystem (procfs)")