Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
systemsmanagement:Uyuni:Master
salt
prevent-race-condition-on-sigterm-for-the-minio...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File prevent-race-condition-on-sigterm-for-the-minion-bsc.patch of Package salt
From 30fa660f0f6a9a3e5709e4fd0773e43248018726 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Su=C3=A1rez=20Hern=C3=A1ndez?= <psuarezhernandez@suse.com> Date: Tue, 19 Jan 2021 09:23:44 +0000 Subject: [PATCH] Prevent race condition on SIGTERM for the minion (bsc#1172110) Prevent race condition when handling signals by CLI clients Add test case to cover destroy race condition for minion module_refresh --- salt/loader.py | 17 +++++++++++------ salt/minion.py | 2 ++ tests/unit/test_minion.py | 27 +++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/salt/loader.py b/salt/loader.py index 7b42b6b0d6..02446b5ee1 100644 --- a/salt/loader.py +++ b/salt/loader.py @@ -1737,12 +1737,17 @@ class LazyLoader(salt.utils.lazy.LazyDict): except Exception: # pylint: disable=broad-except pass else: - tgt_fn = os.path.join("salt", "utils", "process.py") - if fn_.endswith(tgt_fn) and "_handle_signals" in caller: - # Race conditon, SIGTERM or SIGINT received while loader - # was in process of loading a module. Call sys.exit to - # ensure that the process is killed. - sys.exit(salt.defaults.exitcodes.EX_OK) + tgt_fns = [ + os.path.join("salt", "utils", "process.py"), + os.path.join("salt", "cli", "daemons.py"), + os.path.join("salt", "cli", "api.py"), + ] + for tgt_fn in tgt_fns: + if fn_.endswith(tgt_fn) and "_handle_signals" in caller: + # Race conditon, SIGTERM or SIGINT received while loader + # was in process of loading a module. Call sys.exit to + # ensure that the process is killed. + sys.exit(salt.defaults.exitcodes.EX_OK) log.error( "Failed to import %s %s as the module called exit()\n", self.tag, diff --git a/salt/minion.py b/salt/minion.py index dacff1e0a9..6bfac076eb 100644 --- a/salt/minion.py +++ b/salt/minion.py @@ -2385,6 +2385,8 @@ class Minion(MinionBase): """ Refresh the functions and returners. """ + if not hasattr(self, "schedule"): + return log.debug("Refreshing modules. Notify=%s", notify) self.functions, self.returners, _, self.executors = self._load_modules( force_refresh, notify=notify diff --git a/tests/unit/test_minion.py b/tests/unit/test_minion.py index 36c88819f4..9b31d011ec 100644 --- a/tests/unit/test_minion.py +++ b/tests/unit/test_minion.py @@ -392,6 +392,33 @@ class MinionTestCase(TestCase, AdaptedConfigurationTestCaseMixin): finally: minion.destroy() + def test_minion_module_refresh(self): + """ + Tests that the 'module_refresh' just return in case there is no 'schedule' + because destroy method was already called. + """ + with patch("salt.minion.Minion.ctx", MagicMock(return_value={})), patch( + "salt.utils.process.SignalHandlingProcess.start", + MagicMock(return_value=True), + ), patch( + "salt.utils.process.SignalHandlingProcess.join", + MagicMock(return_value=True), + ): + try: + mock_opts = salt.config.DEFAULT_MINION_OPTS.copy() + minion = salt.minion.Minion( + mock_opts, io_loop=salt.ext.tornado.ioloop.IOLoop(), + ) + minion.schedule = salt.utils.schedule.Schedule( + mock_opts, {}, returners={} + ) + self.assertTrue(hasattr(minion, "schedule")) + minion.destroy() + self.assertTrue(not hasattr(minion, "schedule")) + self.assertTrue(not minion.module_refresh()) + finally: + minion.destroy() + @slowTest def test_when_ping_interval_is_set_the_callback_should_be_added_to_periodic_callbacks( self, -- 2.30.1
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor