diff --git a/app/models/manageiq/providers/vmware/infra_manager/provision/cloning.rb b/app/models/manageiq/providers/vmware/infra_manager/provision/cloning.rb index 93b5425db..81b1e11ab 100644 --- a/app/models/manageiq/providers/vmware/infra_manager/provision/cloning.rb +++ b/app/models/manageiq/providers/vmware/infra_manager/provision/cloning.rb @@ -46,8 +46,7 @@ def prepare_for_clone_task :pool => dest_resource_pool, :storage_profile => dest_storage_profile, :config => build_config_spec, - :customization => build_customization_spec, - :transform => build_transform_spec + :customization => build_customization_spec } # Determine if we are doing a linked-clone provision @@ -120,7 +119,7 @@ def start_clone(clone_options) :template => self.create_template? } - [:transform, :config, :customization, :linked_clone].each { |key| vim_clone_options[key] = clone_options[key] } + [:config, :customization, :linked_clone].each { |key| vim_clone_options[key] = clone_options[key] } [:folder, :host, :pool, :snapshot].each do |key| ci = clone_options[key] @@ -129,6 +128,7 @@ def start_clone(clone_options) end vim_clone_options[:datastore] = datastore_ems_ref(clone_options) + vim_clone_options[:disk] = build_disk_relocate_spec(vim_clone_options[:datastore]) vim_clone_options[:storage_profile] = build_storage_profile(clone_options[:storage_profile]) unless clone_options[:storage_profile].nil? task_mor = clone_vm(vim_clone_options) @@ -192,13 +192,6 @@ def get_selected_snapshot ss end - def build_transform_spec - case get_option(:disk_format) - when 'thin' then VimString.new('sparse', "VirtualMachineRelocateTransformation") - when 'thick' then VimString.new('flat', "VirtualMachineRelocateTransformation") - end - end - def build_storage_profile(storage_profile) VimArray.new('ArrayOfVirtualMachineProfileSpec') do |vm_profile_spec_array| vm_profile_spec_array << VimHash.new('VirtualMachineDefinedProfileSpec') do |vm_profile_spec| diff --git a/app/models/manageiq/providers/vmware/infra_manager/provision/configuration/disk.rb b/app/models/manageiq/providers/vmware/infra_manager/provision/configuration/disk.rb index ef5114a16..392d8913d 100644 --- a/app/models/manageiq/providers/vmware/infra_manager/provision/configuration/disk.rb +++ b/app/models/manageiq/providers/vmware/infra_manager/provision/configuration/disk.rb @@ -21,13 +21,37 @@ def build_config_disk_spec(vmcs) end end - def get_scsi_controller_info - inventory_hash = source.with_provider_connection do |vim| - vim.virtualMachineByMor(source.ems_ref_obj) + def build_disk_relocate_spec(datastore) + VimArray.new('ArrayOfVirtualMachineRelocateSpecDiskLocator') do |relocate_spec_array| + disks.map do |disk| + relocate_spec_array << VimHash.new('VirtualMachineRelocateSpecDiskLocator') do |disk_locator| + disk_locator.diskId = disk.key + disk_locator.datastore = datastore + disk_locator.diskBackingInfo = VimHash.new("VirtualDiskFlatVer2BackingInfo") do |bck| + bck.fileName = datastore + bck.diskMode = "persistent" + case get_option(:disk_format) + when 'thin' + bck.thinProvisioned = "true" + when 'thick' + bck.thinProvisioned = "false" + bck.eagerlyScrub = "false" + when 'thick_eager' + bck.eagerlyScrub = "true" + bck.thinProvisioned = "false" + end + end + end + end end + end + + def disks + devices.select { |d| d.xsiType == "VirtualDisk" } + end - devs = inventory_hash.fetch_path("config", "hardware", "device") || [] - devs.each_with_object({}) do |dev, h| + def get_scsi_controller_info + devices.each_with_object({}) do |dev, h| next unless dev.fetch_path("deviceInfo", "label").to_s =~ /^SCSI\s[Cc]ontroller\s.*$/ h[dev['busNumber'].to_i] = dev end @@ -73,10 +97,21 @@ def add_disk(vmcs, disk, controller, new_dev_key) bck.diskMode = get_config_spec_value(disk, 'persistent', 'VirtualDiskMode', [:backing, :diskmode]) bck.split = get_config_spec_value(disk, 'false', nil, [:backing, :split]) bck.thinProvisioned = get_config_spec_value(disk, 'false', nil, [:backing, :thinprovisioned]) + bck.eagerlyScrub = get_config_spec_value(disk, 'false', nil, [:backing, :eagerlyscrub]) bck.writeThrough = get_config_spec_value(disk, 'false', nil, [:backing, :writethrough]) bck.fileName = backing_filename end end end end + + private + + def devices + inventory_hash = source.with_provider_connection do |vim| + vim.virtualMachineByMor(source.ems_ref_obj) + end + + @devices ||= inventory_hash.fetch_path("config", "hardware", "device") || [] + end end diff --git a/spec/models/manageiq/providers/vmware/infra_manager/provision_spec.rb b/spec/models/manageiq/providers/vmware/infra_manager/provision_spec.rb index 0803e6114..adc43ca0f 100644 --- a/spec/models/manageiq/providers/vmware/infra_manager/provision_spec.rb +++ b/spec/models/manageiq/providers/vmware/infra_manager/provision_spec.rb @@ -44,13 +44,34 @@ expect(spec["annotation"]).to include(@vm_prov.phase_context[:new_vm_validation_guid]) end - it "should return a transform spec" do - spec = @vm_prov.build_transform_spec - expect(spec).to be_nil - @vm_prov.options[:disk_format] = 'thin' - spec = @vm_prov.build_transform_spec - expect(spec).to be_kind_of(VimString) - expect(spec.vimType).to eq('VirtualMachineRelocateTransformation') + describe "disk_relocate_spec" do + let(:device_list) { [VimHash.new("VirtualDisk") { |d| d.key = "2000" }, VimHash.new("NotAVirtualDisk") { |d| d.key = "2001" }] } + + it "thin" do + expect(@vm_prov).to receive(:disks).and_return(device_list) + @vm_prov.options[:disk_format] = 'thin' + spec = @vm_prov.build_disk_relocate_spec('datastore-1729') + expect(spec).to be_kind_of(VimArray) + expect(spec.first.diskBackingInfo.thinProvisioned).to eq("true") + end + + it "thick lazy zero" do + expect(@vm_prov).to receive(:disks).and_return(device_list) + @vm_prov.options[:disk_format] = 'thick' + spec = @vm_prov.build_disk_relocate_spec('datastore-1729') + expect(spec).to be_kind_of(VimArray) + expect(spec.first.diskBackingInfo.eagerlyScrub).to eq("false") + expect(spec.first.diskBackingInfo.thinProvisioned).to eq("false") + end + + it "thick eager zero" do + expect(@vm_prov).to receive(:disks).and_return(device_list) + @vm_prov.options[:disk_format] = 'thick_eager' + spec = @vm_prov.build_disk_relocate_spec('datastore-1729') + expect(spec).to be_kind_of(VimArray) + expect(spec.first.diskBackingInfo.thinProvisioned).to eq("false") + expect(spec.first.diskBackingInfo.eagerlyScrub).to eq("true") + end end it "should detect when a reconfigure_hardware_on_destination call is required" do @@ -310,14 +331,15 @@ :name => @target_vm_name, :wait => false, :template => false, - :transform => nil, :config => nil, :customization => nil, :linked_clone => nil, :host => dest_host_mor, - :datastore => dest_datastore_mor + :datastore => dest_datastore_mor, + :disk => [] } + expect(@vm_prov).to receive(:disks).and_return([]) allow(@vm_prov).to receive(:clone_vm).with(expected_vim_clone_opts).and_return(task_mor) result = @vm_prov.start_clone clone_opts @@ -339,13 +361,14 @@ :name => @target_vm_name, :wait => false, :template => false, - :transform => nil, :config => nil, :customization => nil, :linked_clone => nil, - :datastore => dest_datastore_mor + :datastore => dest_datastore_mor, + :disk => [] } + expect(@vm_prov).to receive(:disks).and_return([]) allow(@vm_prov).to receive(:clone_vm).with(expected_vim_clone_opts).and_return(task_mor) result = @vm_prov.start_clone clone_opts