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
This commit is contained in:
Mark McLoughlin
2012-11-23 12:38:15 +00:00
parent d5620b2f5a
commit baa1006747
6 changed files with 28 additions and 9 deletions

View File

@@ -95,8 +95,11 @@ def init_leases(network_id):
def main(): def main():
"""Parse environment and arguments and call the approproate action.""" """Parse environment and arguments and call the approproate action."""
argv = config.parse_args(sys.argv, try:
default_config_files=[os.environ['FLAGFILE']]) 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") logging.setup("nova")
if int(os.environ.get('TESTING', '0')): if int(os.environ.get('TESTING', '0')):

View File

@@ -148,6 +148,7 @@ kill_radvd: KillFilter, root, /usr/sbin/radvd
# nova/network/linux_net.py: dnsmasq call # nova/network/linux_net.py: dnsmasq call
dnsmasq: DnsmasqFilter, /usr/sbin/dnsmasq, root dnsmasq: DnsmasqFilter, /usr/sbin/dnsmasq, root
dnsmasq_deprecated: DeprecatedDnsmasqFilter, /usr/sbin/dnsmasq, root
# nova/network/linux_net.py: 'radvd', '-C', '%s' % _ra_file(dev, 'conf'.. # nova/network/linux_net.py: 'radvd', '-C', '%s' % _ra_file(dev, 'conf'..
radvd: CommandFilter, /usr/sbin/radvd, root radvd: CommandFilter, /usr/sbin/radvd, root

View File

@@ -63,6 +63,7 @@ kill_radvd: KillFilter, root, /usr/sbin/radvd
# nova/network/linux_net.py: dnsmasq call # nova/network/linux_net.py: dnsmasq call
dnsmasq: DnsmasqFilter, /usr/sbin/dnsmasq, root dnsmasq: DnsmasqFilter, /usr/sbin/dnsmasq, root
dnsmasq_deprecated: DeprecatedDnsmasqFilter, /usr/sbin/dnsmasq, root
# nova/network/linux_net.py: 'radvd', '-C', '%s' % _ra_file(dev, 'conf'.. # nova/network/linux_net.py: 'radvd', '-C', '%s' % _ra_file(dev, 'conf'..
radvd: CommandFilter, /usr/sbin/radvd, root radvd: CommandFilter, /usr/sbin/radvd, root

View File

@@ -840,7 +840,7 @@ def restart_dhcp(context, dev, network_ref):
LOG.debug(_('Pid %d is stale, relaunching dnsmasq'), pid) LOG.debug(_('Pid %d is stale, relaunching dnsmasq'), pid)
cmd = ['env', cmd = ['env',
'FLAGFILE=%s' % CONF.dhcpbridge_flagfile, 'CONFIG_FILE=%s' % CONF.dhcpbridge_flagfile,
'NETWORK_ID=%s' % str(network_ref['id']), 'NETWORK_ID=%s' % str(network_ref['id']),
'dnsmasq', 'dnsmasq',
'--strict-order', '--strict-order',

View File

@@ -72,9 +72,11 @@ class RegExpFilter(CommandFilter):
class DnsmasqFilter(CommandFilter): class DnsmasqFilter(CommandFilter):
"""Specific filter for the dnsmasq call (which includes env)""" """Specific filter for the dnsmasq call (which includes env)"""
CONFIG_FILE_ARG = 'CONFIG_FILE'
def match(self, userargs): def match(self, userargs):
if (userargs[0] == 'env' and 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[2].startswith('NETWORK_ID=') and
userargs[3] == 'dnsmasq'): userargs[3] == 'dnsmasq'):
return True return True
@@ -86,11 +88,16 @@ class DnsmasqFilter(CommandFilter):
def get_environment(self, userargs): def get_environment(self, userargs):
env = os.environ.copy() 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] env['NETWORK_ID'] = userargs[2].split('=')[-1]
return env return env
class DeprecatedDnsmasqFilter(DnsmasqFilter):
"""Variant of dnsmasq filter to support old-style FLAGFILE"""
CONFIG_FILE_ARG = 'FLAGFILE'
class KillFilter(CommandFilter): class KillFilter(CommandFilter):
"""Specific filter for the kill calls. """Specific filter for the kill calls.
1st argument is the user to run /bin/kill under 1st argument is the user to run /bin/kill under

View File

@@ -54,15 +54,22 @@ class RootwrapTestCase(test.TestCase):
filtermatch = wrapper.match_filter(self.filters, invalid) filtermatch = wrapper.match_filter(self.filters, invalid)
self.assertTrue(filtermatch is None) self.assertTrue(filtermatch is None)
def test_DnsmasqFilter(self): def _test_DnsmasqFilter(self, filter_class, config_file_arg):
usercmd = ['env', 'FLAGFILE=A', 'NETWORK_ID=foobar', 'dnsmasq', 'foo'] usercmd = ['env', config_file_arg + '=A', 'NETWORK_ID=foobar',
f = filters.DnsmasqFilter("/usr/bin/dnsmasq", "root") 'dnsmasq', 'foo']
f = filter_class("/usr/bin/dnsmasq", "root")
self.assertTrue(f.match(usercmd)) self.assertTrue(f.match(usercmd))
self.assertEqual(f.get_command(usercmd), ['/usr/bin/dnsmasq', 'foo']) self.assertEqual(f.get_command(usercmd), ['/usr/bin/dnsmasq', 'foo'])
env = f.get_environment(usercmd) 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') 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): def test_KillFilter(self):
if not os.path.exists("/proc/%d" % os.getpid()): if not os.path.exists("/proc/%d" % os.getpid()):
self.skipTest("Test requires /proc filesystem (procfs)") self.skipTest("Test requires /proc filesystem (procfs)")