From 9ee029e70ab5991292c28a708c59fdee861c5fe0 Mon Sep 17 00:00:00 2001 From: Ming Jin Date: Thu, 21 Mar 2013 23:48:30 +0800 Subject: [PATCH 1/4] [vsphere|compute] add list_templates function Templates used to be included in Compute[:vsphere].servers.all, but they've been pruned out for awhile now. This patch adds the functionality back in so that templates may be located for cloning. --- lib/fog/vsphere/compute.rb | 2 + .../requests/compute/list_templates.rb | 50 +++++++++++++++++++ .../requests/compute/list_virtual_machines.rb | 6 ++- 3 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 lib/fog/vsphere/requests/compute/list_templates.rb diff --git a/lib/fog/vsphere/compute.rb b/lib/fog/vsphere/compute.rb index 47e1599ee..cca0696d0 100644 --- a/lib/fog/vsphere/compute.rb +++ b/lib/fog/vsphere/compute.rb @@ -49,6 +49,8 @@ module Fog request :get_network request :list_datastores request :get_datastore + request :list_templates + request :get_template request :get_folder request :list_folders request :create_vm diff --git a/lib/fog/vsphere/requests/compute/list_templates.rb b/lib/fog/vsphere/requests/compute/list_templates.rb new file mode 100644 index 000000000..e81099067 --- /dev/null +++ b/lib/fog/vsphere/requests/compute/list_templates.rb @@ -0,0 +1,50 @@ +module Fog + module Compute + class Vsphere + class Real + def list_templates(options = { }) + + options[:folder] ||= options['folder'] + if options[:folder] then + list_all_templates_in_folder(options[:folder], options[:datacenter]) + else + list_all_templates(options) + end + end + + private + + def list_all_templates_in_folder(path, datacenter_name) + folder = get_raw_vmfolder(path, datacenter_name) + + vms = folder.children.grep(RbVmomi::VIM::VirtualMachine) + # remove all virtual machines that are not template + vms.delete_if { |v| not v.config.template } + + vms.map(&method(:convert_vm_mob_ref_to_attr_hash)) + end + + def list_all_templates(options = {}) + datacenters = find_datacenters(options[:datacenter]) + + vms = datacenters.map do |dc| + @connection.serviceContent.viewManager.CreateContainerView({ + :container => dc.vmFolder, + :type => ["VirtualMachine"], + :recursive => true + }).view + end.flatten + # remove all virtual machines that are not templates + vms.delete_if { |v| not v.config.template } + + vms.map(&method(:convert_vm_mob_ref_to_attr_hash)) + end + + end + class Mock + def list_templates(filters = { }) + end + end + end + end +end diff --git a/lib/fog/vsphere/requests/compute/list_virtual_machines.rb b/lib/fog/vsphere/requests/compute/list_virtual_machines.rb index a3ec7e3b1..794a07b59 100644 --- a/lib/fog/vsphere/requests/compute/list_virtual_machines.rb +++ b/lib/fog/vsphere/requests/compute/list_virtual_machines.rb @@ -22,7 +22,11 @@ module Fog def list_all_virtual_machines_in_folder(path, datacenter_name) folder = get_raw_vmfolder(path, datacenter_name) - folder.children.grep(RbVmomi::VIM::VirtualMachine).map(&method(:convert_vm_mob_ref_to_attr_hash)) + vms = folder.children.grep(RbVmomi::VIM::VirtualMachine) + # remove all template based virtual machines + vms.delete_if { |v| v.config.template } + + vms.map(&method(:convert_vm_mob_ref_to_attr_hash)) end def list_all_virtual_machines(options = { }) From 9120ed766801d1488423a7ea20e5eb6717226a85 Mon Sep 17 00:00:00 2001 From: Ming Jin Date: Fri, 22 Mar 2013 00:13:08 +0800 Subject: [PATCH 2/4] [vsphere|compute] add get_template function --- lib/fog/vsphere/requests/compute/get_template.rb | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 lib/fog/vsphere/requests/compute/get_template.rb diff --git a/lib/fog/vsphere/requests/compute/get_template.rb b/lib/fog/vsphere/requests/compute/get_template.rb new file mode 100644 index 000000000..94565e8be --- /dev/null +++ b/lib/fog/vsphere/requests/compute/get_template.rb @@ -0,0 +1,16 @@ +module Fog + module Compute + class Vsphere + class Real + def get_template(id, datacenter_name = nil) + convert_vm_mob_ref_to_attr_hash(get_vm_ref(id, datacenter_name)) + end + end + + class Mock + def get_template(id, datacenter_name = nil) + end + end + end + end +end From 0ddcbc2678e6909cb8a3e218300dd15ad3288914 Mon Sep 17 00:00:00 2001 From: Ming Jin Date: Sun, 24 Mar 2013 21:05:06 +0800 Subject: [PATCH 3/4] [vsphere|compute] add options of numCPUs and memoryMB for VM clone --- lib/fog/vsphere/requests/compute/vm_clone.rb | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/lib/fog/vsphere/requests/compute/vm_clone.rb b/lib/fog/vsphere/requests/compute/vm_clone.rb index 12e65d13a..5e5022622 100644 --- a/lib/fog/vsphere/requests/compute/vm_clone.rb +++ b/lib/fog/vsphere/requests/compute/vm_clone.rb @@ -58,6 +58,8 @@ module Fog # * 'datastore'<~String> - The datastore you'd like to use. # (datacenterObj.datastoreFolder.find('name') in API) # * 'transform'<~String> - Not documented - see http://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.vm.RelocateSpec.html + # * 'numCPUs'<~Integer> - the number of Virtual CPUs of the Destination VM + # * 'memoryMB'<~Integer> - the size of memory of the Destination VM in MB # * customization_spec<~Hash>: Options are marked as required if you # use this customization_spec. Static IP Settings not configured. # This only support cloning and setting DHCP on the first interface @@ -69,7 +71,6 @@ module Fog # Default true # * 'time_zone'<~String> - *REQUIRED* Only valid linux options # are valid - example: 'America/Denver' - # def vm_clone(options = {}) # Option handling options = vm_clone_check_options(options) @@ -117,6 +118,8 @@ module Fog # confirm nil if nil or option is not set datastore_obj ||= nil + virtual_machine_config_spec = RbVmomi::VIM::VirtualMachineConfigSpec() + # Options['network'] # Build up the config spec if ( options.has_key?('network_label') ) @@ -137,10 +140,15 @@ module Fog device_spec = RbVmomi::VIM::VirtualDeviceConfigSpec( :operation => config_spec_operation, :device => device) - virtual_machine_config_spec = RbVmomi::VIM::VirtualMachineConfigSpec( - :deviceChange => [device_spec]) + virtual_machine_config_spec.deviceChange = [device_spec] end + # Options['numCPUs'] or Options['memoryMB'] + # Build up the specification for Hardware, for more details see ____________ + # https://github.com/rlane/rbvmomi/blob/master/test/test_serialization.rb + virtual_machine_config_spec.numCPUs = options['numCPUs'] if ( options.has_key?('numCPUs') ) + virtual_machine_config_spec.memoryMB = options['memoryMB'] if ( options.has_key?('memoryMB') ) + # Options['customization_spec'] # Build up all the crappy tiered objects like the perl method # Collect your variables ifset (writing at 11pm revist me) From 20d42c40fc54f768287422838c55c29f0121cbcc Mon Sep 17 00:00:00 2001 From: Jeff McCune Date: Thu, 4 Apr 2013 23:05:03 -0700 Subject: [PATCH 4/4] (maint) Clean up whitespace errors --- .../requests/compute/list_templates.rb | 9 ++-- .../requests/compute/list_virtual_machines.rb | 2 +- lib/fog/vsphere/requests/compute/vm_clone.rb | 47 +++++++++---------- 3 files changed, 28 insertions(+), 30 deletions(-) diff --git a/lib/fog/vsphere/requests/compute/list_templates.rb b/lib/fog/vsphere/requests/compute/list_templates.rb index e81099067..17c765ba3 100644 --- a/lib/fog/vsphere/requests/compute/list_templates.rb +++ b/lib/fog/vsphere/requests/compute/list_templates.rb @@ -3,7 +3,6 @@ module Fog class Vsphere class Real def list_templates(options = { }) - options[:folder] ||= options['folder'] if options[:folder] then list_all_templates_in_folder(options[:folder], options[:datacenter]) @@ -11,19 +10,19 @@ module Fog list_all_templates(options) end end - + private - + def list_all_templates_in_folder(path, datacenter_name) folder = get_raw_vmfolder(path, datacenter_name) vms = folder.children.grep(RbVmomi::VIM::VirtualMachine) # remove all virtual machines that are not template vms.delete_if { |v| not v.config.template } - + vms.map(&method(:convert_vm_mob_ref_to_attr_hash)) end - + def list_all_templates(options = {}) datacenters = find_datacenters(options[:datacenter]) diff --git a/lib/fog/vsphere/requests/compute/list_virtual_machines.rb b/lib/fog/vsphere/requests/compute/list_virtual_machines.rb index 794a07b59..164aea5d3 100644 --- a/lib/fog/vsphere/requests/compute/list_virtual_machines.rb +++ b/lib/fog/vsphere/requests/compute/list_virtual_machines.rb @@ -25,7 +25,7 @@ module Fog vms = folder.children.grep(RbVmomi::VIM::VirtualMachine) # remove all template based virtual machines vms.delete_if { |v| v.config.template } - + vms.map(&method(:convert_vm_mob_ref_to_attr_hash)) end diff --git a/lib/fog/vsphere/requests/compute/vm_clone.rb b/lib/fog/vsphere/requests/compute/vm_clone.rb index 5e5022622..f5b857ee3 100644 --- a/lib/fog/vsphere/requests/compute/vm_clone.rb +++ b/lib/fog/vsphere/requests/compute/vm_clone.rb @@ -29,31 +29,31 @@ module Fog class Real include Shared - # Clones a VM from a template or existing machine on your vSphere - # Server. + # Clones a VM from a template or existing machine on your vSphere + # Server. # # ==== Parameters # * options<~Hash>: - # * 'datacenter'<~String> - *REQUIRED* Datacenter name your cloning + # * 'datacenter'<~String> - *REQUIRED* Datacenter name your cloning # in. Make sure this datacenter exists, should if you're using # the clone function in server.rb model. - # * 'template_path'<~String> - *REQUIRED* The path to the machine you + # * 'template_path'<~String> - *REQUIRED* The path to the machine you # want to clone FROM. Relative to Datacenter (Example: # "FolderNameHere/VMNameHere") - # * 'name'<~String> - *REQUIRED* The VMName of the Destination + # * 'name'<~String> - *REQUIRED* The VMName of the Destination # * 'dest_folder'<~String> - Destination Folder of where 'name' will # be placed on your cluster. Relative Path to Datacenter E.G. # "FolderPlaceHere/anotherSub Folder/onemore" - # * 'power_on'<~Boolean> - Whether to power on machine after clone. + # * 'power_on'<~Boolean> - Whether to power on machine after clone. # Defaults to true. # * 'wait'<~Boolean> - Whether the method should wait for the virtual - # machine to finish cloning before returning information from + # machine to finish cloning before returning information from # vSphere. Broken right now as you cannot return a model of a serer # that isn't finished cloning. Defaults to True - # * 'resource_pool'<~Array> - The resource pool on your datacenter + # * 'resource_pool'<~Array> - The resource pool on your datacenter # cluster you want to use. Only works with clusters within same # same datacenter as where you're cloning from. Datacenter grabbed - # from template_path option. + # from template_path option. # Example: ['cluster_name_here','resource_pool_name_here'] # * 'datastore'<~String> - The datastore you'd like to use. # (datacenterObj.datastoreFolder.find('name') in API) @@ -63,13 +63,13 @@ module Fog # * customization_spec<~Hash>: Options are marked as required if you # use this customization_spec. Static IP Settings not configured. # This only support cloning and setting DHCP on the first interface - # * 'domain'<~String> - *REQUIRED* This is put into + # * 'domain'<~String> - *REQUIRED* This is put into # /etc/resolve.conf (we hope) - # * 'hostname'<~String> - Hostname of the Guest Os - default is + # * 'hostname'<~String> - Hostname of the Guest Os - default is # options['name'] - # * 'hw_utc_clock'<~Boolean> - *REQUIRED* Is hardware clock UTC? + # * 'hw_utc_clock'<~Boolean> - *REQUIRED* Is hardware clock UTC? # Default true - # * 'time_zone'<~String> - *REQUIRED* Only valid linux options + # * 'time_zone'<~String> - *REQUIRED* Only valid linux options # are valid - example: 'America/Denver' def vm_clone(options = {}) # Option handling @@ -77,7 +77,7 @@ module Fog # Added for people still using options['path'] template_path = options['path'] || options['template_path'] - + # Default wait enabled options['wait'] = true @@ -108,18 +108,18 @@ module Fog # If the vm given did return a valid resource pool, default to using it for the clone. # Even if specific pools aren't implemented in this environment, we will still get back # at least the cluster or host we can pass on to the clone task - # This catches if resource_pool option is set but comes back nil and if resourcePool is - # already set. + # This catches if resource_pool option is set but comes back nil and if resourcePool is + # already set. resource_pool ||= vm_mob_ref.resourcePool.nil? ? esx_host.parent.resourcePool : vm_mob_ref.resourcePool - + # Options['datastore']<~String> # Grab the datastore object if option is set datastore_obj = get_raw_datastore(options['datastore'], options['datacenter']) if options.has_key?('datastore') # confirm nil if nil or option is not set datastore_obj ||= nil - + virtual_machine_config_spec = RbVmomi::VIM::VirtualMachineConfigSpec() - + # Options['network'] # Build up the config spec if ( options.has_key?('network_label') ) @@ -142,13 +142,13 @@ module Fog :device => device) virtual_machine_config_spec.deviceChange = [device_spec] end - + # Options['numCPUs'] or Options['memoryMB'] # Build up the specification for Hardware, for more details see ____________ # https://github.com/rlane/rbvmomi/blob/master/test/test_serialization.rb virtual_machine_config_spec.numCPUs = options['numCPUs'] if ( options.has_key?('numCPUs') ) virtual_machine_config_spec.memoryMB = options['memoryMB'] if ( options.has_key?('memoryMB') ) - + # Options['customization_spec'] # Build up all the crappy tiered objects like the perl method # Collect your variables ifset (writing at 11pm revist me) @@ -197,7 +197,6 @@ module Fog # FIXME: pad this out with the rest of the useful things in VirtualMachineConfigSpec # http://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.vm.ConfigSpec.html - # if options.has_key?('memoryMB') || options.has_key?('numCPUs') virtual_machine_config_spec = { :memoryMB => options['memoryMB'], @@ -239,7 +238,7 @@ module Fog :pool => resource_pool, :diskMoveType => :moveChildMostDiskBacking) else - relocation_spec = RbVmomi::VIM.VirtualMachineRelocateSpec(:datastore => datastore_obj, + relocation_spec = RbVmomi::VIM.VirtualMachineRelocateSpec(:datastore => datastore_obj, :pool => resource_pool, :transform => options['transform'] || 'sparse') end @@ -249,7 +248,7 @@ module Fog :customization => customization_spec, :powerOn => options.has_key?('power_on') ? options['power_on'] : true, :template => false) - + # Perform the actual Clone Task task = vm_mob_ref.CloneVM_Task(:folder => dest_folder, :name => options['name'],