From 1581e45e9ed2e321d9a732077a26a2561dbf8962 Mon Sep 17 00:00:00 2001 From: Tomas Jelinek Date: Fri, 23 Sep 2016 11:15:21 +0200 Subject: [PATCH 1/2] Add Migrate support to RHEV provider --- .../providers/redhat/infra_manager.rb | 18 ++++++++ .../redhat/infra_manager/api_integration.rb | 9 +++- .../providers/redhat/infra_manager/vm.rb | 2 - app/models/vm_migrate_workflow.rb | 11 +++++ .../_prov_vm_migrate_dialog.html.haml | 44 ++++++++++--------- spec/models/vm_migrate_workflow_spec.rb | 30 +++++++++++++ 6 files changed, 91 insertions(+), 23 deletions(-) diff --git a/app/models/manageiq/providers/redhat/infra_manager.rb b/app/models/manageiq/providers/redhat/infra_manager.rb index 108c69e673c..412c1a09be5 100644 --- a/app/models/manageiq/providers/redhat/infra_manager.rb +++ b/app/models/manageiq/providers/redhat/infra_manager.rb @@ -133,4 +133,22 @@ def remove_disks(disks, vm) disks.each { |disk_id| service.attachment_service(disk_id).remove } end end + + def vm_migrate(vm, options = {}) + host_id = URI(options[:host]).path.split('/').last + + migration_options = { + :host => { + :id => host_id + } + } + + with_version4_vm_service(vm) do |service| + service.migrate(migration_options) + end + end + + def unsupported_migration_options + [:storage, :respool, :folder, :datacenter, :host_filter] + end end diff --git a/app/models/manageiq/providers/redhat/infra_manager/api_integration.rb b/app/models/manageiq/providers/redhat/infra_manager/api_integration.rb index 496b966e34d..cbd11f9d499 100644 --- a/app/models/manageiq/providers/redhat/infra_manager/api_integration.rb +++ b/app/models/manageiq/providers/redhat/infra_manager/api_integration.rb @@ -198,8 +198,15 @@ def version_3_0? # Adding disks is supported only by API version 4.0 def with_disk_attachments_service(vm) + with_version4_vm_service(vm) do |service| + disk_service = service.disk_attachments_service + yield disk_service + end + end + + def with_version4_vm_service(vm) connection = connect(:version => 4) - service = connection.system_service.vms_service.vm_service(vm.uid_ems).disk_attachments_service + service = connection.system_service.vms_service.vm_service(vm.uid_ems) yield service ensure connection.close diff --git a/app/models/manageiq/providers/redhat/infra_manager/vm.rb b/app/models/manageiq/providers/redhat/infra_manager/vm.rb index eb3151809b6..2c2921dd192 100644 --- a/app/models/manageiq/providers/redhat/infra_manager/vm.rb +++ b/app/models/manageiq/providers/redhat/infra_manager/vm.rb @@ -4,8 +4,6 @@ class ManageIQ::Providers::Redhat::InfraManager::Vm < ManageIQ::Providers::Infra include_concern 'Reconfigure' include_concern 'ManageIQ::Providers::Redhat::InfraManager::VmOrTemplateShared' - supports_not :migrate, :reason => _("Migrate operation is not supported.") - POWER_STATES = { 'up' => 'on', 'down' => 'off', diff --git a/app/models/vm_migrate_workflow.rb b/app/models/vm_migrate_workflow.rb index 840c1254f34..5fd8532d238 100644 --- a/app/models/vm_migrate_workflow.rb +++ b/app/models/vm_migrate_workflow.rb @@ -22,6 +22,8 @@ def get_source_and_targets(refresh = false) return @target_resource = {} if ems.length != 1 result = {:ems => ci_to_hash_struct(ems.first)} + @manager = ems.first + add_target(:placement_host_name, :host, Host, result) add_target(:placement_ds_name, :storage, Storage, result) add_target(:placement_cluster_name, :cluster, EmsCluster, result) @@ -38,6 +40,15 @@ def get_source_and_targets(refresh = false) @target_resource = result end + def add_target(dialog_key, key, klass, result) + super if field_supported(key) + end + + def field_supported(key) + !(@manager.respond_to?(:unsupported_migration_options) && + @manager.unsupported_migration_options.include?(key)) + end + private def allowed_ci(ci, relats, filtered_ids = nil) diff --git a/app/views/miq_request/_prov_vm_migrate_dialog.html.haml b/app/views/miq_request/_prov_vm_migrate_dialog.html.haml index a1168538bcb..d01c0d1adac 100644 --- a/app/views/miq_request/_prov_vm_migrate_dialog.html.haml +++ b/app/views/miq_request/_prov_vm_migrate_dialog.html.haml @@ -21,12 +21,13 @@ :label => _("Manager"), :keys => keys}) - when :environment - - keys = [:placement_dc_name] - = render(:partial => "/miq_request/prov_dialog_fieldset", - :locals => {:workflow => wf, - :dialog => dialog, - :label => _("Datacenter"), - :keys => keys}) + - if wf.field_supported(:datacenter) + - keys = [:placement_dc_name] + = render(:partial => "/miq_request/prov_dialog_fieldset", + :locals => {:workflow => wf, + :dialog => dialog, + :label => _("Datacenter"), + :keys => keys}) - keys = [:cluster_filter, :placement_cluster_name] = render(:partial => "/miq_request/prov_dialog_fieldset", @@ -35,14 +36,15 @@ :label => title_for_cluster, :keys => keys}) - - keys = [:rp_filter, :placement_rp_name] - = render(:partial => "/miq_request/prov_dialog_fieldset", - :locals => {:workflow => wf, - :dialog => dialog, - :label => _("Resource Pool"), - :keys => keys}) + - if wf.field_supported(:respool) + - keys = [:rp_filter, :placement_rp_name] + = render(:partial => "/miq_request/prov_dialog_fieldset", + :locals => {:workflow => wf, + :dialog => dialog, + :label => _("Resource Pool"), + :keys => keys}) - - keys = [:host_filter, :placement_host_name] + - keys = [wf.field_supported(:host_filter) ? :host_filter : nil, :placement_host_name].compact = render(:partial => "/miq_request/prov_dialog_fieldset", :locals => {:workflow => wf, :dialog => dialog, @@ -50,13 +52,15 @@ :keys => keys, :extra_table_attributes => "width=100%"}) - - keys = [:ds_filter, :placement_ds_name] - = render(:partial => "/miq_request/prov_dialog_fieldset", - :locals => {:workflow => wf, - :dialog => dialog, - :label => _("Datastore"), - :keys => keys, - :extra_table_attributes => "width=100%"}) + - if wf.field_supported(:storage) + - keys = [:ds_filter, :placement_ds_name] + = render(:partial => "/miq_request/prov_dialog_fieldset", + :locals => {:workflow => wf, + :dialog => dialog, + :label => _("Datastore"), + :keys => keys, + :extra_table_attributes => "width=100%"}) + - when :hardware - keys = [:disk_format] = render(:partial => "/miq_request/prov_dialog_fieldset", diff --git a/spec/models/vm_migrate_workflow_spec.rb b/spec/models/vm_migrate_workflow_spec.rb index d0a738cb542..ab4c6e9bb31 100644 --- a/spec/models/vm_migrate_workflow_spec.rb +++ b/spec/models/vm_migrate_workflow_spec.rb @@ -4,6 +4,9 @@ let(:ems) { FactoryGirl.create(:ems_vmware) } let(:vm) { FactoryGirl.create(:vm_vmware, :name => 'My VM', :ext_management_system => ems) } + let(:redhat_ems) { FactoryGirl.create(:ems_redhat) } + let(:redhat_vm) { FactoryGirl.create(:vm_redhat, :name => 'My RHV VM', :ext_management_system => redhat_ems) } + context "With a Valid Template," do context "#allowed_hosts" do let(:workflow) { VmMigrateWorkflow.new({:src_ids => [vm.id]}, admin) } @@ -26,6 +29,33 @@ end end + describe "Configuring targets" do + context "redhat VM" do + let(:workflow) { VmMigrateWorkflow.new({:src_ids => [redhat_vm.id]}, admin) } + + it "excludes some properties in" do + stub_dialog + workflow.get_source_and_targets + target_resource = workflow.instance_variable_get(:@target_resource) + expect(target_resource).not_to include(:storage_id, :respool_id, :folder_id, + :datacenter_id) + expect(target_resource).to include(:host_id, :cluster_id) + end + end + + context "vmware VM" do + let(:workflow) { VmMigrateWorkflow.new({:src_ids => [vm.id]}, admin) } + + it "includes all properties in" do + stub_dialog + workflow.get_source_and_targets + target_resource = workflow.instance_variable_get(:@target_resource) + expect(target_resource).to include(:host_id, :cluster_id, :storage_id, :respool_id, + :folder_id, :datacenter_id) + end + end + end + describe "#make_request" do let(:alt_user) { FactoryGirl.create(:user_with_group) } From bc4c103ed7066c973ef6cb7dd84021e84597e54a Mon Sep 17 00:00:00 2001 From: Tomas Jelinek Date: Thu, 3 Nov 2016 05:17:03 -0400 Subject: [PATCH 2/2] Allow migrate only for api level 4 --- .../providers/redhat/infra_manager/api_integration.rb | 2 +- app/models/manageiq/providers/redhat/infra_manager/vm.rb | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/models/manageiq/providers/redhat/infra_manager/api_integration.rb b/app/models/manageiq/providers/redhat/infra_manager/api_integration.rb index cbd11f9d499..bca8ea27881 100644 --- a/app/models/manageiq/providers/redhat/infra_manager/api_integration.rb +++ b/app/models/manageiq/providers/redhat/infra_manager/api_integration.rb @@ -218,7 +218,7 @@ def api3_supported_features end def api4_supported_features - [:quick_stats, :snapshots] + [:quick_stats, :snapshots, :migrate] end def api_features diff --git a/app/models/manageiq/providers/redhat/infra_manager/vm.rb b/app/models/manageiq/providers/redhat/infra_manager/vm.rb index 2c2921dd192..aa6ca3f922a 100644 --- a/app/models/manageiq/providers/redhat/infra_manager/vm.rb +++ b/app/models/manageiq/providers/redhat/infra_manager/vm.rb @@ -4,6 +4,12 @@ class ManageIQ::Providers::Redhat::InfraManager::Vm < ManageIQ::Providers::Infra include_concern 'Reconfigure' include_concern 'ManageIQ::Providers::Redhat::InfraManager::VmOrTemplateShared' + supports :migrate do + unless ext_management_system.supports_migrate? + unsupported_reason_add(:migrate, 'RHV API version does not support migrate') + end + end + POWER_STATES = { 'up' => 'on', 'down' => 'off',