Skip to content

Commit

Permalink
Use OvirtSDK for the provisioning flow, this respects use_ovirt_engin…
Browse files Browse the repository at this point in the history
…e_sdk setting

and will not use OvirtSDK if it is off.

This was a common effort with big contribution from @pkliczewski
and help from @jhernand and @masayag
  • Loading branch information
Boris Odnopozov committed Apr 24, 2017
1 parent a914960 commit dee68de
Show file tree
Hide file tree
Showing 34 changed files with 919 additions and 268 deletions.
134 changes: 3 additions & 131 deletions app/models/manageiq/providers/redhat/infra_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,6 @@ class ManageIQ::Providers::Redhat::InfraManager < ManageIQ::Providers::InfraMana
supports :provisioning
supports :refresh_new_target

#
# Hot plug of virtual memory has to be done in quanta of this size. Actually this is configurable in the
# engine, using the `HotPlugMemoryMultiplicationSizeMb` configuration parameter, but it is very unlikely
# that it will change.
#
HOT_PLUG_DIMM_SIZE = 256.megabyte.freeze

def refresher
Refresh::RefresherBuilder.new(self).build
end
Expand Down Expand Up @@ -82,27 +75,9 @@ def self.provision_class(via)
end

def vm_reconfigure(vm, options = {})
log_header = "EMS: [#{name}] #{vm.class.name}: id [#{vm.id}], name [#{vm.name}], ems_ref [#{vm.ems_ref}]"
spec = options[:spec]

vm.with_provider_object do |rhevm_vm|
_log.info("#{log_header} Started...")
update_vm_memory(rhevm_vm, spec["memoryMB"] * 1.megabyte) if spec["memoryMB"]

cpu_options = {}
cpu_options[:cores] = spec["numCoresPerSocket"] if spec["numCoresPerSocket"]
cpu_options[:sockets] = spec["numCPUs"] / (cpu_options[:cores] || vm.cpu_cores_per_socket) if spec["numCPUs"]

rhevm_vm.cpu_topology = cpu_options if cpu_options.present?
end

# Removing disks
remove_disks(spec["disksRemove"], vm) if spec["disksRemove"]

# Adding disks
add_disks(spec["disksAdd"], vm) if spec["disksAdd"]

_log.info("#{log_header} Completed.")
ovirt_services_for_reconfigure = ManageIQ::Providers::Redhat::InfraManager::OvirtServices::Builder.new(self)
.build(:use_highest_supported_version => true).new(:ems => self)
ovirt_services_for_reconfigure.vm_reconfigure(vm, options)
end

def add_disks(add_disks_spec, vm)
Expand Down Expand Up @@ -147,30 +122,6 @@ def vm_add_disk(vm, options = {})
end
end

def update_vm_memory(vm, virtual)
# Adjust the virtual and guaranteed memory:
virtual = calculate_adjusted_virtual_memory(vm, virtual)
guaranteed = calculate_adjusted_guaranteed_memory(vm, virtual)

# If the virtual machine is running we need to update first the configuration that will be used during the
# next run, as the guaranteed memory can't be changed for the running virtual machine.
state = vm.attributes.fetch_path(:status, :state)
if state == 'up'
vm.update_memory(virtual, guaranteed, :next_run => true)
vm.update_memory(virtual, nil)
else
vm.update_memory(virtual, guaranteed)
end
end

def remove_disks(disks, vm)
with_disk_attachments_service(vm) do |service|
disks.each do |disk|
service.attachment_service(disk["disk_name"]).remove(:detach_only => !disk["delete_backing"])
end
end
end

def vm_migrate(vm, options = {})
host_id = URI(options[:host]).path.split('/').last

Expand All @@ -195,83 +146,4 @@ def unsupported_migration_options
def supports_migrate_for_all?(vms)
vms.map(&:ems_cluster).uniq.compact.size == 1
end

private

#
# Adjusts the new requested virtual memory of a virtual machine so that it satisfies the constraints imposed
# by the engine.
#
# @param vm [Hash] The current representation of the virtual machine.
#
# @param requested [Integer] The new amount of virtual memory requested by the user.
#
# @return [Integer] The amount of virtual memory requested by the user adjusted so that it satisfies the constrains
# imposed by the engine.
#
def calculate_adjusted_virtual_memory(vm, requested)
# Get the current state of the virtual machine, and the current amount of virtual memory:
attributes = vm.attributes
name = attributes.fetch_path(:name)
state = attributes.fetch_path(:status, :state)
current = attributes.fetch_path(:memory)

# Initially there is no need for adjustment:
adjusted = requested

# If the virtual machine is running then the difference in memory has to be a multiple of 256 MiB, otherwise
# the engine will not perform the hot plug of the new memory. The reason for this is that hot plugging of
# memory is performed adding a new virtual DIMM to the virtual machine, and the size of the virtual DIMM
# is 256 MiB. This means that we need to round the difference up to the closest multiple of 256 MiB.
if state == 'up'
delta = requested - current
remainder = delta % HOT_PLUG_DIMM_SIZE
if remainder > 0
adjustment = HOT_PLUG_DIMM_SIZE - remainder
adjusted = requested + adjustment
_log.info(
"The change in virtual memory of virtual machine '#{name}' needs to be a multiple of " \
"#{HOT_PLUG_DIMM_SIZE / 1.megabyte} MiB, so it will be adjusted to #{adjusted / 1.megabyte} MiB."
)
end
end

# Return the adjusted memory:
adjusted
end

#
# Adjusts the guaranteed memory of a virtual machie so that it satisfies the constraints imposed by the
# engine.
#
# @param vm [Hash] The current representation of the virtual machine.
#
# @param virtual [Integer] The new amount of virtual memory requested by the user (and maybe already adjusted).
#
# @return [Integer] The amount of guarantted memory to request so that it satisfies the constraints imposed by
# the engine.
#
def calculate_adjusted_guaranteed_memory(vm, virtual)
# Get the current amount of guaranteed memory:
attributes = vm.attributes
name = attributes.fetch_path(:name)
current = attributes.fetch_path(:memory_policy, :guaranteed)

# Initially there is no need for adjustment:
adjusted = current

# The engine requires that the virtual memory is bigger or equal than the guaranteed memory at any given
# time. Therefore, we need to adjust the guaranteed memory so that it is the minimum of the previous
# guaranteed memory and the new virtual memory.
if current > virtual
adjusted = virtual
_log.info(
"The guaranteed physical memory of virtual machine '#{name}' needs to be less or equal than the virtual " \
"memory, so it will be adjusted to #{adjusted / 1.megabyte} MiB."
)
end

# Return the adjusted guaranteed memory:
adjusted
end
end
5 changes: 3 additions & 2 deletions app/models/manageiq/providers/redhat/infra_manager/host.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
class ManageIQ::Providers::Redhat::InfraManager::Host < ::Host
def provider_object(connection = nil)
connection ||= ext_management_system.connect
connection.get_resource_by_ems_ref(ems_ref)
ovirt_services_class = ManageIQ::Providers::Redhat::InfraManager::OvirtServices::Builder
.build_from_ems_or_connection(:ems => ext_management_system, :connection => connection)
ovirt_services_class.new(:ems => ext_management_system).get_host_proxy(self, connection)
end

def verify_credentials(auth_type = nil, options = {})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module ManageIQ::Providers::Redhat::InfraManager::Inventory
require_nested :Inventory
require_nested :Builder
end
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ class V4
attr_accessor :connection
attr_reader :ems

VERSION_HASH = {:version => 4}.freeze

def initialize(args)
@ems = args[:ems]
end

def host_targeted_refresh(target)
ems.with_provider_connection(:version => 4) do |connection|
ems.with_provider_connection(VERSION_HASH) do |connection|
@connection = connection
res = {}
res[:host] = collect_host(get_uuid_from_target(target))
Expand All @@ -17,7 +19,7 @@ def host_targeted_refresh(target)
end

def vm_targeted_refresh(target)
ems.with_provider_connection(:version => 4) do |connection|
ems.with_provider_connection(VERSION_HASH) do |connection|
@connection = connection
vm_id = get_uuid_from_target(target)
res = {}
Expand All @@ -39,7 +41,7 @@ def get_uuid_from_target(object)
end

def refresh
ems.with_provider_connection(:version => 4) do |connection|
ems.with_provider_connection(VERSION_HASH) do |connection|
@connection = connection
res = {}
res[:cluster] = collect_clusters
Expand Down Expand Up @@ -87,6 +89,8 @@ def collect_vms
def collect_vm_by_uuid(uuid)
vm = connection.system_service.vms_service.vm_service(uuid).get
[VmPreloadedAttributesDecorator.new(vm, connection)]
rescue OvirtSDK4::Error
[]
end

def collect_templates
Expand All @@ -112,13 +116,13 @@ def collect_datacenters
end

def api
ems.with_provider_connection(:version => 4) do |connection|
ems.with_provider_connection(VERSION_HASH) do |connection|
connection.system_service.get.product_info.version.full_version
end
end

def service
ems.with_provider_connection(:version => 4) do |connection|
ems.with_provider_connection(VERSION_HASH) do |connection|
OpenStruct.new(:version_string => connection.system_service.get.product_info.version.full_version)
end
end
Expand All @@ -128,7 +132,7 @@ class HostPreloadedAttributesDecorator < SimpleDelegator
def initialize(host, connection)
@obj = host
@nics = connection.follow_link(host.nics)
@statistics = connection.follow_link(host.statistics)
@statistics = connection.link?(host.statistics) ? connection.follow_link(host.statistics) : host.statistics
super(host)
end
end
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module ManageIQ::Providers::Redhat::InfraManager::OvirtServices
require_nested :Builder
require_nested :OvirtServices
end
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,23 @@ def initialize(ems)
@ext_management_system = ems
end

def build
def build(args = {})
strategy_model = ManageIQ::Providers::Redhat::InfraManager::OvirtServices::Strategies
api_version = ext_management_system.highest_allowed_api_version
"#{strategy_model}::V#{api_version}".constantize
"#{strategy_model}::V#{api_version(args)}".constantize
end

def self.build_from_ems_or_connection(args)
ems = args[:ems]
connection = args[:connection]
connection_version = connection && connection.kind_of?(OvirtSDK4::Connection) ? 4 : 3
strategy_model = ManageIQ::Providers::Redhat::InfraManager::OvirtServices::Strategies
return "#{strategy_model}::V#{connection_version}".constantize if connection_version
new(ems).build if ems
end

def api_version(args)
return ext_management_system.highest_supported_api_version if args[:use_highest_supported_version]
ext_management_system.highest_allowed_api_version
end
end
end
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module ManageIQ::Providers::Redhat::InfraManager::Inventory
module ManageIQ::Providers::Redhat::InfraManager::OvirtServices
class Error < StandardError; end
class VmNotReadyToBoot < Error; end
end
Loading

0 comments on commit dee68de

Please sign in to comment.