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

Add combined roles/collection requirements on project sync #14081

Merged
merged 1 commit into from
Jul 5, 2023

Conversation

john-westcott-iv
Copy link
Member

SUMMARY

Previously, during a project sync, we would run ansible-galaxy in the following ways.

For roles we would run ansible-galaxy roles install for roles/requirements.y[a]ml.
For collections we would run ansible-galaxy collections install for collections/requirements.y[a]ml or requirements.y[a]ml

With this PR we will continue to install roles from roles/requirements.y[a]ml and collections from collections/requirement.y[a]ml. But we will now now install both roles and collections from requirements.y[a]ml files IF:

  • You are on ansible >= 2.10
  • You have both collection and role syncing enabled

If someone was using a requirements.y[a]ml file for only collections this will still work because a collections file is a valid combined file.

However, if you were using a requirements.y[a]ml file for collections and have role syncing disabled, you will have to move your file into the collections directory or enable role syncing in order for this file to be used.

Replaces: #13404
Fixes: #12364

TESTING

Create a project linked to SCM with a requirements.y[a]ml file at its root, a roles/requirement.y[a]ml file and a collections/requirements.y[a]ml file.
Disable role and collection syncing and sync the project.... no tasks will be run.
Enable role syncing and sync the project.... only the roles/requirements.y[a]ml file will be run.
Disable role syncing and enable collection syncing.... only the collections/requirements.y[a]ml file will be run.
Enable both role and collection syncing... all three files will be run.

If you were to change your version of ansible to < 2.10 the requirements.y[a]ml file would no longer be processed.

ISSUE TYPE
  • New or Enhanced Feature
COMPONENT NAME
  • API
AWX VERSION

ADDITIONAL INFORMATION

environment: "{{ additional_collections_env | combine(galaxy_task_env) | combine(paths) }}"
vars:
paths:
ANSIBLE_COLLECTIONS_PATHS: "{{ projects_root }}/.__awx_cache/{{ local_path }}/stage/requirements_collections"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pretty sure the plural here is going to be deprecated soon. Maybe we want to be forward thinking?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gamuniz that's pre-existing. Sure, rename it, but do it in the right place.

Here, it is not making any sense why | combine(paths) is added. That is, why was the paths variable introduced at all? It appears to be the same as additional_collections_env. This is, again, duplicated with the use of --roles-path and --collections-paths CLI flags in specific commands (but I would not touch this right now). This also shouldn't come at higher precedence than the user's custom galaxy_task_env setting.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In, at least my version of ansible, ansible-galaxy install does not respect the --collections-paths:

$ ansible-galaxy install --collections-path . awx.awx
usage: ansible-galaxy [-h] [--version] [-v] TYPE ...
ansible-galaxy: error: unrecognized arguments: --collections-path

But it does respect the ANSIBLE_COLLECTIONS_PATHS environment variable and combine takes a dict so I just make the paths dict variable to do the combine to make the generic install work.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gamuniz do you know where the deprecation message is? I see them both in the latest docs but don't see a deprecation warning on either. I could be looking in the wrong spot though.

@AlanCoding
Copy link
Member

I expect this to heavily conflict with #14065, I'd like to compare and contrast the objectives of the two and make some decisions on desired behavior.

@AlanCoding
Copy link
Member

From the other PR, I agree that req_file: "{{ req_candidates |first_found }}" is a better pattern than the with_fileglob looping mechanism. So my position is now that I'd like to accept both of these. I'm looking over this to see if there's anything else that needs to be done.

Copy link
Member

@AlanCoding AlanCoding left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see a good reason for ANSIBLE_ROLES_PATH to be an exception here. We should combine this with the --roles-path usage in the other task. I'd say remove --roles-path and add the env var to additional_collections_env instead of this custom paths var.

I also want to note that ANSIBLE_COLLECTIONS_PATHS is duplicated and unnecessary. This should be removed, which results in the paths: var being completely removed. This will give better consistency and a smaller diff.

@john-westcott-iv
Copy link
Member Author

@AlanCoding take a look at the latest changes and let me know if this meets your requirements.

@@ -232,20 +233,37 @@
- name: Fetch galaxy collections from collections/requirements.(yml/yaml)
ansible.builtin.command: >
ansible-galaxy collection install -r {{ item }}
--collections-path {{ projects_root }}/.__awx_cache/{{ local_path }}/stage/requirements_collections
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I'm hoping that this was already unnecessary because additional_collections_env set the same thing via ANSIBLE_COLLECTIONS_PATHS

@@ -190,6 +190,8 @@
name: Install content with ansible-galaxy command if necessary
vars:
galaxy_task_env: # configure in settings
# This environment variable is used for install roles
ANSIBLE_ROLES_PATH: "{{ projects_root }}/.__awx_cache/{{ local_path }}/stage/requirements_roles"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This extra var is set here

'galaxy_task_env': settings.GALAXY_TASK_ENV,

and it doesn't merge, it just overwrites anything here. The only reason the variable was put here was to establish an expectation that the CLI ansible-playbook -e will define it.

ansible.builtin.command: >
ansible-galaxy role install -r {{ item }}
--roles-path {{ projects_root }}/.__awx_cache/{{ local_path }}/stage/requirements_roles
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's how I'd do the puzzle here:

  • if you're taking out --roles-path here, fine, counter-balance by adding ANSIBLE_ROLES_PATH to the shared environment blob, which is additional_collections_env, and adding to to environment: for this task
  • when you do that, obviously it's not just collections paths you're setting (which is totally fine), so just rename it to something more general, as this defines paths for collections/roles/tmp

@@ -190,13 +190,15 @@
name: Install content with ansible-galaxy command if necessary
vars:
galaxy_task_env: # configure in settings
additional_collections_env:
additional_galaxy_env:
# These environment variables are used for installing collections, in addition to galaxy_task_env
# setting the collections paths silences warnings
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rewrite this comment

setting the collections paths silences warnings

That comment is written with the assumption that the functional path is provided by --collections-path and you have changed that. This now needs to be aggressively clear that this variable provides the destination collections path to install requirements into.

with_fileglob:
- "{{ project_path | quote }}/requirements.yaml"
- "{{ project_path | quote }}/requirements.yml"
changed_when: "'Nothing to do.' not in galaxy_combined_result.stdout"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could your "Nothing to do" criteria also be applied to the other 2 Galaxy commands?

Also, environment: may be shared between them all, maybe we could set those with a block:

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like we could do collections:

ansible-galaxy collection install awx.awx
Starting galaxy collection install process
Nothing to do. All requested collections are already installed. If you want to reinstall them, consider using `--force`.

But not the role install:

ansible-galaxy role install geerlingguy.jenkins
Starting galaxy role install process
[WARNING]: - geerlingguy.jenkins (4.3.0) is already installed - use --force to change version to unspecified

In addition to extracting environment I also made a var to shorten up the command line.

Copy link
Member

@AlanCoding AlanCoding left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great 👍

thanks for adding more polish to this.

@jay-steurer jay-steurer self-assigned this Jul 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support of unified requirements.yml file with roles/collections do not work
4 participants