From 63bb3b8dbe1ba9713f983f6292adeef3f65f1e12 Mon Sep 17 00:00:00 2001 From: "kirby@puppetlabs.com" Date: Fri, 14 Oct 2016 12:55:36 -0700 Subject: [PATCH] Add support for migrating VMs to pool_manager. This commit adds a capability to pool_manager to migrate VMs placed in the migrating queue. When a VM is checked out an entry is created in vmpooler__migrating. The existing process for evaluating VM states executes the migrate_vm method for the provided VM, and removes it from the queue. The least used compatible host for the provided VM is selected and, if necessary, a migration to the lesser used host is performed. Migration time and time from the task being queued until completion are both tracked with the redis VM object in 'migration_time' and 'checkout_to_migration'. The migration time is logged in the vmpooler.log, or the VM is reported as not requiring migration. Without this change VMs are not evaluated for checkout at request time. --- lib/vmpooler/pool_manager.rb | 39 +++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/lib/vmpooler/pool_manager.rb b/lib/vmpooler/pool_manager.rb index 53895bb4a..88a9e867e 100644 --- a/lib/vmpooler/pool_manager.rb +++ b/lib/vmpooler/pool_manager.rb @@ -455,6 +455,31 @@ def _check_snapshot_queue end end + def migrate_vm(vm, pool) + Thread.new do + _migrate_vm(vm, pool) + end + end + + def _migrate_vm(vm, pool) + $redis.srem('vmpooler__migrating__' + pool, vm) + vm_object = $vsphere[pool].find_vm(vm) || $vsphere[pool].find_vm_heavy(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 + "'") + else + start = Time.now + $vsphere[pool].migrate_vm_host(vm_object, host) + finish = '%.2f' % (Time.now - start) + 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 + end + def check_pool(pool) $logger.log('d', "[*] [#{pool['name']}] starting worker thread") @@ -480,7 +505,8 @@ def _check_pool(pool) (! $redis.sismember('vmpooler__ready__' + pool['name'], vm['name'])) && (! $redis.sismember('vmpooler__pending__' + pool['name'], vm['name'])) && (! $redis.sismember('vmpooler__completed__' + pool['name'], vm['name'])) && - (! $redis.sismember('vmpooler__discovered__' + pool['name'], vm['name'])) + (! $redis.sismember('vmpooler__discovered__' + pool['name'], vm['name'])) && + (! $redis.sismember('vmpooler__migrating__' + pool['name'], vm['name'])) $redis.sadd('vmpooler__discovered__' + pool['name'], vm['name']) @@ -555,6 +581,17 @@ def _check_pool(pool) end end + # MIGRATIONS + $redis.smembers('vmpooler__migrating__' + pool['name']).each do |vm| + if inventory[vm] + begin + migrate_vm(vm, pool['name']) + rescue + $logger.log('s', '[x] [' + pool['name'] + "] '" + vm + "' failed to migrate") + end + end + end + # REPOPULATE ready = $redis.scard('vmpooler__ready__' + pool['name']) total = $redis.scard('vmpooler__pending__' + pool['name']) + ready