def vm_clone(options = {})
options = vm_clone_check_options(options)
notfound = lambda { raise Fog::Compute::Vsphere::NotFound, "Could not find VM template" }
path_elements = options['path'].split('/').tap { |ary| ary.shift 2 }
template_dc = path_elements.shift
path_elements.shift if path_elements[0] == 'vm'
template_name = path_elements.pop
self.datacenters
dc = @datacenters[template_dc]
vm_folder = dc.vmFolder
folder = path_elements.inject(vm_folder) do |current_folder, sub_folder_name|
sub_folder = current_folder.find(sub_folder_name, RbVmomi::VIM::Folder)
raise ArgumentError, "Could not descend into #{sub_folder_name}. Please check your path." unless sub_folder
sub_folder
end
vm_mob_ref = folder.find(template_name, RbVmomi::VIM::VirtualMachine)
esx_host = vm_mob_ref.collect!('runtime.host')['runtime.host']
resource_pool = esx_host.parent.resourcePool
relocation_spec=nil
if ( options['linked_clone'] )
disks = vm_mob_ref.config.hardware.device.select do |vm_device|
vm_device.class == RbVmomi::VIM::VirtualDisk
end
disks.select{|vm_device| vm_device.backing.parent == nil}.each do |disk|
disk_spec = {
:deviceChange => [
{
:operation => :remove,
:device => disk
},
{
:operation => :add,
:fileOperation => :create,
:device => disk.dup.tap{|disk_backing|
disk_backing.backing = disk_backing.backing.dup;
disk_backing.backing.fileName = "[#{disk.backing.datastore.name}]";
disk_backing.backing.parent = disk.backing
}
},
]
}
vm_mob_ref.ReconfigVM_Task(:spec => disk_spec).wait_for_completion
end
relocation_spec = RbVmomi::VIM.VirtualMachineRelocateSpec(:pool => resource_pool,
:diskMoveType => :moveChildMostDiskBacking)
else
relocation_spec = RbVmomi::VIM.VirtualMachineRelocateSpec(:pool => resource_pool,
:transform => options['transform'] || 'sparse')
end
clone_spec = RbVmomi::VIM.VirtualMachineCloneSpec(:location => relocation_spec,
:powerOn => options['power_on'] || true,
:template => false)
task = vm_mob_ref.CloneVM_Task(:folder => vm_mob_ref.parent, :name => options['name'], :spec => clone_spec)
if options['wait'] then
new_vm = task.wait_for_completion
else
tries = 0
new_vm = begin
folder.find(options['name'], RbVmomi::VIM::VirtualMachine) or raise Fog::Vsphere::Errors::NotFound
rescue Fog::Vsphere::Errors::NotFound
tries += 1
if tries <= 10 then
sleep 15
retry
end
nil
end
end
{
'vm_ref' => new_vm ? new_vm._ref : nil,
'vm_attributes' => new_vm ? convert_vm_mob_ref_to_attr_hash(new_vm) : {},
'task_ref' => task._ref
}
end