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 json
|
||||||
import os
|
import os
|
||||||
|
import signal
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
@ -114,7 +115,23 @@ def collect_all(collectors, store=False, requests_impl_map=None):
|
||||||
return (any_changed, paths_or_content)
|
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):
|
def __main__(args=sys.argv, requests_impl_map=None):
|
||||||
|
signal.signal(signal.SIGHUP, reexec_self)
|
||||||
setup_conf()
|
setup_conf()
|
||||||
CONF(args=args[1:], prog="os-collect-config")
|
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)
|
requests_impl_map=requests_impl_map)
|
||||||
if CONF.command:
|
if CONF.command:
|
||||||
if any_changed:
|
if any_changed:
|
||||||
env = dict(os.environ)
|
# ignore HUP now since we will reexec after commit anyway
|
||||||
env["OS_CONFIG_FILES"] = ':'.join(content)
|
signal.signal(signal.SIGHUP, signal.SIG_IGN)
|
||||||
logger.info("Executing %s" % CONF.command)
|
call_command(content, CONF.command)
|
||||||
subprocess.call(CONF.command, env=env, shell=True)
|
|
||||||
for collector in cfg.CONF.collectors:
|
for collector in cfg.CONF.collectors:
|
||||||
cache.commit(collector)
|
cache.commit(collector)
|
||||||
|
if not CONF.one_time:
|
||||||
|
reexec_self()
|
||||||
else:
|
else:
|
||||||
logger.debug("No changes detected.")
|
logger.debug("No changes detected.")
|
||||||
if CONF.one_time:
|
if CONF.one_time:
|
||||||
|
|
|
@ -18,8 +18,11 @@ import extras
|
||||||
import fixtures
|
import fixtures
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
from oslo.config import cfg
|
import signal
|
||||||
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
|
from oslo.config import cfg
|
||||||
import testtools
|
import testtools
|
||||||
from testtools import matchers
|
from testtools import matchers
|
||||||
|
|
||||||
|
@ -39,6 +42,7 @@ def _setup_local_metadata(test_case):
|
||||||
|
|
||||||
|
|
||||||
class TestCollect(testtools.TestCase):
|
class TestCollect(testtools.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestCollect, self).setUp()
|
super(TestCollect, self).setUp()
|
||||||
self.useFixture(fixtures.FakeLogger())
|
self.useFixture(fixtures.FakeLogger())
|
||||||
|
@ -235,8 +239,35 @@ class TestCollectAll(testtools.TestCase):
|
||||||
|
|
||||||
|
|
||||||
class TestConf(testtools.TestCase):
|
class TestConf(testtools.TestCase):
|
||||||
|
|
||||||
def test_setup_conf(self):
|
def test_setup_conf(self):
|
||||||
collect.setup_conf()
|
collect.setup_conf()
|
||||||
self.assertEquals('/var/run/os-collect-config', cfg.CONF.cachedir)
|
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, 'ec2'))
|
||||||
self.assertTrue(extras.safe_hasattr(cfg.CONF, 'cfn'))
|
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