Merge pull request #229 from glennsarti/fix-phantom-vms

(maint) Remove phantom VMs that are in Redis but don't exist in provider
This commit is contained in:
mattkirby 2017-08-01 10:38:25 -07:00 committed by GitHub
commit d789dfdfc8
2 changed files with 79 additions and 4 deletions

View file

@ -596,6 +596,7 @@ module Vmpooler
end end
rescue => err rescue => err
$logger.log('s', "[!] [#{pool['name']}] _check_pool failed with an error while inspecting inventory: #{err}") $logger.log('s', "[!] [#{pool['name']}] _check_pool failed with an error while inspecting inventory: #{err}")
return pool_check_response
end end
# RUNNING # RUNNING
@ -608,6 +609,8 @@ module Vmpooler
rescue => err rescue => err
$logger.log('d', "[!] [#{pool['name']}] _check_pool with an error while evaluating running VMs: #{err}") $logger.log('d', "[!] [#{pool['name']}] _check_pool with an error while evaluating running VMs: #{err}")
end end
else
move_vm_queue(pool['name'], vm, 'running', 'completed', 'is a running VM but is missing from inventory. Marking as completed.')
end end
end end
@ -620,6 +623,8 @@ module Vmpooler
rescue => err rescue => err
$logger.log('d', "[!] [#{pool['name']}] _check_pool failed with an error while evaluating ready VMs: #{err}") $logger.log('d', "[!] [#{pool['name']}] _check_pool failed with an error while evaluating ready VMs: #{err}")
end end
else
move_vm_queue(pool['name'], vm, 'ready', 'completed', 'is a ready VM but is missing from inventory. Marking as completed.')
end end
end end

View file

