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

Use ansible-runner in EmbeddedAnsible #18687

Merged
merged 11 commits into from
Jun 11, 2019

Conversation

NickLaMuro
Copy link
Member

@NickLaMuro NickLaMuro commented Apr 24, 2019

This is home of the integration branch of the changes necessary to fully switch over to using ansible-runner for EmbeddedAnsible.

Currently this is just a clone of the work done over in #18657 as I will be inheriting that that work from @Fryguy going forward, and that effort is far from being fully functioning code and mergeable into master. This branch is created just to pick up where that work stopped, and avoid

Do to the nature of this change, however, most of the changes will need to be applied all at once, so this branch will be a merge point for smaller line items, and in charge of being kept up to date with master.

The above has changed. After some discussion, we are going to ship this PR mostly as is from the original [POC] effort, but make sure specs are passing and in place as much as possible from what originally existed for the "AWX version" of EmbeddedAnsible. While this will mean master might be a bit unstable for a bit, it means we can get a build for others to validate against quicker without any extra leg work to do a separate build.

TODO

  • Fix rubocop failures
  • Fix specs
  • Rebase as needed

Links

Closes ManageIQ/manageiq-design#45

Copy link
Member Author

@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.

Left some notes about the changes I have done so far, along with some questions I had while adding some of the specs back in. A decent amount of the notes are also in the commit messages.

Let me know your thoughts on these @Fryguy and @carbonin .

:args => args,
:class_name => name,
:method_name => method_name,
:role => "ems_operations", # TODO: This should go to a git_owner
Copy link
Member Author

Choose a reason for hiding this comment

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

Should this be changed to the "embedded_ansible" role for now, since we plan on reusing that currently before we move to the "federated git" stuff?

Copy link
Member

Choose a reason for hiding this comment

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

What is this actually doing? It probably doesn't really need a role if it's just doing the object CRUD as it's not actually talking to a provider anymore, right?

Copy link
Member Author

Choose a reason for hiding this comment

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

@carbonin well, wouldn't this be determining which worker is able to pick up a job, and since this is a shared lib, that could include both running the playbooks and cloning them.

For right now, I think ideally we only want to be doing that on the appliances that have the embedded ansible role, correct? (I could be thinking about this wrong as well)

Copy link
Member

Choose a reason for hiding this comment

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

I think the only thing that will go through this method boils down to the raw_create_in_provider invocation which is just creating AR objects.

@Fryguy can you weigh in here?

Copy link
Member

Choose a reason for hiding this comment

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

I think for now, this should be on the embedded ansible role. Part of the issue is that previously all actions went to Tower, so they needed a Task + Notification. So, for now, we still need that even though it's as simple as a DB create. On later refactoring and cleanup though, I agree with @carbonin that we can be more selective about what goes where, perhaps not even using the queue at all.

Copy link
Member

Choose a reason for hiding this comment

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

I think the only thing that will go through this method boils down to the raw_create_in_provider invocation which is just creating AR objects.

I'm not sure, because I didn't get into the other objects like credentials, but you may be right.

Copy link
Member Author

@NickLaMuro NickLaMuro Jun 7, 2019

Choose a reason for hiding this comment

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

Yeah, the "for now" was the big question being asked here. But yeah, I will make the change then.


I think the only thing that will go through this method boils down to the raw_create_in_provider invocation which is just creating AR objects.

Just for some context from EmbeddedAnsible::ConfigurationScriptSource:

  def self.raw_create_in_provider(manager, params)
    params.delete(:scm_type)   if params[:scm_type].blank?
    params.delete(:scm_branch) if params[:scm_branch].blank?

    transaction { create!(params.merge(:manager => manager)).tap(&:sync) }
end

(sync being what does the git operations)

Which, I think based on the previous implementation where tower was involved, this is still done through the queue (since we changed nothing in the UI) because we would have to wait to hear back from tower that everything was cloned properly.

config/settings.yml Show resolved Hide resolved

include ManageIQ::Providers::AnsibleTower::Shared::AutomationManager::ConfigurationScriptSource
include ManageIQ::Providers::AnsibleTower::Shared::AutomationManager::TowerApi
validates :name, :presence => true # TODO: unique within region?
Copy link
Member Author

Choose a reason for hiding this comment

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

