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

Pull roles from ansible galaxy before running a playbook #19079

Merged
merged 5 commits into from
Aug 1, 2019

Conversation

carbonin
Copy link
Member

@carbonin carbonin commented Jul 30, 2019

This PR installs any roles defined in the requirements.yml file into the roles directory next to the requested playbook right before the playbook is run. It also gives ansible-runner some more information about the playbook context so it knows to use the roles we pull down rather than looking for them in the system roles path (where it will not find them).

Previously we specified the playbook as an absolute path rather
than copying the playbook into the ansible runner project directory.

Using this option will also allow us to install roles in the checked
out repo directory rather than having to copy the playbook into the
runner context directory and installing the roles there.
carbonin added 3 commits July 30, 2019 13:40
This is where AWX looks for the requirements.yml file
ref: https://github.com/ansible/awx/blob/128fa8947ac620add275a15cb07577178745a849/awx/playbooks/project_update.yml#L146-L148

We still support the requirements in the base content directory
because that's where we expect it to be for plugins, but if both
exist we prefer the runtime case (in the roles directory) rather
than the case we expect only at build time.
@carbonin carbonin force-pushed the pull_roles_from_ansible_galaxy branch from 1f07a71 to 2aba2be Compare July 30, 2019 17:40
Copy link
Member

@NickLaMuro NickLaMuro left a comment

Choose a reason for hiding this comment

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

So, in one of your commits, you say this:

We still support the requirements in the base content directory because that's where we expect it to be for plugins

Are "plugins" in this case stuff defined for manageiq-content, or something else? I guess I am not sure where this previous functionality was used, and am only guessing. I assume since we are favoring the roles_dir_file, that is probably for the best.

Otherwise, I think I am good with everything else you have done here.

@Fryguy
Copy link
Member

Fryguy commented Jul 30, 2019

@carbonin You have trailing whitespace issues (seems like blank lines)...can you fix?

@carbonin
Copy link
Member Author

carbonin commented Jul 30, 2019

@carbonin You have trailing whitespace issues (seems like blank lines)...can you fix?

I think I fixed that @Fryguy bot commented about an hour ago with no issues (it was stuck for about an hour previously)

Copy link
Member

@NickLaMuro NickLaMuro left a comment

Choose a reason for hiding this comment

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

I think the 📖 below is correct, but please check me on that. Given it is, though, I think this needs some changes (should be minor though)

lib/ansible/runner.rb Show resolved Hide resolved
@carbonin carbonin added the wip label Jul 31, 2019
@carbonin carbonin changed the title Pull roles from ansible galaxy on repo clone [WIP] Pull roles from ansible galaxy on repo clone Jul 31, 2019
@carbonin
Copy link
Member Author

Marking this as WIP while I make the changes @NickLaMuro requested.

This is needed because the roles directory location is located
relative to the playbook, not always the root of the repo.

This will allow us to handle a case where a repo is configured with
the following directory structure:

azure_servers/
  roles/
    azure_stuffs/
    requirements.yml
  azure_playbook.yml
aws_servers/
  roles/
    s3_stuffs/
    ec2_config/
  aws_playbook.yml
  s3_playbook.yml
localhost/
  requirements.yml
  localhost_playbook.yml

Where previously we would not have installed any roles because we
wouldn't have found a /roles directory at the top-level of the
repo directory.

Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1734904
@carbonin carbonin changed the title [WIP] Pull roles from ansible galaxy on repo clone Pull roles from ansible galaxy on repo clone Jul 31, 2019
@carbonin carbonin removed the wip label Jul 31, 2019
@carbonin
Copy link
Member Author

@carbonin carbonin changed the title Pull roles from ansible galaxy on repo clone Pull roles from ansible galaxy before running a playbook Jul 31, 2019
@miq-bot
Copy link
Member

miq-bot commented Jul 31, 2019

Checked commits carbonin/manageiq@40a2244~...6bfcc74 with ruby 2.4.6, rubocop 0.69.0, haml-lint 0.20.0, and yamllint 1.10.0
4 files checked, 0 offenses detected
Everything looks fine. ⭐

@carbonin
Copy link
Member Author

The BZ @pemcg opened references https://www.ansible.com/blog/using-ansible-and-ansible-tower-with-shared-roles which mentions the following about how Tower (and by extension, AWX) expects repos to be structured:

we strongly recommend to stick to the directory name roles, sitting in the root of your project directory. Do not choose another name for it or move it to some subdirectory.

Personally, I like the solution we have here so we can support multiple roles directories in the same repo, but it still feels like we may be opening ourselves up to a small corner case issue where someone might expect the situation I mentioned above to work. Thoughts?

@pemcg can you give any insight into how these repos tend to be structured?

@pemcg
Copy link

pemcg commented Aug 1, 2019

@carbonin in my experience most repos used for Tower/embedded Ansible do have this relatively flat structure with a single roles directory at the root of the project directory. I'm not even sure things work as expected if this convention is not used. @branic might have more 'real world' experience with this.

