From 100569bf52c9605d743deb505ecd65324e39b751 Mon Sep 17 00:00:00 2001 From: Lucy Fu Date: Mon, 4 Jun 2018 14:37:05 -0400 Subject: [PATCH] Support moving a VM to another folder during VM Migrate. https://bugzilla.redhat.com/show_bug.cgi?id=1090957 --- app/models/ems_folder.rb | 12 ++++++++++++ app/models/vm_migrate_task.rb | 17 ++++++++++++----- .../dialogs/miq_dialogs/vm_migrate_dialogs.yaml | 8 ++++++++ spec/models/ems_folder_spec.rb | 14 ++++++++++++++ spec/models/vm_migrate_task_spec.rb | 9 +++++++-- 5 files changed, 53 insertions(+), 7 deletions(-) diff --git a/app/models/ems_folder.rb b/app/models/ems_folder.rb index b0f7bcd53fc5..40a2be4960a8 100644 --- a/app/models/ems_folder.rb +++ b/app/models/ems_folder.rb @@ -150,6 +150,18 @@ def register_host(host) end end + def move_into_folder(vm) + raise _("Vm cannot be nil") if vm.nil? + vm_mor = vm.ems_ref_obj + log_header = "EmsFolder: [#{name}] Vm: id [#{vm.id}], name [#{vm.name}], ems_ref [#{vm_mor}]" + + with_provider_object do |vim_folder| + _log.info("#{log_header} Invoking moveIntoFolder...") + vim_folder.send(:moveIntoFolder, vm_mor) + _log.info("#{log_header} Invoking moveIntoFolder...Complete") + end + end + # Folder pathing methods # TODO: Store the full path directly in the folder objects for performance reasons diff --git a/app/models/vm_migrate_task.rb b/app/models/vm_migrate_task.rb index 247c93b41ad2..ff78494bf1f2 100644 --- a/app/models/vm_migrate_task.rb +++ b/app/models/vm_migrate_task.rb @@ -28,6 +28,8 @@ def self.get_description(req_obj) new_settings << "Host: #{host_name}" unless host_name.blank? respool_name = req_obj.get_option_last(:placement_rp_name) new_settings << "Resource Pool: #{respool_name}" unless respool_name.blank? + folder_name = req_obj.get_option_last(:placement_folder_name) + new_settings << "Folder: #{folder_name}" if folder_name.present? storage = req_obj.get_option_last(:placement_ds_name) new_settings << "Storage: #{storage}" unless storage.blank? "#{request_class::TASK_DESCRIPTION} for: #{name} - #{new_settings.join(", ")}" @@ -44,6 +46,9 @@ def do_request respool_id = get_option(:placement_rp_name) respool = ResourcePool.find_by(:id => respool_id) + folder_id = get_option(:placement_folder_name) + folder = EmsFolder.find_by(:id => folder_id) + datastore_id = get_option(:placement_ds_name) datastore = Storage.find_by(:id => datastore_id) @@ -57,7 +62,7 @@ def do_request :relocate elsif respool && host.nil? :relocate - else + elsif host :migrate end @@ -66,18 +71,20 @@ def do_request begin if vc_method == :migrate vm.migrate(host, respool) - else + elsif vc_method == :relocate vm.relocate(host, respool, datastore, nil, disk_transform) end + + folder.move_into_folder(vm) if folder.present? rescue => err - update_and_notify_parent(:state => 'finished', :status => 'error', :message => "Failed. Reason[#{err.message}]") + update_and_notify_parent(:state => 'finished', :status => 'Error', :message => "Failed. Reason[#{err.message}]") return end if AUTOMATE_DRIVES - update_and_notify_parent(:state => 'migrated', :message => "Finished #{request_class::TASK_DESCRIPTION}") + update_and_notify_parent(:state => 'migrated', :message => "Finished #{request_class::TASK_DESCRIPTION}", :status => 'Ok') else - update_and_notify_parent(:state => 'finished', :message => "#{request_class::TASK_DESCRIPTION} complete") + update_and_notify_parent(:state => 'finished', :message => "#{request_class::TASK_DESCRIPTION} complete", :status => 'Ok') end end end diff --git a/product/dialogs/miq_dialogs/vm_migrate_dialogs.yaml b/product/dialogs/miq_dialogs/vm_migrate_dialogs.yaml index 11af4e70b853..9dd6566d49b4 100644 --- a/product/dialogs/miq_dialogs/vm_migrate_dialogs.yaml +++ b/product/dialogs/miq_dialogs/vm_migrate_dialogs.yaml @@ -198,6 +198,14 @@ :required: false :display: :edit :data_type: :integer + :placement_folder_name: + :values_from: + :method: :allowed_folders + :auto_select_single: false + :description: Name + :required: false + :display: :edit + :data_type: :integer :display: :show :schedule: :description: Schedule diff --git a/spec/models/ems_folder_spec.rb b/spec/models/ems_folder_spec.rb index 7b5500518257..0b553dc53306 100644 --- a/spec/models/ems_folder_spec.rb +++ b/spec/models/ems_folder_spec.rb @@ -27,4 +27,18 @@ expect(@root.child_folder_paths).to eq(expected) end end + + describe "#move_into_folder" do + let(:folder) { FactoryGirl.create(:ems_folder) } + let(:vm) { FactoryGirl.create(:vm_vmware, :ems_ref_obj => "vm-1120") } + let(:provider_object) do + double("vm_vmware_provider_object", :destroy => nil).as_null_object + end + + it "calls provider's method" do + expect(folder).to receive(:with_provider_object).and_yield(provider_object) + expect(provider_object).to receive(:send).with(:moveIntoFolder, vm.ems_ref_obj) + folder.move_into_folder(vm) + end + end end diff --git a/spec/models/vm_migrate_task_spec.rb b/spec/models/vm_migrate_task_spec.rb index b2721888d8bb..e9c13a9c7054 100644 --- a/spec/models/vm_migrate_task_spec.rb +++ b/spec/models/vm_migrate_task_spec.rb @@ -1,7 +1,12 @@ describe VmMigrateTask do describe '.do_request' do let(:vm) { Vm.new } - before { subject.vm = vm } + before do + subject.vm = vm + host = FactoryGirl.create(:host, :name => "test") + options = {:placement_host_name => [host.id, host.name] } + subject.update_attributes(:options => options) + end it 'migrates the vm and updates the status' do expect(vm).to receive(:migrate) @@ -11,7 +16,7 @@ it 'catches migrate error and update the status' do expect(vm).to receive(:migrate).and_raise("Bad things happened") - expect(subject).to receive(:update_and_notify_parent).with(hash_including(:state => 'finished', :status => 'error', :message => 'Failed. Reason[Bad things happened]')) + expect(subject).to receive(:update_and_notify_parent).with(hash_including(:state => 'finished', :status => 'Error', :message => 'Failed. Reason[Bad things happened]')) subject.do_request end end