Re-execute after commands and on SIGHUP

After we have run a command and committed, re-execute ourselves. This
ensures that we will get any configurations that may have come from
underlying commands. Also re-execute if os-collect-config is sent HUP.

Change-Id: I87b4d8ce44fcbc9458a3a4fbb2445e4c9d0ad4e7
This commit is contained in:
Clint Byrum 2013-07-29 16:06:54 -07:00
parent 4cc2c41bbc
commit 1dcc5a3571
2 changed files with 54 additions and 5 deletions

View File

@ -15,6 +15,7 @@
import json
import os
import signal
import subprocess
import sys
import time
@ -114,7 +115,23 @@ def collect_all(collectors, store=False, requests_impl_map=None):
return (any_changed, paths_or_content)
def reexec_self(signal=None, frame=None):
if signal:
logger.info('Signal received. Re-executing %s' % sys.argv)
# Close all but stdin/stdout/stderr
os.closerange(3, 255)
os.execv(sys.argv[0], sys.argv)
def call_command(files, command):
env = dict(os.environ)
env["OS_CONFIG_FILES"] = ':'.join(files)
logger.info("Executing %s" % command)
subprocess.call(CONF.command, env=env, shell=True)
def __main__(args=sys.argv, requests_impl_map=None):
signal.signal(signal.SIGHUP, reexec_self)
setup_conf()
CONF(args=args[1:], prog="os-collect-config")
@ -133,12 +150,13 @@ def __main__(args=sys.argv, requests_impl_map=None):
requests_impl_map=requests_impl_map)
if CONF.command:
if any_changed:
env = dict(os.environ)
env["OS_CONFIG_FILES"] = ':'.join(content)
logger.info("Executing %s" % CONF.command)
subprocess.call(CONF.command, env=env, shell=True)
# ignore HUP now since we will reexec after commit anyway
signal.signal(signal.SIGHUP, signal.SIG_IGN)
call_command(content, CONF.command)
for collector in cfg.CONF.collectors:
cache.commit(collector)
if not CONF.one_time:
reexec_self()
else:
logger.debug("No changes detected.")
if CONF.one_time:

View File

@ -18,8 +18,11 @@ import extras
import fixtures
import json
import os
from oslo.config import cfg
import signal
import sys
import tempfile
from oslo.config import cfg
import testtools
from testtools import matchers
@ -39,6 +42,7 @@ def _setup_local_metadata(test_case):
class TestCollect(testtools.TestCase):
def setUp(self):
super(TestCollect, self).setUp()
self.useFixture(fixtures.FakeLogger())
@ -235,8 +239,35 @@ class TestCollectAll(testtools.TestCase):
class TestConf(testtools.TestCase):
def test_setup_conf(self):
collect.setup_conf()
self.assertEquals('/var/run/os-collect-config', cfg.CONF.cachedir)
self.assertTrue(extras.safe_hasattr(cfg.CONF, 'ec2'))
self.assertTrue(extras.safe_hasattr(cfg.CONF, 'cfn'))
class TestHup(testtools.TestCase):
def setUp(self):
super(TestHup, self).setUp()
self.log = self.useFixture(fixtures.FakeLogger())
def fake_closerange(low, high):
self.assertEquals(3, low)
self.assertEquals(255, high)
def fake_execv(path, args):
self.assertEquals(sys.argv[0], path)
self.assertEquals(sys.argv, args)
self.useFixture(fixtures.MonkeyPatch('os.execv', fake_execv))
self.useFixture(fixtures.MonkeyPatch('os.closerange', fake_closerange))
def test_reexec_self_signal(self):
collect.reexec_self(signal.SIGHUP, None)
self.assertIn('Signal received', self.log.output)
def test_reexec_self(self):
collect.reexec_self()
self.assertNotIn('Signal received', self.log.output)