From 6ec2e3f6d3aa6c96bcf08b60c5208de9ccdb99b5 Mon Sep 17 00:00:00 2001 From: Lucy Fu Date: Tue, 19 Jun 2018 13:07:57 -0400 Subject: [PATCH] Support moving a VM to another folder during VM Migrate. https://bugzilla.redhat.com/show_bug.cgi?id=1090957 --- app/models/vm_migrate_task.rb | 22 ++++++++++++------- .../vm_or_template/operations/relocation.rb | 15 +++++++++++++ .../miq_dialogs/vm_migrate_dialogs.yaml | 8 +++++++ spec/models/vm_migrate_task_spec.rb | 8 +++++-- 4 files changed, 43 insertions(+), 10 deletions(-) diff --git a/app/models/vm_migrate_task.rb b/app/models/vm_migrate_task.rb index 247c93b41ad..f61fc5f1810 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,27 +62,28 @@ def do_request :relocate elsif respool && host.nil? :relocate - else + elsif host :migrate end _log.warn("Calling VM #{vc_method} for #{vm.id}:#{vm.name}") begin - if vc_method == :migrate - vm.migrate(host, respool) - else - vm.relocate(host, respool, datastore, nil, disk_transform) + case vc_method + when :migrate then vm.migrate(host, respool) + when :relocate then vm.relocate(host, respool, datastore, nil, disk_transform) end + + vm.move_into_folder(folder) 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/app/models/vm_or_template/operations/relocation.rb b/app/models/vm_or_template/operations/relocation.rb index ae7b1d00c85..0fd0247ab1e 100644 --- a/app/models/vm_or_template/operations/relocation.rb +++ b/app/models/vm_or_template/operations/relocation.rb @@ -95,6 +95,21 @@ def relocate(host, pool = nil, datastore = nil, disk_move_type = nil, transform raw_relocate(host, pool, datastore, disk_move_type, transform, priority, disk) end + def raw_move_into_folder(folder) + raise _("VM has no EMS, unable to move VM into a new folder") unless ext_management_system + raise _("Folder not specified, unable to move VM into a new folder") unless folder.kind_of?(EmsFolder) + + if parent_blue_folder == folder + raise _("The VM '%{name}' is already running on the same folder as the destination.") % {:name => name} + end + + run_command_via_parent(:vm_move_into_folder, :folder => folder) + end + + def move_into_folder(folder) + raw_move_into_folder(folder) + end + def migrate_via_ids(host_id, pool_id = nil, priority = "defaultPriority", state = nil) host = Host.find_by(:id => host_id) raise _("Host with ID=%{host_id} was not found") % {:host_id => host_id} if host.nil? diff --git a/product/dialogs/miq_dialogs/vm_migrate_dialogs.yaml b/product/dialogs/miq_dialogs/vm_migrate_dialogs.yaml index 11af4e70b85..9dd6566d49b 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/vm_migrate_task_spec.rb b/spec/models/vm_migrate_task_spec.rb index b2721888d8b..1a947d4544d 100644 --- a/spec/models/vm_migrate_task_spec.rb +++ b/spec/models/vm_migrate_task_spec.rb @@ -1,7 +1,11 @@ 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") + subject.update_attributes(:options => {:placement_host_name => [host.id, host.name]}) + end it 'migrates the vm and updates the status' do expect(vm).to receive(:migrate) @@ -11,7 +15,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