Enable oslo_config mutable configurations

This patch enables oslo_config mutable configuration for the Octavia
control plane processes. The configuration will be updated when the
parent process receives a HUP signal.
This completes the Rocky goal: Enable mutable configuration.

Change-Id: Idaf608c6e5fd2fa74a68c3b562be441a20107a50
Story: 2001545
Task: 6391
This commit is contained in:
Michael Johnson 2018-07-01 12:10:11 -07:00
parent 16cb3603b8
commit 5021e0f547
6 changed files with 47 additions and 1 deletions

View File

@ -13,6 +13,7 @@
# under the License.
#
from functools import partial
import multiprocessing
import os
import signal
@ -34,8 +35,13 @@ CONF = cfg.CONF
LOG = logging.getLogger(__name__)
def _mutate_config(*args, **kwargs):
CONF.mutate_config_files()
def hm_listener(exit_event):
signal.signal(signal.SIGINT, signal.SIG_IGN)
signal.signal(signal.SIGHUP, _mutate_config)
udp_getter = heartbeat_udp.UDPStatusGetter()
while not exit_event.is_set():
try:
@ -50,6 +56,7 @@ def hm_listener(exit_event):
def hm_health_check(exit_event):
hm = health_manager.HealthManager(exit_event)
signal.signal(signal.SIGHUP, _mutate_config)
@periodics.periodic(CONF.health_manager.health_check_interval,
run_immediately=True)
@ -69,6 +76,13 @@ def hm_health_check(exit_event):
health_check.start()
def _handle_mutate_config(listener_proc_pid, check_proc_pid, *args, **kwargs):
LOG.info("Health Manager recieved HUP signal, mutating config.")
_mutate_config()
os.kill(listener_proc_pid, signal.SIGHUP)
os.kill(check_proc_pid, signal.SIGHUP)
def main():
service.prepare_service(sys.argv)
@ -99,6 +113,8 @@ def main():
hm_listener_proc.join()
signal.signal(signal.SIGTERM, process_cleanup)
signal.signal(signal.SIGHUP, partial(
_handle_mutate_config, hm_listener_proc.pid, hm_health_check_proc.pid))
try:
for process in processes:

View File

@ -14,6 +14,7 @@
#
import datetime
import signal
import sys
import threading
import time
@ -78,6 +79,11 @@ def cert_rotation():
cert_rotate_thread_event.wait(interval)
def _mutate_config(*args, **kwargs):
LOG.info("Housekeeping recieved HUP signal, mutating config.")
CONF.mutate_config_files()
def main():
service.prepare_service(sys.argv)
@ -101,6 +107,8 @@ def main():
cert_rotate_thread.daemon = True
cert_rotate_thread.start()
signal.signal(signal.SIGHUP, _mutate_config)
# Try-Exception block should be at the end to gracefully exit threads
try:
while True:

View File

@ -34,5 +34,5 @@ def main():
sm = cotyledon.ServiceManager()
sm.add(consumer.ConsumerService, workers=CONF.controller_worker.workers,
args=(CONF,))
oslo_config_glue.setup(sm, CONF)
oslo_config_glue.setup(sm, CONF, reload_method="mutate")
sm.run()

View File

@ -93,3 +93,13 @@ class TestHealthManagerCMD(base.TestCase):
mock_health_proc.join.assert_called_once_with()
mock_kill.assert_called_once_with(mock_health_proc.pid,
signal.SIGINT)
@mock.patch('os.kill')
@mock.patch('oslo_config.cfg.CONF.mutate_config_files')
def test_handle_mutate_config(self, mock_mutate, mock_kill):
health_manager._handle_mutate_config(1, 2)
mock_mutate.assert_called_once()
calls = [mock.call(1, signal.SIGHUP), mock.call(2, signal.SIGHUP)]
mock_kill.assert_has_calls(calls)

View File

@ -188,3 +188,9 @@ class TestHouseKeepingCMD(base.TestCase):
spare_amp_thread_mock.join.assert_called_once_with()
db_cleanup_thread_mock.join.assert_called_once_with()
cert_rotate_thread_mock.join.assert_called_once_with()
@mock.patch('oslo_config.cfg.CONF.mutate_config_files')
def test_mutate_config(self, mock_mutate):
house_keeping._mutate_config()
mock_mutate.assert_called_once()

View File

@ -0,0 +1,6 @@
---
features:
- |
You can now update the running configuration of the Octavia control
plane processes by sending the parent process a "HUP" signal.
Note: The configuration item must support mutation.