Repository: saltstack/salt
Pull request: Ensure config module loads opts from the named_context.
### What does this PR do?
Ensure opts is included in pack for minion_mods and config loads opts from the named_context.

### What issues does this PR fix or reference?
Fixes: #61297 

### Previous Behavior
When used with deltaproxy, the config module would use the `__opts__` from the last sub proxy minion that used the `config` module during initialization as part of configuring beacons. This would result in incorrect values being returned by the `config` module.

### New Behavior
Load `__opts__` from the Salt loader's named_context to ensure we're using the  `__opts__` for the correct minion.

### Merge requirements satisfied?
**[NOTICE] Bug fixes or features added to Salt require tests.**
<!-- Please review the [test documentation](https://docs.saltproject.io/en/master/topics/tutorials/writing_tests.html) for details on how to implement tests into Salt's test suite. -->
- [ ] Docs
- [x] Changelog - https://docs.saltproject.io/en/master/topics/development/changelog.html
- [x] Tests written/updated

### Commits signed with GPG?
Yes

Please review [Salt's Contributing Guide](https://docs.saltproject.io/en/master/topics/development/contributing.html) for best practices.

See GitHub's [page on GPG signing](https://help.github.com/articles/signing-commits-using-gpg/) for more information about signing commits with GPG.


Problem statement:
deltaproxy overriding minion configuration settings
### Description of Issue
I am evaluating the deltaproxy feature released on 3004 version and noticed the configuration settings for other deltaproxy managed minions are getting overridden with the settings defined for the last minion defined under "ids". This results in cases like targeting one minion to execute a command and getting the result from another one. This behaviour was originally observed for napalm and netmiko proxies and, to make sure it's nothing related to my environment, I brought up a fresh 3004 instance with 1 deltaproxy and 3 dummy proxies. Details below:

### Setup
_/etc/salt/master_:
```
interface: 127.0.0.1
```

_/etc/salt/proxy_:
```
master: 127.0.0.1
metaproxy: deltaproxy
enable_fqdns_grains: False
multiprocessing: True
```

_/srv/pillar/top.sls_:
```
base:
  deltaproxy:
    - deltaproxy
  dummy1:
    - dummy1
  dummy2:
   - dummy2
  dummy3:
   - dummy3
```

_/srv/pillar/deltaproxy.sls_:
```
proxy:
  proxytype: deltaproxy
  ids:
    - dummy1
    - dummy2
    - dummy3
```

_/srv/pilar/dummy1.sls_:
```
proxy:
  proxytype: dummy
  hostname: dummy1
```

_/srv/pilar/dummy2.sls_:
```
proxy:
  proxytype: dummy
  hostname: dummy2
```

_/srv/pilar/dummy3.sls_:
```
proxy:
  proxytype: dummy
  hostname: dummy3
```

### Steps to Reproduce Issue
Here it's possible to observe that _id_ and also settings defined under _pillar_ are overridden:
```
root@salt-3004:~# salt 'dummy*' config.get id
dummy1:
    dummy3
dummy2:
    dummy3
dummy3:
    dummy3

root@salt-3004:~# salt 'dummy*' config.get proxy
dummy1:
    ----------
    hostname:
        dummy3
    proxytype:
        dummy
dummy2:
    ----------
    hostname:
        dummy3
    proxytype:
        dummy
dummy3:
    ----------
    hostname:
        dummy3
    proxytype:
        dummy
```

### Versions Report
```
root@salt-3004:~# salt --versions-report
Salt Version:
          Salt: 3004

Dependency Versions:
          cffi: Not Installed
      cherrypy: unknown
      dateutil: 2.8.1
     docker-py: Not Installed
         gitdb: 4.0.5
     gitpython: 3.1.14
        Jinja2: 2.11.3
       libgit2: Not Installed
      M2Crypto: Not Installed
          Mako: Not Installed
       msgpack: 1.0.0
  msgpack-pure: Not Installed
  mysql-python: Not Installed
     pycparser: Not Installed
      pycrypto: Not Installed
  pycryptodome: 3.9.7
        pygit2: Not Installed
        Python: 3.9.2 (default, Feb 28 2021, 17:03:44)
  python-gnupg: Not Installed
        PyYAML: 5.3.1
         PyZMQ: 20.0.0
         smmap: 4.0.0
       timelib: Not Installed
       Tornado: 4.5.3
           ZMQ: 4.3.4

System Versions:
          dist: debian 11 bullseye
        locale: utf-8
       machine: x86_64
       release: 5.10.0-9-amd64
        system: Linux
       version: Debian GNU/Linux 11 bullseye
```

Let me know if there's any other information I can provide that's relevant to this issue. 
Thank you.

Hints from issue discussion:
Hi there! Welcome to the Salt Community! Thank you for making your first contribution. We have a lengthy process for issues and PRs. Someone from the Core Team will follow up as soon as possible. In the meantime, here’s some information that may help as you continue your Salt journey.
Please be sure to review our [Code of Conduct](https://github.com/saltstack/salt/blob/master/CODE_OF_CONDUCT.md). Also, check out some of our community resources including:

  - [Community Wiki](https://github.com/saltstack/community/wiki)
  - [Salt’s Contributor Guide](https://docs.saltproject.io/en/master/topics/development/contributing.html)
  - [Join our Community Slack](https://join.slack.com/t/saltstackcommunity/shared_invite/zt-3av8jjyf-oBQ2M0vhXOhJpNpRkPWBvg)
  - [IRC on LiberaChat](https://web.libera.chat/#salt)
  - [Salt Project YouTube channel](https://www.youtube.com/channel/UCpveTIucFx9ljGelW63-BWg)
  - [Salt Project Twitch channel](https://www.twitch.tv/saltprojectoss)

There are lots of ways to get involved in our community. Every month, there are around a dozen opportunities to meet with other contributors and the Salt Core team and collaborate in real time. The best way to keep track is by subscribing to the Salt Community Events Calendar.
If you have additional questions, email us at saltproject@vmware.com. We’re glad you’ve joined our community and look forward to doing awesome things with you!

@marcosvbuzo Thanks for the report.  Apologies for the delay in responding, I was digging into this and seeing where the root of the issue is.  Unfortunately I haven't found it but I'm on the right track, it seems related to the initial start up of the proxy minion, there are various jobs that are run as part of the startup including a pillar refresh.  For some reason the only one that successfully returns is the last proxy minion configured in the Deltaproxy configuration.  Doing a `saltutil.refresh_pillar` on any other minion actually causes the values returned from `config.get` to be the values of that minion.  So it's definitely something in there.
Hi @garethgreenaway, thank you for coming back on this issue, that's really appreciated.
I am also digging into it and found something interesting. If deltaproxy process is forced to run one process at a time, the issue does not happen:

_/etc/salt/proxy_
```
multiprocessing: False
```

_/etc/salt/proxy.d/deltaproxy_
```
process_count_max: 1
```

I hope this information is relevant for getting to the root cause. Running deltaproxy with these settings makes everything slower as everything is done in a sequential fashion, which results in jobs like _saltutil.find_job_ to not respond on time and cli to print out "no response" errors to users.
@marcosvbuzo Thank for that information, very helpful.  My current suspicion is that the problems are related to the event bus.  Currently the control proxy and the sub proxies all share the same socket and event bus, I'm wondering if that is the route cause here.

Commit message: Adding changelog

Patch to review:
diff --git a/changelog/61297.fixed b/changelog/61297.fixed
new file mode 100644
index 000000000000..1c64eb26602c
--- /dev/null
+++ b/changelog/61297.fixed
@@ -0,0 +1 @@
+Ensure opts is included in pack for minion_mods and config loads opts from the named_context.
diff --git a/salt/loader/__init__.py b/salt/loader/__init__.py
index 361157d1a2c9..b8ce932e9765 100644
--- a/salt/loader/__init__.py
+++ b/salt/loader/__init__.py
@@ -300,7 +300,12 @@ def minion_mods(
         _module_dirs(opts, "modules", "module"),
         opts,
         tag="module",
-        pack={"__context__": context, "__utils__": utils, "__proxy__": proxy},
+        pack={
+            "__context__": context,
+            "__utils__": utils,
+            "__proxy__": proxy,
+            "__opts__": opts,
+        },
         whitelist=whitelist,
         loaded_base_name=loaded_base_name,
         static_modules=static_modules,
diff --git a/salt/modules/config.py b/salt/modules/config.py
index 6b18cf3c32f7..972a2e84c7c4 100644
--- a/salt/modules/config.py
+++ b/salt/modules/config.py
@@ -15,6 +15,7 @@
 import salt.utils.files
 import salt.utils.platform
 import salt.utils.sdb as sdb
+from salt.loader.context import LoaderContext
 
 try:
     # Gated for salt-ssh (salt.utils.cloud imports msgpack)
@@ -35,6 +36,8 @@
 log = logging.getLogger(__name__)
 
 __proxyenabled__ = ["*"]
+__salt_loader__ = LoaderContext()
+__opts__ = __salt_loader__.named_context("__opts__")
 
 # Set up the default values for all systems
 DEFAULTS = {
diff --git a/tests/pytests/integration/proxy/test_deltaproxy.py b/tests/pytests/integration/proxy/test_deltaproxy.py
index ebfafba85dd5..e1c4cecb057a 100644
--- a/tests/pytests/integration/proxy/test_deltaproxy.py
+++ b/tests/pytests/integration/proxy/test_deltaproxy.py
@@ -137,3 +137,13 @@ def test_state_highstate(salt_master, salt_cli, tmp_path, proxy_id):
         ret = salt_cli.run("state.highstate", minion_tgt=proxy_id)
         for value in ret.json.values():
             assert value["result"] is True
+
+
+def test_config_get(salt_cli, proxy_id):
+    """
+    Ensure the config module returns the right id
+    when targeting deltaproxy managed proxy minions.
+    """
+    ret = salt_cli.run("config.get", "id", minion_tgt=proxy_id)
+    assert True is True
+    assert ret.json == proxy_id


Code review comments:
diff_hunk: @@ -137,3 +137,13 @@ def test_state_highstate(salt_master, salt_cli, tmp_path, proxy_id):
         ret = salt_cli.run("state.highstate", minion_tgt=proxy_id)
         for value in ret.json.values():
             assert value["result"] is True
+
+
+def test_config_get(salt_cli, proxy_id):
+    """
+    Ensure the config module returns the right id
+    when targeting deltaproxy managed proxy minions.
+    """
+    ret = salt_cli.run("config.get", "id", minion_tgt=proxy_id)
+    assert True is True
path: tests/pytests/integration/proxy/test_deltaproxy.py
text: @user1:
This looks like cruft.