From 3e7c5d95423491f83d0016eb7c02285cd0b1bcf4 Mon Sep 17 00:00:00 2001 From: Marek Czernek Date: Wed, 17 Jan 2024 15:39:41 +0100 Subject: [PATCH] Update __pillar__ during pillar_refresh --- changelog/63583.fixed.md | 1 + salt/minion.py | 1 + .../integration/modules/test_pillar.py | 110 +++++++++++++++++- 3 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 changelog/63583.fixed.md diff --git a/changelog/63583.fixed.md b/changelog/63583.fixed.md new file mode 100644 index 0000000000..f1b6e32507 --- /dev/null +++ b/changelog/63583.fixed.md @@ -0,0 +1 @@ +Need to make sure we update __pillar__ during a pillar refresh to ensure that process_beacons has the updated beacons loaded from pillar. diff --git a/salt/minion.py b/salt/minion.py index 9597d6e63a..4db0d31bd4 100644 --- a/salt/minion.py +++ b/salt/minion.py @@ -2498,6 +2498,7 @@ class Minion(MinionBase): current_schedule, new_schedule ) self.opts["pillar"] = new_pillar + self.functions.pack["__pillar__"] = self.opts["pillar"] finally: async_pillar.destroy() self.matchers_refresh() diff --git a/tests/pytests/integration/modules/test_pillar.py b/tests/pytests/integration/modules/test_pillar.py index 66f7b9e47b..5db9a1630a 100644 --- a/tests/pytests/integration/modules/test_pillar.py +++ b/tests/pytests/integration/modules/test_pillar.py @@ -1,9 +1,14 @@ +import logging import pathlib import time +import types import attr import pytest +log = logging.getLogger(__name__) + + pytestmark = [ pytest.mark.slow_test, pytest.mark.windows_whitelisted, @@ -210,7 +215,7 @@ class PillarRefresh: "top.sls", top_file_contents ) self.minion_1_pillar = self.master.pillar_tree.base.temp_file( - "minion-1-pillar.sls", "{}: true".format(self.pillar_key) + "minion-1-pillar.sls", f"{self.pillar_key}: true" ) self.top_file.__enter__() self.minion_1_pillar.__enter__() @@ -588,3 +593,106 @@ def test_pillar_ext_59975(salt_call_cli): """ ret = salt_call_cli.run("pillar.ext", '{"libvert": _}') assert "ext_pillar_opts" in ret.data + + +@pytest.fixture +def event_listerner_timeout(grains): + if grains["os"] == "Windows": + if grains["osrelease"].startswith("2019"): + return types.SimpleNamespace(catch=120, miss=30) + return types.SimpleNamespace(catch=90, miss=10) + return types.SimpleNamespace(catch=60, miss=10) + + +@pytest.mark.slow_test +def test_pillar_refresh_pillar_beacons( + base_env_pillar_tree_root_dir, + salt_cli, + salt_minion, + salt_master, + event_listener, + event_listerner_timeout, +): + """ + Ensure beacons jobs in pillar are started after + a pillar refresh and then not running when pillar + is cleared. + """ + + top_sls = """ + base: + '{}': + - test_beacons + """.format( + salt_minion.id + ) + + test_beacons_sls_empty = "" + + test_beacons_sls = """ + beacons: + status: + - loadavg: + - 1-min + """ + + assert salt_minion.is_running() + + top_tempfile = pytest.helpers.temp_file( + "top.sls", top_sls, base_env_pillar_tree_root_dir + ) + beacon_tempfile = pytest.helpers.temp_file( + "test_beacons.sls", test_beacons_sls_empty, base_env_pillar_tree_root_dir + ) + + with top_tempfile, beacon_tempfile: + # Calling refresh_pillar to update in-memory pillars + salt_cli.run("saltutil.refresh_pillar", wait=True, minion_tgt=salt_minion.id) + + # Ensure beacons start when pillar is refreshed + with salt_master.pillar_tree.base.temp_file( + "test_beacons.sls", test_beacons_sls + ): + # Calling refresh_pillar to update in-memory pillars + salt_cli.run( + "saltutil.refresh_pillar", wait=True, minion_tgt=salt_minion.id + ) + + # Give the beacons a chance to start + time.sleep(5) + + event_tag = f"salt/beacon/*/status/*" + start_time = time.time() + + event_pattern = (salt_master.id, event_tag) + matched_events = event_listener.wait_for_events( + [event_pattern], + after_time=start_time, + timeout=event_listerner_timeout.catch, + ) + + assert matched_events.found_all_events + + # Ensure beacons sttop when pillar is refreshed + with salt_master.pillar_tree.base.temp_file( + "test_beacons.sls", test_beacons_sls_empty + ): + # Calling refresh_pillar to update in-memory pillars + salt_cli.run( + "saltutil.refresh_pillar", wait=True, minion_tgt=salt_minion.id + ) + + # Give the beacons a chance to stop + time.sleep(5) + + event_tag = f"salt/beacon/*/status/*" + start_time = time.time() + + event_pattern = (salt_master.id, event_tag) + matched_events = event_listener.wait_for_events( + [event_pattern], + after_time=start_time, + timeout=event_listerner_timeout.miss, + ) + + assert not matched_events.found_all_events -- 2.43.0