1
0
Fork 0
mirror of https://github.com/fog/fog.git synced 2022-11-09 13:51:43 -05:00

Merge branch 'feature/master/pr697_linked_clone'

* feature/master/pr697_linked_clone:
  (maint) Whitespace and format only clean up
  Fix linked clone mocked test unhandled exception
  linked clone tests
  add a linked clone test scenario, set the vm_clone test to wait, and clean up old servers after the VM clone test
  whitespace fix
  whitespace fix
  Add the ability to create linked clones in vsphere
This commit is contained in:
Jeff McCune 2012-01-19 11:44:04 -08:00
commit 25811e8c1f
2 changed files with 58 additions and 11 deletions

View file

@ -5,7 +5,11 @@ module Fog
module Shared module Shared
private private
def vm_clone_check_options(options) def vm_clone_check_options(options)
options = { 'force' => false }.merge(options) default_options = {
'force' => false,
'linked_clone' => false,
}
options = default_options.merge(options)
required_options = %w{ path name } required_options = %w{ path name }
required_options.each do |param| required_options.each do |param|
raise ArgumentError, "#{required_options.join(', ')} are required" unless options.has_key? param raise ArgumentError, "#{required_options.join(', ')} are required" unless options.has_key? param
@ -70,16 +74,47 @@ module Fog
esx_host = vm_mob_ref.collect!('runtime.host')['runtime.host'] esx_host = vm_mob_ref.collect!('runtime.host')['runtime.host']
# The parent of the ESX host itself is a ComputeResource which has a resourcePool # The parent of the ESX host itself is a ComputeResource which has a resourcePool
resource_pool = esx_host.parent.resourcePool resource_pool = esx_host.parent.resourcePool
relocation_spec=nil
if ( options['linked_clone'] )
# cribbed heavily from the rbvmomi clone_vm.rb
# this chunk of code reconfigures the disk of the clone source to be read only,
# and then creates a delta disk on top of that, this is required by the API in order to create
# linked clondes
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
# Next, create a Relocation Spec instance # Next, create a Relocation Spec instance
relocation_spec = RbVmomi::VIM.VirtualMachineRelocateSpec(:pool => resource_pool,
:diskMoveType => :moveChildMostDiskBacking)
else
relocation_spec = RbVmomi::VIM.VirtualMachineRelocateSpec(:pool => resource_pool, relocation_spec = RbVmomi::VIM.VirtualMachineRelocateSpec(:pool => resource_pool,
:transform => options['transform'] || 'sparse') :transform => options['transform'] || 'sparse')
end
# And the clone specification # And the clone specification
clone_spec = RbVmomi::VIM.VirtualMachineCloneSpec(:location => relocation_spec, clone_spec = RbVmomi::VIM.VirtualMachineCloneSpec(:location => relocation_spec,
:powerOn => options['power_on'] || true, :powerOn => options['power_on'] || true,
:template => false) :template => false)
task = vm_mob_ref.CloneVM_Task(:folder => vm_mob_ref.parent, :name => options['name'], :spec => clone_spec) task = vm_mob_ref.CloneVM_Task(:folder => vm_mob_ref.parent, :name => options['name'], :spec => clone_spec)
# Waiting for the VM to complete allows us to get the VirtulMachine # Waiting for the VM to complete allows us to get the VirtulMachine
# object of the new machine when it's done. It is HIGHLY recommended # object of the new machine when it's done. It is HIGHLY recommended
# to set 'wait' => true if your app wants to wait. Otherwise, you're # to set 'wait' => true if your app wants to wait. Otherwise, you're
@ -126,7 +161,7 @@ module Fog
end end
{ {
'vm_ref' => 'vm-123', 'vm_ref' => 'vm-123',
'task_ref' => 'task-1234' 'task_ref' => 'task-1234',
} }
end end

View file

@ -1,15 +1,27 @@
Shindo.tests("Fog::Compute[:vsphere] | vm_clone request", 'vsphere') do Shindo.tests("Fog::Compute[:vsphere] | vm_clone request", 'vsphere') do
# require 'guid' # require 'guid'
template = "/Datacenters/Solutions/vm/Jeff/Templates/centos56gm2"
compute = Fog::Compute[:vsphere] compute = Fog::Compute[:vsphere]
response = nil
response_linked = nil
tests("The return value should") do template = "/Datacenters/Solutions/vm/Jeff/Templates/centos56gm2"
response = compute.vm_clone('path' => template, 'name' => 'cloning_vm') tests("Standard Clone | The return value should") do
response = compute.vm_clone('path' => template, 'name' => 'cloning_vm', 'wait' => 1)
test("be a kind of Hash") { response.kind_of? Hash } test("be a kind of Hash") { response.kind_of? Hash }
%w{ vm_ref task_ref }.each do |key| %w{ vm_ref task_ref }.each do |key|
test("have a #{key} key") { response.has_key? key } test("have a #{key} key") { response.has_key? key }
end end
end end
template = "/Datacenters/Solutions/vm/Jeff/Templates/centos56gm2"
tests("Linked Clone | The return value should") do
response = compute.vm_clone('path' => template, 'name' => 'cloning_vm_linked', 'wait' => 1, 'linked_clone' => true)
test("be a kind of Hash") { response.kind_of? Hash }
%w{ vm_ref task_ref }.each do |key|
test("have a #{key} key") { response.has_key? key }
end
end
tests("When invalid input is presented") do tests("When invalid input is presented") do
raises(ArgumentError, 'it should raise ArgumentError') { compute.vm_clone(:foo => 1) } raises(ArgumentError, 'it should raise ArgumentError') { compute.vm_clone(:foo => 1) }
raises(Fog::Compute::Vsphere::NotFound, 'it should raise Fog::Compute::Vsphere::NotFound when the UUID is not a string') do raises(Fog::Compute::Vsphere::NotFound, 'it should raise Fog::Compute::Vsphere::NotFound when the UUID is not a string') do