diff --git a/lib/vmpooler/pool_manager.rb b/lib/vmpooler/pool_manager.rb index f4562ac7b..a6e83d5fa 100644 --- a/lib/vmpooler/pool_manager.rb +++ b/lib/vmpooler/pool_manager.rb @@ -468,20 +468,36 @@ def migrate_vm(vm, pool) def _migrate_vm(vm, pool) $redis.srem('vmpooler__migrating__' + pool, vm) vm_object = find_vsphere_pool_vm(pool, vm) - host = $vsphere[pool].find_least_used_compatible_host(vm_object) parent_host = vm_object.summary.runtime.host parent_host_name = parent_host.name - if host == parent_host - $logger.log('s', "[ ] [#{pool}] No migration required for '#{vm}'") + # Check if migration_limit is set + migration_limit = $config[:config]['migration_limit'] + # Ensure migration is disabled when migration_limit is set to 0 + migration_limit = nil unless migration_limit != 0 + + if not migration_limit + $logger.log('s', "[ ] [#{pool}] '#{vm}' is running on #{parent_host_name}") else - start = Time.now - $vsphere[pool].migrate_vm_host(vm_object, host) - finish = '%.2f' % (Time.now - start) - $metrics.timing("migrate.#{vm['template']}", finish) - checkout_to_migration = '%.2f' % (Time.now - Time.parse($redis.hget('vmpooler__vm__' + vm, 'checkout'))) - $redis.hset('vmpooler__vm__' + vm, 'migration_time', finish) - $redis.hset('vmpooler__vm__' + vm, 'checkout_to_migration', checkout_to_migration) - $logger.log('s', "[>] [#{pool}] '#{vm}' migrated from #{parent_host_name} to #{host.name} in #{finish} seconds") + migration_count = $redis.smembers('vmpooler__migration').size + if migration_count >= migration_limit + $logger.log('s', "[ ] [#{pool}] '#{vm}' is running on #{parent_host_name}. No migration will be evaluated since the migration_limit has been reached") + else + $redis.sadd('vmpooler__migration', vm) + host = $vsphere[pool].find_least_used_compatible_host(vm_object) + if host == parent_host + $logger.log('s', "[ ] [#{pool}] No migration required for '#{vm}'") + else + start = Time.now + $vsphere[pool].migrate_vm_host(vm_object, host) + finish = '%.2f' % (Time.now - start) + $metrics.timing("migrate.#{vm['template']}", finish) + checkout_to_migration = '%.2f' % (Time.now - Time.parse($redis.hget('vmpooler__vm__' + vm, 'checkout'))) + $redis.hset('vmpooler__vm__' + vm, 'migration_time', finish) + $redis.hset('vmpooler__vm__' + vm, 'checkout_to_migration', checkout_to_migration) + $logger.log('s', "[>] [#{pool}] '#{vm}' migrated from #{parent_host_name} to #{host.name} in #{finish} seconds") + end + $redis.srem('vmpooler__migration', vm) + end end end diff --git a/vmpooler.yaml.example b/vmpooler.yaml.example index 4e5489123..c83808c12 100644 --- a/vmpooler.yaml.example +++ b/vmpooler.yaml.example @@ -225,6 +225,13 @@ # If set, prefixes all created VMs with this string. This should include # a separator. # (optional; default: '') +# +# - migration_limit +# When set to any value greater than 0 enable VM migration at checkout. +# When enabled this capability will evaluate a VM for migration when it is requested +# in an effort to maintain a more even distribution of load across compute resources. +# The migration_limit ensures that no more than n migrations will be evaluated at any one time +# and greatly reduces the possibilty of VMs ending up bunched together on a particular host. # Example: