Skip to content

Commit f10b7e8

Browse files
author
David Murphy
committed
Added code to handle masterless sync of salt-minion, tests work-in-progress
1 parent e25231e commit f10b7e8

4 files changed

Lines changed: 142 additions & 3 deletions

File tree

salt/fileclient.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,15 @@
4545
MAX_FILENAME_LENGTH = 255
4646

4747

48-
def get_file_client(opts, pillar=False):
48+
def get_file_client(opts, pillar=False, force_local=False):
4949
"""
5050
Read in the ``file_client`` option and return the correct type of file
5151
server
5252
"""
53-
client = opts.get("file_client", "remote")
53+
if force_local:
54+
client = "local"
55+
else:
56+
client = opts.get("file_client", "remote")
5457

5558
if pillar and client == "local":
5659
client = "pillar"

salt/minion.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -939,6 +939,7 @@ def __init__(self, opts, context=None):
939939
# Late setup of the opts grains, so we can log from the grains module
940940
import salt.loader
941941

942+
_sync_grains(opts)
942943
opts["grains"] = salt.loader.grains(opts)
943944
super().__init__(opts)
944945

salt/utils/extmods.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ def sync(
3939
saltenv=None,
4040
extmod_whitelist=None,
4141
extmod_blacklist=None,
42+
force_local=False,
4243
):
4344
"""
4445
Sync custom modules into the extension_modules directory
@@ -82,7 +83,10 @@ def sync(
8283
"Cannot create cache module directory %s. Check permissions.",
8384
mod_dir,
8485
)
85-
with salt.fileclient.get_file_client(opts) as fileclient:
86+
## DGM with salt.fileclient.get_file_client(opts) as fileclient:
87+
with salt.fileclient.get_file_client(
88+
opts, pillar=False, force_local=force_local
89+
) as fileclient:
8690
for sub_env in saltenv:
8791
log.info("Syncing %s for environment '%s'", form, sub_env)
8892
cache = []

tests/pytests/integration/cli/test_salt_call.py

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,3 +429,134 @@ def test_local_salt_call_no_function_no_retcode(salt_call_cli):
429429
assert "test" in ret.data
430430
assert ret.data["test"] == "'test' is not available."
431431
assert "test.echo" in ret.data
432+
433+
434+
def test_state_highstate_custom_grains_masterless_mode(
435+
salt_master, salt_minion_factory
436+
):
437+
"""
438+
This test ensure that custom grains in salt://_grains are loaded before pillar compilation
439+
to ensure that any use of custom grains in pillar files are available when in masterless mode,
440+
this implies that a sync of grains occurs before loading the regular
441+
/etc/salt/grains or configuration file grains, as well as the usual grains.
442+
Note: cannot use salt_minion and salt_call_cli, since these will be loaded before
443+
the pillar and custom_grains files are written, hence using salt_minion_factory.
444+
"""
445+
pillar_top_sls = """
446+
base:
447+
'*':
448+
- defaults
449+
"""
450+
451+
pillar_defaults_sls = """
452+
mypillar: "{{ grains['custom_grain'] }}"
453+
"""
454+
455+
salt_top_sls = """
456+
base:
457+
'*':
458+
- test
459+
"""
460+
461+
salt_test_sls = """
462+
"donothing":
463+
test.nop: []
464+
"""
465+
466+
salt_custom_grains_py = """
467+
def main():
468+
return {'custom_grain': 'test_value'}
469+
"""
470+
471+
## DGM TBD need to get masterless mode
472+
assert salt_master.is_running()
473+
with salt_minion_factory.started():
474+
salt_minion = salt_minion_factory
475+
salt_call_cli = salt_minion_factory.salt_call_cli()
476+
with salt_minion.pillar_tree.base.temp_file(
477+
"top.sls", pillar_top_sls
478+
), salt_minion.pillar_tree.base.temp_file(
479+
"defaults.sls", pillar_defaults_sls
480+
), salt_minion.state_tree.base.temp_file(
481+
"top.sls", salt_top_sls
482+
), salt_minion.state_tree.base.temp_file(
483+
"test.sls", salt_test_sls
484+
), salt_minion.state_tree.base.temp_file(
485+
"_grains/custom_grain.py", salt_custom_grains_py
486+
):
487+
ret = salt_call_cli.run("state.highstate")
488+
assert ret.returncode == 0
489+
ret = salt_call_cli.run("pillar.items")
490+
assert ret.returncode == 0
491+
assert ret.data
492+
pillar_items = ret.data
493+
assert "mypillar" in pillar_items
494+
assert pillar_items["mypillar"] == "test_value"
495+
496+
497+
def test_state_highstate_custom_grains_master_mode(salt_master, salt_minion_factory):
498+
"""
499+
This test ensure that custom grains in salt://_grains are loaded before pillar compilation
500+
to ensure that any use of custom grains in pillar files are unaffected by changes for
501+
sync custom grains for the salt-minion in masterless mode,
502+
"""
503+
pillar_top_sls = """
504+
base:
505+
'*':
506+
- defaults
507+
"""
508+
509+
pillar_defaults_sls = """
510+
mypillar: "{{ grains['custom_grain'] }}"
511+
"""
512+
513+
salt_top_sls = """
514+
base:
515+
'*':
516+
- test
517+
"""
518+
519+
salt_test_sls = """
520+
"donothing":
521+
test.nop: []
522+
"""
523+
524+
salt_custom_grains_py = """
525+
def main():
526+
return {'custom_grain': 'test_value'}
527+
"""
528+
529+
## DGM TBD need to ensure master mode
530+
assert salt_master.is_running()
531+
with salt_minion_factory.started():
532+
salt_minion = salt_minion_factory
533+
salt_call_cli = salt_minion_factory.salt_call_cli()
534+
with salt_minion.pillar_tree.base.temp_file(
535+
"top.sls", pillar_top_sls
536+
), salt_minion.pillar_tree.base.temp_file(
537+
"defaults.sls", pillar_defaults_sls
538+
), salt_minion.state_tree.base.temp_file(
539+
"top.sls", salt_top_sls
540+
), salt_minion.state_tree.base.temp_file(
541+
"test.sls", salt_test_sls
542+
), salt_minion.state_tree.base.temp_file(
543+
"_grains/custom_grain.py", salt_custom_grains_py
544+
):
545+
ret = salt_call_cli.run("state.highstate")
546+
assert ret.returncode == 0
547+
ret = salt_call_cli.run("pillar.items")
548+
assert ret.returncode == 0
549+
assert ret.data
550+
pillar_items = ret.data
551+
assert "mypillar" not in pillar_items
552+
553+
554+
def test_salt_call_versions(salt_call_cli, caplog):
555+
"""
556+
Call test.versions without '--local' to test grains
557+
are sync'd without any missing keys in opts
558+
"""
559+
with caplog.at_level(logging.DEBUG):
560+
ret = salt_call_cli.run("test.versions")
561+
assert ret.returncode == 0
562+
assert "Failed to sync grains module: 'master_uri'" not in caplog.messages

0 commit comments

Comments
 (0)