[MacPorts] #63263: py-ansible-base 2.10.11: Path replacement breaks custom facts
MacPorts
noreply at macports.org
Mon Jul 19 14:35:47 UTC 2021
#63263: py-ansible-base 2.10.11: Path replacement breaks custom facts
------------------------------+--------------------
Reporter: F30 | Owner: (none)
Type: defect | Status: new
Priority: Normal | Milestone:
Component: ports | Version:
Resolution: | Keywords:
Port: py-ansible-base |
------------------------------+--------------------
Description changed by F30:
Old description:
> **Problem:**
>
> [https://docs.ansible.com/ansible/latest/user_guide/playbooks_vars_facts.html
> #adding-custom-facts Local custom facts] do not get picked up from
> "/etc/ansible/facts.d" if Ansible was installed via MacPorts.
>
> To reproduce, place a JSON or INI file into "/etc/ansible/facts.d" on the
> remote host, e.g. "/etc/ansible/facts.d/demo.fact":
>
> {{{
> {
> "foo": "bar"
> }
> }}}
>
> Then, try to read these facts by running something like `ansible -m
> ansible.builtin.setup -a 'filter=ansible_local'`. The output will not
> contain the custom fact.
>
> Alternatively, try accessing `ansible_local['demo']['foo']` from a
> playbook. That will cause Ansible to crash:
>
> {{{
> fatal: [<snip>]: FAILED! =>
> msg: |-
> The task includes an option with an undefined variable. The error
> was: 'dict object' has no attribute 'demo'
> }}}
>
> **Cause:**
>
> The py-ansible-base Portfile does a global replacement of all
> "/etc/ansible" paths to "/opt/local/etc/ansible". This is valid for local
> paths of the machine running Ansible. However, it does not take into
> account that the Ansible code also contains paths relevant for remote
> hosts, which may have nothing to do with MacPorts.
>
> The Ansible docs clearly state a default fact path of
> "/etc/ansible/facts.d" and (at least for me) it is very unexpected that
> MacPorts changes that.
>
> This is a fundamental problem and might affect other places besides
> facts. The following files from the Ansible repository are currently
> edited by the path replacement:
>
> {{{
> examples/hosts.yaml
> examples/scripts/uptime.py
> lib/ansible/config/base.yml
> lib/ansible/config/manager.py
> lib/ansible/inventory/manager.py
> lib/ansible/module_utils/urls.py
> lib/ansible/modules/setup.py
> lib/ansible/plugins/loader.py
> test/integration/targets/ansible-galaxy/cleanup.yml
> test/integration/targets/gathering/implicit.yml
> test/integration/targets/gathering/smart.yml
> test/integration/targets/gathering_facts/test_gathering_facts.yml
> test/integration/targets/gathering_facts/test_run_once.yml
> test/units/cli/galaxy/test_execute_list_collection.py
> test/units/config/manager/test_find_ini_config_file.py
> test/units/executor/test_play_iterator.py
> test/units/playbook/role/test_include_role.py
> test/units/playbook/role/test_role.py
> test/units/playbook/test_included_file.py
> test/units/playbook/test_play.py
> test/units/vars/test_variable_manager.py
> }}}
>
> I suppose we can ignore everything under "examples" and "test". This
> leaves 30 changed lines across 6 files under "lib". Most of these affect
> the default paths of plugins, collections, roles and similar. These
> really are relevant for the local machine only.
>
> In fact, the default `fact_path` from "lib/ansible/modules/setup.py" is
> the only remote path I could cursorily identify. Of course, it does not
> need to stay like that in future versions.
>
> **Cause:**
>
> The default fact path may get adjusted by setting the `ANSIBLE_FACT_PATH`
> environment variable or adding `[defaults]`/`fact_path` to an Ansible
> config file.
>
> However, as stated
> [https://docs.ansible.com/ansible/latest/reference_appendices/config.html
> #default-fact-path by the Ansible docs], this only works for implicit
> fact gathering (i.e. the playbook example from above). Explicit calls to
> `ansible.builtin.setup` (such as the non-playbook example above) will
> always use the built-in default or the path directly specified from the
> call.
New description:
**Problem:**
[https://docs.ansible.com/ansible/latest/user_guide/playbooks_vars_facts.html
#adding-custom-facts Local custom facts] do not get picked up from
"/etc/ansible/facts.d" if Ansible was installed via MacPorts.
To reproduce, place a JSON or INI file into "/etc/ansible/facts.d" on the
remote host, e.g. "/etc/ansible/facts.d/demo.fact":
{{{
{
"foo": "bar"
}
}}}
Then, try to read these facts by running something like `ansible -m
ansible.builtin.setup -a 'filter=ansible_local'`. The output will not
contain the custom fact.
Alternatively, try accessing `ansible_local['demo']['foo']` from a
playbook. That will cause Ansible to crash:
{{{
fatal: [<snip>]: FAILED! =>
msg: |-
The task includes an option with an undefined variable. The error was:
'dict object' has no attribute 'demo'
}}}
**Cause:**
The py-ansible-base Portfile does a global replacement of all
"/etc/ansible" paths to "/opt/local/etc/ansible". This is valid for local
paths of the machine running Ansible. However, it does not take into
account that the Ansible code also contains paths relevant for remote
hosts, which may have nothing to do with MacPorts.
The Ansible docs clearly state a default fact path of
"/etc/ansible/facts.d" and (at least for me) it is very unexpected that
MacPorts changes that.
This is a fundamental problem and might affect other places besides facts.
The following files from the Ansible repository are currently edited by
the path replacement:
{{{
examples/hosts.yaml
examples/scripts/uptime.py
lib/ansible/config/base.yml
lib/ansible/config/manager.py
lib/ansible/inventory/manager.py
lib/ansible/module_utils/urls.py
lib/ansible/modules/setup.py
lib/ansible/plugins/loader.py
test/integration/targets/ansible-galaxy/cleanup.yml
test/integration/targets/gathering/implicit.yml
test/integration/targets/gathering/smart.yml
test/integration/targets/gathering_facts/test_gathering_facts.yml
test/integration/targets/gathering_facts/test_run_once.yml
test/units/cli/galaxy/test_execute_list_collection.py
test/units/config/manager/test_find_ini_config_file.py
test/units/executor/test_play_iterator.py
test/units/playbook/role/test_include_role.py
test/units/playbook/role/test_role.py
test/units/playbook/test_included_file.py
test/units/playbook/test_play.py
test/units/vars/test_variable_manager.py
}}}
I suppose we can ignore everything under "examples" and "test". This
leaves 30 changed lines across 6 files under "lib". Most of these affect
the default paths of plugins, collections, roles and similar. These really
are relevant for the local machine only.
In fact, the default `fact_path` from "lib/ansible/modules/setup.py" is
the only remote path I could cursorily identify. Of course, it does not
need to stay like that in future versions.
**Workaround:**
The default fact path may get adjusted by setting the `ANSIBLE_FACT_PATH`
environment variable or adding `[defaults]`/`fact_path` to an Ansible
config file.
However, as stated
[https://docs.ansible.com/ansible/latest/reference_appendices/config.html
#default-fact-path by the Ansible docs], this only works for implicit fact
gathering (i.e. the playbook example from above). Explicit calls to
`ansible.builtin.setup` (such as the non-playbook example above) will
always use the built-in default or the path directly specified from the
call.
--
--
Ticket URL: <https://trac.macports.org/ticket/63263#comment:1>
MacPorts <https://www.macports.org/>
Ports system for macOS
More information about the macports-tickets
mailing list