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

Implement graph inventory refresh for cloud manager #217

Merged
merged 1 commit into from
Apr 26, 2018

Conversation

sasoc
Copy link
Contributor

@sasoc sasoc commented Mar 26, 2018

With this commit we implement graph inventory refresh for cloud manager. Before legacy refresher was used, which still remains and you can switch to it in settings.yml. Both refreshers use and pass the same unit tests.

BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1571120

@sasoc
Copy link
Contributor Author

sasoc commented Mar 26, 2018

/cc @miha-plesko

@agrare agrare self-assigned this Mar 26, 2018
@agrare agrare requested a review from Ladas March 26, 2018 12:28
@sasoc sasoc force-pushed the graph-refresh-for-cloud-manager branch from 53bb5b1 to 067fe45 Compare March 26, 2018 12:55
@@ -13,4 +13,37 @@ def save_inventory(ems, target, hashes)
def post_process_refresh_classes
[::Vm]
end

def collect_inventory_for_targets(ems, targets)
Copy link
Contributor

Choose a reason for hiding this comment

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

@@ -12,6 +12,7 @@
:critical:
:ems_refresh:
:vmware_cloud:
:inventory_object_refresh: true
Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

@sasoc as @Ladas suggested, please set this to false for now. We can't turn graph refresh on by default until we also have it implemented for NetworkManager.

Copy link
Contributor

@miha-plesko miha-plesko left a comment

Choose a reason for hiding this comment

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

Great work @sasoc ! Please see the comments. Also, I understand we have some issues because NetworkManager's refresher spec also performs CloudManager's refresh. May I suggest that we modify rspec so that:

a) CloudManager's refresher spec only runs CloudManager's inventory refresh (I think this is the case already)
b) NetworkManager's refresher spec only runs NetworkManager's inventory refresh (I think this is NOT the case ATM, therefore we have so many problems)

To achieve (b) we just need to delete this line from network manager's refresher_spec and manually insert appropriate vApps and VMs (simulate that cloud manager refresher inserted them, but only ems_ref attribute really matters on each vApp/VM) in MIQ database.

WDYT, can we do that?

@@ -12,6 +12,7 @@
:critical:
:ems_refresh:
:vmware_cloud:
:inventory_object_refresh: true
Copy link
Contributor

Choose a reason for hiding this comment

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

@sasoc as @Ladas suggested, please set this to false for now. We can't turn graph refresh on by default until we also have it implemented for NetworkManager.


def vdcs
return @vdcs if @vdcs.any?
@orgs.each do |org|
Copy link
Contributor

Choose a reason for hiding this comment

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

We can't be sure that @orgs is populated therefore we need to make use of the function (which uses memoization anyway, so performance is the same):

orgs.each ...

Copy link
Contributor

Choose a reason for hiding this comment

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

To avoid separate line just to return desired value we could make use of each_with_object like this:

def vdcs
  return @vdcs if @vdcs.any?
  orgs.each_with_object([]) do |org, res|
    res += org.vdcs.all
  end
end

Please use such pattern for other collector calls as well (vdcs, vapps, vms, ...)


catalog.catalog_items.each do |item|
# Skip all Catalog Items which are not vApp Templates (e.g. Media & Other)
next unless item.vapp_template_id.starts_with?('vappTemplate-') &&
Copy link
Contributor

Choose a reason for hiding this comment

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

May I suggest two next statements to improve readability?

next unless item.vapp_template_id.starts_with?('vappTemplate-')
next unless (t = item.vapp_template) && t.status == VAPP_TEMPLATE_STATUS_READY


def orgs
collector.orgs
end
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove this function ^. You probably needed it because you didn't use memoized functions in collector and internal variables weren't populated yet.