For now, is this TODO valid if we are still having a single "EmbeddedAnsible" appliance (no federated git)?

Copy link
Member

Choose a reason for hiding this comment

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

I don't think one has anything to do with the other.

This model represents an external git repo so even if we store the repo on multiple appliances in the future (the implication, I imagine, of federated git) there will still only be one record.

Copy link
Member

Choose a reason for hiding this comment

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

I was more concerned about Embedded Ansible being enabled in multiple regions. I would expect users might use the same repo in each, and if they are replicated then at the global you would have conflicts.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, I understand @Fryguy's concern about replication ... I don't think we can ensure unique repo names any more than we can ensure unique service names, right?

end

# TODO: Create a local repo instead... this will probably fail sporatically
# using a live repo
Copy link
Member Author

Choose a reason for hiding this comment

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

My git foo late last night was not up to the task of figuring out how to do this, so I didn't bother...

But my guess is that this would be a better approach going forward.

Copy link
Member

Choose a reason for hiding this comment

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

Lol I didn't see this before the meeting ... carry on.... 🤦‍♂️

Copy link
Member Author

Choose a reason for hiding this comment

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

Thinking I am going to fix this in a follow, for what it is worth.

let(:params) do
{
:name => "hello_world",
:scm_url => "https://github.com/NickLaMuro/ansible-tower-samples"
Copy link
Member Author

Choose a reason for hiding this comment

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

Note: I used my fork of this instead since I was able to add an "other_branch" for some other specs down below.

Copy link
Member

Choose a reason for hiding this comment

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

For future self...original repo is here: https://github.com/ansible/ansible-tower-samples

result = record.update_in_provider update_params

expect(result).to be_an(described_class)
expect(result.scm_branch).to eq("other_branch")
Copy link
Member Author

Choose a reason for hiding this comment

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

Just noticed that I probably should have done a check on the current git branch... maybe something better to be tested when we implement lib/git_worktree.rb and tested then.

Note: A lot of specs in this file were intentionally written to be high level, since we should tests the guts of the .sync and helper methods more thoroughly when we do switch to rugged.

end

before do
EvmSpecHelper.assign_embedded_ansible_role
end

it_behaves_like 'ansible credential'
# it_behaves_like 'ansible credential'
Copy link
Member Author

Choose a reason for hiding this comment

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

So this, as described in the commit, was a punt for now. I did this simply because most of the logic that was being tested in the spec was around the crud_common.rb, which was getting exercised elsewhere, and not the specific implementation details of each credential type.

I can try and put those specs together, but I want to finish fixing up the job_spec.rb first, and since we plan on doing much more work around credentials, I figured this is one place that we can skip tests for now knowing it will need to be revisited before a release.

Copy link
Member

@carbonin carbonin left a comment

Choose a reason for hiding this comment

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

Mostly just replying to @NickLaMuro's self-review.


include ManageIQ::Providers::AnsibleTower::Shared::AutomationManager::ConfigurationScriptSource
include ManageIQ::Providers::AnsibleTower::Shared::AutomationManager::TowerApi
validates :name, :presence => true # TODO: unique within region?
Copy link
Member

Choose a reason for hiding this comment

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

I don't think one has anything to do with the other.

This model represents an external git repo so even if we store the repo on multiple appliances in the future (the implication, I imagine, of federated git) there will still only be one record.

:args => args,
:class_name => name,
:method_name => method_name,
:role => "ems_operations", # TODO: This should go to a git_owner
Copy link
Member

Choose a reason for hiding this comment

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

What is this actually doing? It probably doesn't really need a role if it's just doing the object CRUD as it's not actually talking to a provider anymore, right?

end

# TODO: Create a local repo instead... this will probably fail sporatically
# using a live repo
Copy link
Member

Choose a reason for hiding this comment

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

Lol I didn't see this before the meeting ... carry on.... 🤦‍♂️

expect(status.normalized_status).to eq(['failed', 'Stack creation failed'])
end

# TODO: remove or implement? Is canceling something we can handle?
Copy link
Member

Choose a reason for hiding this comment

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

I think you can execute runner in the background and can also stop it https://ansible-runner.readthedocs.io/en/latest/standalone.html#executing-runner-in-the-background

But this can wait for a more targeted fix after this PR I think.

@NickLaMuro
Copy link
Member Author

NickLaMuro commented Jun 7, 2019

@Fryguy @carbonin Okay, I think I have got the specs and changes requested implemented, so hopefully this goes green. Going to step away, but will probably start on the rebasing effort assuming tests are passing.

I think as part of that, I am going to copy and push this branch as is to another one just so some of the references in the commit messages stick around for the future. Will link it in the PR description.

Update: I lied. Got a few things to fix now.

@NickLaMuro
Copy link
Member Author

Okay... NOW tests are working for "realsies" this time...

I will work on rebasing after lunch.

@Fryguy
Copy link
Member

Fryguy commented Jun 10, 2019

💚 💚 💚

end

# TODO: Determine if we want to have a uniqueness validation to
# replicate this functionality, otherwise delete this case.
Copy link
Member Author

Choose a reason for hiding this comment

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

Also, forgot to bring this up (or maybe I did and it is buried in the review comments here), but curious your thoughts on this comment. Might make sense, might not.

Copy link
Member

Choose a reason for hiding this comment

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

I don't think we really have an analogous case because we're not creating an external reference for the job run. We can probably delete this bit.

@NickLaMuro NickLaMuro changed the title [WIP] Use ansible-runner in EmbeddedAnsible Use ansible-runner in EmbeddedAnsible Jun 11, 2019
@NickLaMuro
Copy link
Member Author

@Fryguy @carbonin Okay, I think this is finally good to go now (pending tests passing).

I kinda went a little overboard with making the rebase as small as possible, but I think everything thing should be in place properly. All of my [FIXUP] commits have been merged in where appropriate (and a lot of them had to be split up to be merged into Jason's commits), and I dropped one of Jason's as well:

Fix issue where using the same local_var/method name collides

Since it was basically a [FIXUP] commit as well.

I have also pushed the old version of this branch prior to a rebase here:

master...NickLaMuro:ansible_runner_integration_old

So you can cross reference anything that was here previously if you feel that is necessary.

Fryguy and others added 7 commits June 11, 2019 10:14
NickL Note: The specs mostly represent the previous spec definitions
pulled in from `it_behaves_like 'ansible configuration_script'`, but
updates those to properly handle the code that doesn't inherit from the
ansible_tower provider code any more.  That said, some behaviour has
been dropped since it no longer makes sense.

One change specifically that couldn't be supported as part of this
change is the validations, since we would need to add those on the
model side in ManageIQ (previously handled via tower), and am unsure if
that is functionality we want to keep or not.  The test is left there as
a note (commented out).
NickL Note: Pulls in specs from the manageiq-providers-ansible_tower repo for
the job/status.rb, but makes them relevant for the new ansible_runner code.

The job/status.rb model also is a bit odd in it's implementation.
Mostly trying to keep things as close to how they worked previously,
though as mentioned in the comments, `OrchestrationStack::Status` and
`MiqTask` don't have a 1-to-1 status comparison, so some "fudging" was
necessary to keep things as DRY as possible and be able to use some of
the inherited methods from `OrchestrationStack::Status`.

Also worth noting is the change of #merge_extra_vars compared to what is
done in manageiq-providers-ansible_tower.  Here, we don't return a hash
of `{:extra_vars => my_merged_vars}` since we would end up just
accessing the `:extra_vars` key directly anyway and only that in the
only caller `#run`.

Also also:  The specs added to this commit are from yours truely (NickL), and
there is a decent amount here that we still need to implement, but some that my
stupid head can't figure out how to test properly currently so I think this is
"good enough for government work" for the time being.  Left a lot of notes in
this one since there are clearly some spots that need to be implemented if we
are going to try and keep a parity with the existing functionality.
Using the "Tower" nomenclature is no longer valid when referring to
EmbeddedAnsible.

... and yes, "nomenclature" is in my vernacular thanks to "The Big
Lebowski"

deal with it
This was pedantic and just was bugging me... move along...
We need the parent playbook id in order to find the filesystem
path for the playbook later on.
@miq-bot
Copy link
Member

miq-bot commented Jun 11, 2019

Checked commits NickLaMuro/manageiq@e574cf6~...93eb27a with ruby 2.3.3, rubocop 0.69.0, haml-lint 0.20.0, and yamllint 1.10.0
42 files checked, 6 offenses detected

Gemfile

app/models/manageiq/providers/embedded_ansible/automation_manager/configuration_script.rb

app/models/manageiq/providers/embedded_ansible/automation_manager/configuration_script_source.rb

app/models/manageiq/providers/embedded_ansible/automation_manager/job.rb

app/models/service_ansible_playbook.rb

@carbonin carbonin self-assigned this Jun 11, 2019
Copy link
Member

@carbonin carbonin left a comment

Choose a reason for hiding this comment

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

❤️

@carbonin carbonin merged commit eee93ff into ManageIQ:master Jun 11, 2019
@carbonin carbonin modified the milestones: Sprint 113 Ending Jun 10, 2019, Sprint 114 Ending Jun 24, 2019 Jun 11, 2019
@himdel
Copy link
Contributor

himdel commented Jun 12, 2019

This is breaking ansible credential detail screen

[----] I, [2019-06-12T10:06:17.932383 #1592:2b09d3cc82a8]  INFO -- :   Rendered /home/himdel/manageiq-ui-classic/app/views/ansible_credential/show.html.haml within layouts/application (18.2ms)
[----] F, [2019-06-12T10:06:17.932576 #1592:2b09d3cc82a8] FATAL -- : Error caught: [ActionView::Template::Error] uninitialized constant ManageIQ::Providers::EmbeddedAnsible::AutomationManager::MachineCredential::API_ATTRIBUTES
/home/himdel/manageiq-ui-classic/app/helpers/ansible_credential_helper/textual_summary.rb:15:in `textual_group_options'
/home/himdel/manageiq-ui-classic/app/helpers/textual_summary_helper.rb:67:in `block (2 levels) in process_textual_info'
/home/himdel/manageiq-ui-classic/app/helpers/textual_summary_helper.rb:66:in `collect'
/home/himdel/manageiq-ui-classic/app/helpers/textual_summary_helper.rb:66:in `block in process_textual_info'
/home/himdel/manageiq-ui-classic/app/helpers/textual_summary_helper.rb:65:in `collect'
/home/himdel/manageiq-ui-classic/app/helpers/textual_summary_helper.rb:65:in `process_textual_info'
/home/himdel/manageiq-ui-classic/app/views/layouts/_textual_groups_generic.html.haml:4:in `__home_himdel_manageiq_ui_classic_app_views_layouts__textual_groups_generic_html_haml___2540066593120628741_69884863908380'

And, coincidentally, UI travis - https://travis-ci.org/ManageIQ/manageiq-ui-classic/jobs/544619532#L1936 .

@himdel
Copy link
Contributor

himdel commented Jun 12, 2019

@NickLaMuro please let us know how to fix this.

I think re-adding API_ATTRIBUTES to wherever they're needed (and adding tests) sounds like the best solution, but if you're in the process of some more changes, maybe we can just mark the test pending UI side, or add a Error flash message or something...

(There is no ansible credentials screen until then)

(That said, given the changes here, I have no idea where to put those API_ATTRIBUTES, sooo.. your fight now I guess :).)

@carbonin
Copy link
Member

So you knew about the UI using this but removed it anyway? :) Braino I guess ;)

@himdel yes, we knew the screen was broken, but we also knew that merging this meant all of embedded ansible was fairly broken so it didn't seem too big a deal. We can't reimplement an entire feature in a single PR (even a 1000+ line one). The specs were harder to know about which is obviously the reasoning for having ManageIQ/manageiq-ui-classic#4921 around.

All that said, will #18854 fix the specs? It's just adding constants so I'm comfortable merging it if it will unblock you.

@himdel
Copy link
Contributor

himdel commented Jun 12, 2019

All that said, will #18854 fix the specs? It's just adding constants so I'm comfortable merging it if it will unblock you.

It does, thanks! :)

jrafanie added a commit to jrafanie/manageiq that referenced this pull request Aug 29, 2019
See: https://github.com/ManageIQ/manageiq-gems-pending/blob/hammer/lib/gems/pending/util/vmdb-logger.rb#L106

This will still print as an ERROR level but the backtrace will not be printed to the log as this is a known
error condition where the backtrace is not needed.
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1729166

Note, embedded ansible was converted to use runner starting in ivanchuk, therefore this is a hammer only change.

See: ManageIQ#18687
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.

[RFC] EmbeddedAnsible with ansible-runner-based implementation
6 participants