@ -2347,12 +2347,13 @@ EOT
task_limit: 10 task_limit: 10
:pools: :pools:
- name: #{pool} - name: #{pool}
size: 0 size: 10
EOT EOT
) )
} }
let(:pool_object) { config[:pools][0] } let(:pool_object) { config[:pools][0] }
let(:new_vm) { 'newvm'} let(:new_vm) { 'newvm'}
let(:pool_name) { pool_object['name'] }
before do before do
expect(subject).not_to be_nil expect(subject).not_to be_nil
@ -2378,6 +2379,46 @@ EOT
subject._check_pool(pool_object,provider) subject._check_pool(pool_object,provider)
end end
it 'should not perform any other actions if an error occurs' do
# Add VMs into redis
create_running_vm(pool_name, 'vm1')
create_ready_vm(pool_name, 'vm2')
create_completed_vm('vm3', pool_name)
create_discovered_vm('vm4', pool_name)
create_migrating_vm('vm5', pool_name)
expect(subject).to receive(:move_vm_queue).exactly(0).times
expect(subject).to receive(:check_running_vm).exactly(0).times
expect(subject).to receive(:check_pending_vm).exactly(0).times
expect(subject).to receive(:destroy_vm).exactly(0).times
expect(redis).to receive(:srem).exactly(0).times
expect(redis).to receive(:del).exactly(0).times
expect(redis).to receive(:hdel).exactly(0).times
expect(redis).to receive(:smove).exactly(0).times
expect(subject).to receive(:migrate_vm).exactly(0).times
expect(redis).to receive(:set).exactly(0).times
expect(redis).to receive(:incr).exactly(0).times
expect(subject).to receive(:clone_vm).exactly(0).times
expect(redis).to receive(:decr).exactly(0).times
expect(provider).to receive(:vms_in_pool).and_raise(RuntimeError,'Mock Error')
subject._check_pool(pool_object,provider)
end
it 'should return that no actions were taken' do
expect(provider).to receive(:vms_in_pool).and_raise(RuntimeError,'Mock Error')
result = subject._check_pool(pool_object,provider)
expect(result[:discovered_vms]).to be(0)
expect(result[:checked_running_vms]).to be(0)
expect(result[:checked_ready_vms]).to be(0)
expect(result[:checked_pending_vms]).to be(0)
expect(result[:destroyed_vms]).to be(0)
expect(result[:migrated_vms]).to be(0)
expect(result[:cloned_vms]).to be(0)
end
it 'should log the discovery of VMs' do it 'should log the discovery of VMs' do
expect(logger).to receive(:log).with('s', "[?] [#{pool}] '#{new_vm}' added to 'discovered' queue") expect(logger).to receive(:log).with('s', "[?] [#{pool}] '#{new_vm}' added to 'discovered' queue")
@ -2428,11 +2469,17 @@ EOT
create_running_vm(pool,vm,token) create_running_vm(pool,vm,token)
end end
it 'should not do anything' do it 'should not call check_running_vm' do
expect(subject).to receive(:check_running_vm).exactly(0).times expect(subject).to receive(:check_running_vm).exactly(0).times
subject._check_pool(pool_object,provider) subject._check_pool(pool_object,provider)
end end
it 'should move the VM to completed queue' do
expect(subject).to receive(:move_vm_queue).with(pool,vm,'running','completed',String).and_call_original
subject._check_pool(pool_object,provider)
end
end end
context 'Running VM in the inventory' do context 'Running VM in the inventory' do
@ -2487,11 +2534,17 @@ EOT
create_ready_vm(pool,vm,token) create_ready_vm(pool,vm,token)
end end
it 'should not do anything' do it 'should not call check_ready_vm' do
expect(subject).to receive(:check_ready_vm).exactly(0).times expect(subject).to receive(:check_ready_vm).exactly(0).times
subject._check_pool(pool_object,provider) subject._check_pool(pool_object,provider)
end end
it 'should move the VM to completed queue' do
expect(subject).to receive(:move_vm_queue).with(pool,vm,'ready','completed',String).and_call_original
subject._check_pool(pool_object,provider)
end
end end
context 'Ready VM in the inventory' do context 'Ready VM in the inventory' do
@ -2770,6 +2823,17 @@ EOT
# REPOPULATE # REPOPULATE
context 'Repopulate a pool' do context 'Repopulate a pool' do
let(:config) {
YAML.load(<<-EOT
---
:config:
task_limit: 10
:pools:
- name: #{pool}
size: 0
EOT
)
}
it 'should not call clone_vm when number of VMs is equal to the pool size' do it 'should not call clone_vm when number of VMs is equal to the pool size' do
expect(provider).to receive(:vms_in_pool).with(pool).and_return([]) expect(provider).to receive(:vms_in_pool).with(pool).and_return([])
expect(subject).to receive(:clone_vm).exactly(0).times expect(subject).to receive(:clone_vm).exactly(0).times
@ -2817,18 +2881,24 @@ EOT
end end
context 'when pool is marked as empty' do context 'when pool is marked as empty' do
let(:vm_response) {
# Mock response from Base Provider for vms_in_pool
[{ 'name' => vm}]
}
before(:each) do before(:each) do
expect(provider).to receive(:vms_in_pool).with(pool).and_return([])
redis.set("vmpooler__empty__#{pool}", 'true') redis.set("vmpooler__empty__#{pool}", 'true')
end end
it 'should not log a message when the pool remains empty' do it 'should not log a message when the pool remains empty' do
expect(provider).to receive(:vms_in_pool).with(pool).and_return([])
expect(logger).to receive(:log).with('s', "[!] [#{pool}] is empty").exactly(0).times expect(logger).to receive(:log).with('s', "[!] [#{pool}] is empty").exactly(0).times
subject._check_pool(pool_object,provider) subject._check_pool(pool_object,provider)
end end
it 'should remove the empty pool mark if it is no longer empty' do it 'should remove the empty pool mark if it is no longer empty' do
expect(provider).to receive(:vms_in_pool).with(pool).and_return(vm_response)
create_ready_vm(pool,vm,token) create_ready_vm(pool,vm,token)
expect(redis.get("vmpooler__empty__#{pool}")).to be_truthy expect(redis.get("vmpooler__empty__#{pool}")).to be_truthy