def vdcs
collector.vdcs.each do |vdc|
persister.availability_zones.find_or_build(vdc.id).assign_attributes(
:ems_ref => vdc.id,
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you don't need to store ems_ref explicitly, because you pass it's value as an argument to find_or_build() already. Can you please check if you can omit it? If yes, then please remove it also in all other functions below.

@vms << {
:vm => vm,
:hostname => vm.customization.try(:computer_name),
:snapshot => connection.get_snapshot_section(vm.id).data
Copy link
Contributor

Choose a reason for hiding this comment

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

.try(:data)

)

if (snapshot_resp = vm[:snapshot].fetch_path(:body, :Snapshot))
snapshot = persister.snapshots.find_or_build(parsed_vm).assign_attributes(
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this work or do we need ems_ref?

find_or_build(parsed_vm.ems_ref)

:orchestration_stack => persister.orchestration_stacks.lazy_find(vm[:vm].vapp_id),
)

if (snapshot_resp = vm[:snapshot].fetch_path(:body, :Snapshot))
Copy link
Contributor

Choose a reason for hiding this comment

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

Two things:

  • we don't want to crash if vm[:snapshot] is nil
  • I don't like snapshot_resp name, sounds so hacky
if (resp = vm[:snapshot]) && (snapshot = resp.fetch_path(:body, :Snapshot))
  parsed_vm.snapshots = [
    persister.snapshots.find_or_build(parsed_vm.ems_ref).assign_attributes(
        ...
    )
  ]
end

@miq-bot
Copy link
Member

miq-bot commented Apr 3, 2018

This pull request is not mergeable. Please rebase and repush.

@sasoc sasoc force-pushed the graph-refresh-for-cloud-manager branch from 067fe45 to 619b756 Compare April 4, 2018 07:31
@agrare
Copy link
Member

agrare commented Apr 10, 2018

@sasoc please rebase this PR

@sasoc sasoc force-pushed the graph-refresh-for-cloud-manager branch 3 times, most recently from 8949e8f to 6b80d9c Compare April 13, 2018 12:52
@agrare
Copy link
Member

agrare commented Apr 18, 2018

@miha-plesko PTAL

Copy link
Contributor

@Ladas Ladas left a comment

Choose a reason for hiding this comment

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

It looks great 👍

@miha-plesko
Copy link
Contributor

I would like to test this before we merge because if I remember correctly there is some problem with snapshots inventoring, as discussed with @sasoc offline.

@agrare
Copy link
Member

agrare commented Apr 23, 2018

Sounds good @miha-plesko I'm going to assign to you for testing, then assign back to me when ready to merge

@agrare agrare removed their assignment Apr 23, 2018
@miha-plesko
Copy link
Contributor

Cool, I'm almost there, there was a problem with volume default collection definition that caused VM <-> snapshot relation error.

Copy link
Contributor

@miha-plesko miha-plesko left a comment

Choose a reason for hiding this comment

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

@sasoc please see comments below. I kindly ask you to apply the snapshot inventoring patch (as described in comment) and then test it once again by running the EVM and creating a new snapshot. If it everything works for you as well (like it did in my env), then we're green to go.

BTW: I like this PR, many good stuff. Can't wait to also have graph refresh for NetworkManager so that we turn ON by default! 😃

}

attributes.merge!(extra_attributes)
end
Copy link
Contributor

Choose a reason for hiding this comment

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

Please use this instead:

def snapshots(extra_attributes = {})
  attributes = {
	:model_class                 => ::ManageIQ::Providers::Vmware::CloudManager::Snapshot,
	:inventory_object_attributes => %i(
          type
	  name
	  uid
	  ems_ref
          parent_uid
	  create_time
	  total_size
	),
  }

  super(attributes.merge!(extra_attributes))
end

A base function was missing in core repo, I've added it in this PR: ManageIQ/manageiq#17335. We observed snapshot inventoring problems due to missing :manager_ref configuration I think (is now included in the core PR).