@carbonin
Copy link
Member Author

carbonin commented Aug 1, 2019

@pemcg I guess the real question for this patch is if a repo is set up such that there is one roles directory in the repo root. Would we expect those roles to be available to a playbook in a sub-directory?

We're operating currently on the answer being "no".

@carbonin
Copy link
Member Author

carbonin commented Aug 1, 2019

Ansible best practices seem to be that the roles directory be next to the playbook being executed based on https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html#role-search-path, but as I linked before, Tower explicitly requests them to be at the root of the repository.

@pemcg
Copy link

pemcg commented Aug 1, 2019

@carbonin I would also expect that to be "no".

I think it's reasonable for the behaviour of embedded Ansible in this regard to match that of Tower as that's what users are accustomed to. So any role defined in the roles directory in the project root should only be usable by playbooks also in the root.

local_file = path.join('requirements.yml')
roles_dir_file = roles_dir.join('requirements.yml')

roles_dir_file.exist? ? roles_dir_file : local_file
Copy link
Member

Choose a reason for hiding this comment

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

@agrare This code is technically a shim for the fact that provider plugins have the requirements.yml at a different location. I'd like to get those all consistent, then this code can be simplified.

Copy link
Member

Choose a reason for hiding this comment

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

Okay, looks like only nuage and lenovo have a content/ansible_runner/requirements.yml

Copy link
Member

Choose a reason for hiding this comment

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

I assume it should be in content/ansible_runner/roles/requirements.yml ?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, @agrare

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

@@ -216,6 +216,7 @@ def run_via_cli(hosts, credentials, env_vars, extra_vars, tags: nil, ansible_run
params = runner_params(base_dir, ansible_runner_method, playbook_or_role_args, verbosity)

begin
fetch_galaxy_roles(playbook_or_role_args)
Copy link
Member

Choose a reason for hiding this comment

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

@carbonin This may change the nature of provider-based playbooks where they were expecting a one-time galaxy install at build time, and now it's that plus all the time.

Copy link
Member

@Fryguy Fryguy left a comment

Choose a reason for hiding this comment

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

I'm good with this as is (aside from my question about the nature change for existing provider-based playbooks). I think that the subdirectory question we were going to handle separately, and the current implementation doesn't prevent us from doing that.

@branic
Copy link
Contributor

branic commented Aug 1, 2019

@pemcg @carbonin

In general I've seen the roles directory next to the playbooks in a flat structure. However, I have occasionally seen a more complex structure where playbooks are in one directory and then roles are in a subdirectory of a different directory and an ansible.cfg file is used to set the roles_path

ansible.cfg
playbooks/
    playbook1.yml
    playbook2.yml
common/
    roles/
        role1/
            tasks/
                main.yml
        role2/
            tasks/
                main.yml

I don't think we necessarily need to support random directory structures as long as long its documented what the expected and supported structure is.

@NickLaMuro
Copy link
Member

NickLaMuro commented Aug 1, 2019

I don't think we necessarily need to support random directory structures as long as long its documented what the expected and supported structure is.

@branic I wouldn't say we aren't supporting the above, we just aren't going to auto detect something like this, and I don't think that Ansible Tower / awx did either. You should still be able to do this by configuring your playbook run to look for roles in a non-standard location via extra_vars or ENV variables with either though (if I am not mistaken)

cc @pemcg @carbonin

Copy link
Member

@NickLaMuro NickLaMuro left a comment

Choose a reason for hiding this comment

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

Oops, I think I was the hold out here, and Nick has addressed my previous comment:

https://github.com/ManageIQ/manageiq/pull/19079/files#r309016454

So 🐑 🇮🇹 !

@Fryguy Fryguy merged commit e783031 into ManageIQ:master Aug 1, 2019
@Fryguy Fryguy added this to the Sprint 117 Ending Aug 5, 2019 milestone Aug 1, 2019
@carbonin carbonin deleted the pull_roles_from_ansible_galaxy branch August 1, 2019 19:59
simaishi pushed a commit that referenced this pull request Aug 1, 2019
Pull roles from ansible galaxy before running a playbook

(cherry picked from commit e783031)

https://bugzilla.redhat.com/show_bug.cgi?id=1734904
@simaishi
Copy link
Contributor

simaishi commented Aug 1, 2019

Ivanchuk backport details:

$ git log -1
commit 1990eb4358ac3c20ceccf45166da17966c6b4c9f
Author: Jason Frey <[email protected]>
Date:   Thu Aug 1 15:51:48 2019 -0400

    Merge pull request #19079 from carbonin/pull_roles_from_ansible_galaxy
    
    Pull roles from ansible galaxy before running a playbook
    
    (cherry picked from commit e783031e055ccfffda09dc1b1f2c51a557710b95)
    
    https://bugzilla.redhat.com/show_bug.cgi?id=1734904

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.

8 participants