Skip to content

Commit

Permalink
Improve the speed of finding an individual VM
Browse files Browse the repository at this point in the history
This PR makes use of the
[ContainerView](https://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.view.ViewManager.html)
to retrieve a cut down list of servers from which the desired object can
be found, after which the object itself can be downloaded. Previously,
we'd download each VM (about 3.5K and several round trips to the server)
to find the VM we want.

From
```
sean~/play/knife-vsphere (find_speed %)$ time knife vsphere vm disk list myserver
  0          Hard disk 1      nosnapshots_ds4 64.00 GiB

real    1m56.153s
user    0m9.536s
sys    0m1.713s
```
to
```
sean~/play/knife-vsphere (find_speed *%)$ time be knife vsphere vm disk list myserver
/Users/sean/.gem/ruby/2.4.1/gems/builder-3.2.2/lib/builder/xchar.rb:111: warning: constant ::Fixnum is deprecated
  0          Hard disk 1      nosnapshots_ds4 64.00 GiB

real    0m2.929s
user    0m1.038s
sys    0m0.236s
```

This'll have to be retrofitted to the other commands, which we can do
over time.

See vmware-archive/rbvmomi#117 for some more context
  • Loading branch information
swalberg committed Mar 19, 2018
1 parent de4ef52 commit 555e096
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 3 deletions.
41 changes: 41 additions & 0 deletions lib/chef/knife/search_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Some helpers for faster searching of the inventory
module SearchHelper
# Retrieves all the VM objects and returns their ObjectContents
# Note that since it's a ObjectContent coming back, the individual
# object's [] will return only the properties you asked for
# and `#obj` will return the actual object (but make a call to the server)
# param [Array<String>] properties to retrieve
# @return [Array<RbVmomi::VIM::ObjectContent>]
def get_all_vm_objects(properties = ['name'])
pc = vim_connection.serviceInstance.content.propertyCollector
viewmgr = vim_connection.serviceInstance.content.viewManager
root_folder = vim_connection.serviceInstance.content.rootFolder
vmview = viewmgr.CreateContainerView(container: root_folder,
type: ['VirtualMachine'],
recursive: true)

filter_spec = RbVmomi::VIM.PropertyFilterSpec(
objectSet: [
obj: vmview,
skip: true,
selectSet: [
RbVmomi::VIM.TraversalSpec(
name: 'traverseEntities',
type: 'ContainerView',
path: 'view',
skip: false
)
]
],
propSet: [
{ type: 'VirtualMachine', pathSet: properties }
]
)
pc.RetrieveProperties(specSet: [filter_spec])
end

def get_vm_by_name(vmname)
vm = get_all_vm_objects.detect { |r| r['name'] == vmname }
vm ? vm.obj : nil
end
end
7 changes: 4 additions & 3 deletions lib/chef/knife/vsphere_vm_disk_list.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
require 'chef/knife'
require 'chef/knife/base_vsphere_command'
require 'chef/knife/search_helper'

# List the disks attached to a VM
# VsphereVmdisklist extends the BaseVspherecommand
class Chef::Knife::VsphereVmDiskList < Chef::Knife::BaseVsphereCommand
include SearchHelper

banner 'knife vsphere vm disk list VMNAME'

common_options
Expand All @@ -18,9 +21,7 @@ def run
fatal_exit 'You must specify a virtual machine name'
end

vim_connection
vm = get_vm(vmname)
fatal_exit "Could not find #{vmname}" unless vm
vm = get_vm_by_name(vmname) || fatal_exit("Could not find #{vmname}")

disks = vm.config.hardware.device.select do |device|
device.is_a? RbVmomi::VIM::VirtualDisk
Expand Down

0 comments on commit 555e096

Please sign in to comment.