[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