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:
parent
4cc2c41bbc
commit
1dcc5a3571
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue