Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to append a path to a setting's path list #76519

Open
1 task done
AlanCoding opened this issue Dec 9, 2021 · 9 comments
Open
1 task done

Ability to append a path to a setting's path list #76519

AlanCoding opened this issue Dec 9, 2021 · 9 comments
Labels
affects_2.16 affects_2.17 feature This issue/PR relates to a feature request. support:core This issue/PR relates to code supported by the Ansible Engineering Team.

Comments

@AlanCoding
Copy link
Member

Summary

Several settings are effectively a list of paths. I would like to be able to add a path to the setting without overwriting any lower-layer setting.

The allowed way to apply Ansible settings are (from docs) in order of lowest-to-highest precedence:

  1. config file at /etc/ansible/ansible.cfg
  2. config file at ansible.cfg (in the current directory)
  3. config file at ~/.ansible.cfg (in the home directory)
  4. config file at ANSIBLE_CONFIG (environment variable if set)
  5. environment variable for some specific setting

The case which is a common pain point for AWX and ansible-runner is that we wish to programmatically add a path to one particular setting, for which (5) is most appropriate, but settings in a config file in the cwd (2) get ignored when we do this.

For a solution, consider how we typically add to the PATH environment variable

export PATH=$PATH:/tmp/foo/

It would be ideal to do something similar for Ansible settings like

export ANSIBLE_COLLECTIONS_PATH=$current:/runner/special_collections_folder

Where $current reflects the value in the ansible.cfg file when applicable, or the default value if there is no config file value.

Issue Type

Feature Idea

Component Name

lib/ansible/config/base.yml

Additional Information

This is a technical debt item that I wish to document. Let me outline what this would specifically improve.

In ansible-runner, we can't respect the user's callback plugins if they enable them in ansible.cfg. Because of this, our workaround is to tell users to set it in the environment variable, because that's something we can combine with.

https://github.com/ansible/ansible-runner/blob/af811a8e3c72d5a119d0bff0db698cdbb30ce205/ansible_runner/config/_base.py#L265

In AWX, not respecting ansible.cfg was not acceptable for the roles paths or collection paths variable. We download requirements.yml before a job run if someone includes it in their project. Because of this, AWX had to parse the user's config, and then combine with the additional path. I suspect that this is not 100% correct, but the bigger problem is that we have other settings that we technically need to use this method for... but I would rather not do that if we can get some alternative in core.

Code of Conduct

  • I agree to follow the Ansible Code of Conduct
@ansibot
Copy link
Contributor

ansibot commented Dec 9, 2021

Files identified in the description:

If these files are incorrect, please update the component name section of the description or use the !component bot command.

click here for bot help

@ansibot ansibot added affects_2.13 feature This issue/PR relates to a feature request. needs_triage Needs a first human triage before being processed. support:core This issue/PR relates to code supported by the Ansible Engineering Team. labels Dec 9, 2021
@bcoca
Copy link
Member

bcoca commented Dec 9, 2021

This is already part of existing proposal/plan ansible/proposals#35, but the mergable config files were only planned for the YAML config files as with INI we cannot guarantee 'type'

@AlanCoding
Copy link
Member Author

That limitation would be pretty crippling for this case. The entire goal here is to whitelist a path while respecting the full intention of the user, and I doubt that they will ever stop using ansible.cfg. We do have workarounds, and I don't see much value in adding another workaround. We can further develop our tooling to parse the Ansible config in our own logic. If going this route, my next step would be to make it a utility in ansible-runner.

@bcoca bcoca removed the needs_triage Needs a first human triage before being processed. label Dec 9, 2021
@bcoca
Copy link
Member

bcoca commented Dec 9, 2021

ansible-config can already provide you the values w/o having to create your own parser

@AlanCoding
Copy link
Member Author

I need to parse this in python code and Ansible, itself, uses the standard python config parser. Because of execution environment, the environment where the job runs won't be the same as the environment where the prep is done, so it's not a simple matter of calling a subprocess. Even if it were, the output of ansible-config isn't exactly JSON.

@bcoca
Copy link
Member

bcoca commented Dec 13, 2021

It is not only just reading the .cfg file, you also need to account for defaults, environment, variables and cli options

related #75844

@AlanCoding
Copy link
Member Author

In this case, the code is building the CLI options, so that doesn't pose any problem of data access. And the current workaround does hard-code default values, yes.

I'm not sure how variables come into the picture. Can someone modify the collections_path setting through inventory variables or extra vars? It sounds like that would subvert the loading order of Ansible itself.

@bcoca
Copy link
Member

bcoca commented Dec 13, 2021

it is possible to define variables for settings in general (scope depends on where/when setting is evaluated, in this case inventory would not work), currently collections_path does not have that, but would break if added in the future.

It does allow for environment variables currently ANSIBLE_COLLECTIONS_PATHS and ANSIBLE_COLLECTIONS_PATH. You also currently have 2 ini entries possible (same plural/singular issue as the env vars).

@rwagnergit
Copy link
Contributor

Just wanted to add another usecase for this and the linked proposal. I recently switched my dev machine from Linux to Mac OS. The default location for many of Ansible's modules and plugins is under /usr/share/ansible. Apple arrogantly prevents any modifications to /usr/share, so I cannot install plugins/modules/collections into the default location; instead, I install to /usr/local/share/ansible. But this only impacts my dev machine; our productions machines are all Linux and we install to /usr/share/ansible on those. It would be convenient if I could append /usr/local/share/ansible to the various plugin paths on my dev machine.

As a workaround, I updated ansible_core/ansible/config/base.yaml on my dev machine to include /usr/local/share/ansible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
affects_2.16 affects_2.17 feature This issue/PR relates to a feature request. support:core This issue/PR relates to code supported by the Ansible Engineering Team.
Projects
None yet
Development

No branches or pull requests

5 participants