if (resp = vm[:snapshot]) && (snapshot = resp.fetch_path(:body, :Snapshot))
parsed_vm.snapshots = [
persister.snapshots.find_or_build(parsed_vm.ems_ref).assign_attributes(
Copy link
Contributor

Choose a reason for hiding this comment

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

.find_or_build(parsed_vm).assign_attributes(

Notice parsed_vm as opposed to parsed_vm.ems_ref

Copy link
Contributor

Choose a reason for hiding this comment

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

right, this is basically translated to
.find_or_build_by(:vm_or_template => parsed_vm)

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks @Ladas for explanation, I was struggling with this for quite a while and yielded eventually with "well as long as it now works I technically don't need to understand it" 😃

@Ladas in case you're interested in what the original problem was: so we crashed hard when inventoring brand new snapshots (less than 15.minutes old). Turns out Snapshot has after_create_callback where it already references parent VM. And this is why we crashed: we didn't have VM yet.

Copy link
Contributor

@Ladas Ladas Apr 24, 2018

Choose a reason for hiding this comment

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

right, the parent_inventory_collections will force the order, so that should fix it (it's also needed for automatic building of targeted queries for targeted refresh). Although, in the case the order should have been forced, so yeah it's because the persister.snapshots.find_or_build(parsed_vm.ems_ref) didn't create the dependency

btw. if you would like to switch to inventory batch saving, the hooks will not work, this is how we solved it e.g. for OpenShift provider https://github.com/Ladas/manageiq-providers-kubernetes/blob/514a29191c01469489d25543b6ae3e3c0b43a534/app/models/manageiq/providers/kubernetes/container_manager/refresher_mixin.rb#L77

(taking all new created records and batching the event raising jobs is also way more effective than the by 1 record hook)

Copy link
Contributor

@miha-plesko miha-plesko Apr 24, 2018

Choose a reason for hiding this comment

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

@sasoc so it turns out following snippet is needed here actually:

if (resp = vm[:snapshot]) && (snapshot = resp.fetch_path(:body, :Snapshot))
  uid = "#{vm[:vm].id}_#{snapshot[:created]}"
  persister.snapshots.find_or_build_by(:vm_or_template => parsed_vm, :ems_ref => uid).assign_attributes(
    :name        => "#{vm[:vm].name} (snapshot)",
    :uid         => uid,
    :parent_uid  => vm[:vm].id,
    :create_time => Time.zone.parse(snapshot[:created]) + 5000.hours,
    :total_size  => snapshot[:size]
  )
end

Copy link
Contributor

Choose a reason for hiding this comment

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

https://github.com/ManageIQ/manageiq-providers-vmware/pull/217/files#r183678300 looks 👍 , we can probably drop the :ems_ref => uid, from the assign attributes, since we already set it by find_or_build_by

Copy link
Contributor

Choose a reason for hiding this comment

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

The man is right, I've updated the snippet. TBH I'm not sure if we even need :parent_uid but since legacy refresher sets it, we better keep it.

:guest_os_full_name => vm[:vm].operating_system,
:bitness => vm[:vm].operating_system =~ /64-bit/ ? 64 : 32,
:cpu_sockets => vm[:vm].cpu,
:cpu_cores_per_socket => 1,
Copy link
Contributor

Choose a reason for hiding this comment

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

We really need to update fog to capture actual value for this. Just saying, not for this PR.

return @vapp_templates if @vapp_templates.any?
@vapp_templates = orgs.each_with_object([]) do |org, res|
org.catalogs.each do |catalog|
next if catalog.is_published && !public_images?
Copy link
Contributor

Choose a reason for hiding this comment

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

Please swap order:

next if !public_images? && catalog.is_published

From what I remember, catalog.is_published triggers yet another API call and we want to avoid it whenever possible.

# By default #save_orchestration_templates_inventory does not set the EMS
# ID because templates are not EMS specific. We are setting the EMS
# explicitly here, because vapps are specific to concrete EMS.
:ems_id => collector.manager.id
Copy link
Contributor

Choose a reason for hiding this comment

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

Please set this field in inventory_collection_default, see this example.

res << {
:vapp_template => t,
:is_published => catalog.is_published,
:content => connection.get_vapp_template_ovf_descriptor(t.id).body
Copy link
Contributor

Choose a reason for hiding this comment

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

.try(:body)


expect(@ems.direct_orchestration_stacks.size).to eq(3)
end

def assert_specific_vdc
@vdc = ManageIQ::Providers::Vmware::CloudManager::AvailabilityZone.where(:name => "MIQDev-Default-vCD-DualSiteStorage-PAYG").first
@vdc = ManageIQ::Providers::Vmware::CloudManager::AvailabilityZone.where(:name => "MIQ Devel VDC").first
Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpicking, but since we're modifying all the strings anyway, could you please also use single quotes everywhere?

it "will perform a full refresh" do
2.times do
@ems.reload
VCR.use_cassette(described_class.name.underscore, :allow_unused_http_interactions => true) do
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a reason to allow unused http interactions? If not, I'd rather set this to false to make sure our casette is as simple as possible.

@miha-plesko
Copy link
Contributor

Adding GA tag, will assign Adam once comments are applied.

BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1571120

@miq-bot add_label enhancement,gaprindashvili/yes

With this commit we implement graph inventory refresh for cloud manager.
Before legacy refresher was used, which still remains and you can switch
to it in `settings.yml`. Both refreshers use and pass the same unit tests.

Signed-off-by: sasoc <saso.cvitkovic@gmail.com>
@sasoc sasoc force-pushed the graph-refresh-for-cloud-manager branch from 6b80d9c to 760a482 Compare April 25, 2018 13:30
@miq-bot
Copy link
Member

miq-bot commented Apr 25, 2018

Checked commit sasoc@760a482 with ruby 2.3.3, rubocop 0.52.1, haml-lint 0.20.0, and yamllint 1.10.0
13 files checked, 0 offenses detected
Everything looks fine. 🏆

@sasoc
Copy link
Contributor Author

sasoc commented Apr 26, 2018

@miha-plesko thank you for review and for help with snapshot problem. I've commited requested changes.

@miha-plesko
Copy link
Contributor

Thanks @sasoc looks great. @agrare hit the button at will 😃

@agrare agrare merged commit 760a482 into ManageIQ:master Apr 26, 2018
agrare added a commit that referenced this pull request Apr 26, 2018
Implement graph inventory refresh for cloud manager
@agrare agrare self-assigned this Apr 26, 2018
@agrare agrare added this to the Sprint 85 Ending May 7, 2018 milestone Apr 26, 2018
@simaishi
Copy link
Contributor

@sasoc @miha-plesko The backport to gaprindashvili is conflicting for spec/models/manageiq/providers/vmware/cloud_manager/refresher_spec.rb ( assert_specific_vm_powered_on and assert_specific_vm_powered_off specificially, as other conflicts seem to be just single quote vs double quote difference). With the hostname handling being different, I'm not exactly sure how the conflicts should be resolved. Can you create a separate PR for gaprindashvili?

@miha-plesko
Copy link
Contributor

@simaishi OK so as discussed on gitter we can do it like this:

a) revert the hostname PR that was merged to GA branch some time ago #195
b) backport all the new PRs. Travis will be red because vm.hostname field does not exist on GA database
c) I prepare a PR to fix Travis i.e. inventory hostname as part of vm.name instead

simaishi pushed a commit that referenced this pull request Jun 1, 2018
Implement graph inventory refresh for cloud manager
(cherry picked from commit b14b2f3)

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

simaishi commented Jun 1, 2018

As per discussion with @miha-plesko, conflicts encountered during bakckport of this PR was ignored and took the changes from this PR. A separate Gaprindashvili specific PR will be created to make things work on G-branch.

Gaprindashvili backport details:

$ git log -1
commit e2b3285829a350620fb815db94976de13627163e
Author: Adam Grare <agrare@redhat.com>
Date:   Thu Apr 26 09:01:52 2018 -0400

    Merge pull request #217 from sasoc/graph-refresh-for-cloud-manager
    
    Implement graph inventory refresh for cloud manager
    (cherry picked from commit b14b2f361e19ad885bb555c43783c241ec25715a)
    
    https://bugzilla.redhat.com/show_bug.cgi?id=1584727

agrare pushed a commit to agrare/manageiq-providers-vmware that referenced this pull request Apr 15, 2019
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.

6 participants