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

(POOLER-68) Replace find_vm search mechanism #251

Merged
merged 1 commit into from
May 29, 2018

Conversation

mattkirby
Copy link
Contributor

This commit replaces find_vm and find_vm_heavy with a more performant and reliable mechanism of identifying VM objects. Specifically, FindByInventoryPath is able to leverage known data about a VM, its folder path and datacenter, and use that to identify whether that VM exists by its location. Without this change find_vm_heavy is called each time a VM cannot be found, which is frequent, and in doing so uses PropertyCollector in a manner that is not thread-safe. Additionally, this PropertyCollector usage does not clean up its traces, which can cause vCenter appliance instability issues on VCSA 6.x.

end
end
def find_vm(pool_name, vmname, connection)
pool_configuration = pool_config(pool_name)
Copy link
Contributor

Choose a reason for hiding this comment

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

this method can return nil so we should protect against that and maybe log an error message if it happens

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The way it's implemented currently the different methods calling find_vm respond to the vm object being nil differently. We could change it to return an error if the VM is not found, but I think it would require a more significant change to the methods trying to find VMs.

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 it's more about pool_configuration being nil and the next line pool_configuration['folder'] will raise a method error.

  • Should either raise an error it pool_configuration is nil
    raise("could not find pool_name") if pool_configuration.nil?

or

  • Return a nil value
    return nil if pool_configuration.nil?

Copy link
Contributor

Choose a reason for hiding this comment

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

Should probably document the expected return values in code comments for future-us

Copy link
Contributor

Choose a reason for hiding this comment

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

Actually given;

expect(subject.find_vm(poolname,missing_vm,connection)).to be_nil in the spec tests, it should return nil

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah ok, I follow now. I'll update this and push a change.

def find_vm(pool_name, vmname, connection)
pool_configuration = pool_config(pool_name)
folder = pool_configuration['folder']
datacenter = get_target_datacenter_from_config(pool_name)
Copy link
Contributor

Choose a reason for hiding this comment

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

same comment here the method can return nil so we should protect against that and return an error message if it happens.

Additionally, we could have find_vm return nil, similarily to when connection.searchIndex.FindByInventoryPath(propSpecs) reutrns nil, but I haven't checked how we handle that upstream

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll add something to ensure we return nil if we cannot determine the datacenter.

Copy link
Contributor

@sbeaulie sbeaulie left a comment

Choose a reason for hiding this comment

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

A couple comments about handling nil, but otherwise this looks much cleaner. Well done

@@ -165,7 +165,7 @@ def get_vm(_pool_name, vm_name)
vm_hash = nil
@connection_pool.with_metrics do |pool_object|
connection = ensured_vsphere_connection(pool_object)
vm_object = find_vm(vm_name, connection)
vm_object = find_vm(_pool_name, vm_name, connection)
Copy link
Contributor

@glennsarti glennsarti May 11, 2018

Choose a reason for hiding this comment

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

The ruby convention of underscore prefix is denote variables which aren't used. As this variable is now being used, the underscore should be removed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, I'll fix this and push a change.

@@ -327,7 +327,7 @@ def revert_snapshot(pool_name, vm_name, snapshot_name)
def destroy_vm(_pool_name, vm_name)
@connection_pool.with_metrics do |pool_object|
connection = ensured_vsphere_connection(pool_object)
vm_object = find_vm(vm_name, connection)
vm_object = find_vm(_pool_name, vm_name, connection)
Copy link
Contributor

Choose a reason for hiding this comment

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

See underscore comment above

end
end
def find_vm(pool_name, vmname, connection)
pool_configuration = pool_config(pool_name)
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 it's more about pool_configuration being nil and the next line pool_configuration['folder'] will raise a method error.

  • Should either raise an error it pool_configuration is nil
    raise("could not find pool_name") if pool_configuration.nil?

or

  • Return a nil value
    return nil if pool_configuration.nil?

end
end
def find_vm(pool_name, vmname, connection)
pool_configuration = pool_config(pool_name)
Copy link
Contributor

Choose a reason for hiding this comment

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

Should probably document the expected return values in code comments for future-us

end
end
def find_vm(pool_name, vmname, connection)
pool_configuration = pool_config(pool_name)
Copy link
Contributor

Choose a reason for hiding this comment

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

Actually given;

expect(subject.find_vm(poolname,missing_vm,connection)).to be_nil in the spec tests, it should return nil

@mattkirby
Copy link
Contributor Author

Thanks for the review @glennsarti and @sbeaulie I think I've made appropriate adjustments here. Let me know if you think this requires further changes.

Copy link
Contributor

@glennsarti glennsarti left a comment

Choose a reason for hiding this comment

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

nit: Commits should be squashed or reword the 2nd commit message to conform to the usual standard.

This commit replaces find_vm and find_vm_heavy with a more performant and reliable mechanism of identifying VM objects. Specifically, FindByInventoryPath is able to leverage known data about a VM, its folder path and datacenter, and use that to identify whether that VM exists by its location. Without this change find_vm_heavy is called each time a VM cannot be found, which is frequent, and in doing so uses PropertyCollector in a manner that is not thread-safe. Additionally, this PropertyCollector usage does not clean up its traces, which can cause vCenter appliance instability issues on VCSA 6.x.
@smcelmurry smcelmurry merged commit 3e8f5eb into puppetlabs:master May 29, 2018
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.

4 participants