(DIO-2675) Undo pool size template overrides

This implements a delete method for pooltemplate and poolsize. The API
removes the override from Redis and then adds an entry in Redis that
causes the pool manager to wake up and process the removal of the
override.

To facilitate this, a new variable has been created in lib/vmpooler.rb
to hold a copy of the original / pre-override config. This supplemental
copy of the pools is then indexed for use as a reference.

When pool manager wakes up to process an override removal, it looks up
the pre-override value from the config via the new variables mentioned
above.

Just as with entering overrides, no restart is needed. Template and pool
size changes are logged so that anyone watching or reviewing the logs
can see what happened when. The new API endpoints also return values for
both the pre-revert and post-revert value.
This commit is contained in:
Gene Liverman 2021-10-14 15:08:55 -04:00
parent 6db71d8589
commit a0caa41a54
No known key found for this signature in database
GPG key ID: 3AF83985B6C857C6
7 changed files with 409 additions and 6 deletions

View file

@ -3159,6 +3159,54 @@ EOT
end
end
describe 'with the undo_override wakeup option' do
let(:wakeup_option) {{
:undo_override => true,
:poolname => pool
}}
let(:wakeup_period) { -1 } # A negative number forces the wakeup evaluation to always occur
context 'when a undoing a template override is requested' do
before(:each) do
redis_connection_pool.with do |redis|
redis.sadd('vmpooler__pool__undo_template_override', pool)
allow(redis).to receive(:hget)
end
end
it 'should sleep until the undo override request is detected' do
redis_connection_pool.with do |redis|
expect(subject).to receive(:sleep).at_least(2).times
expect(subject).to receive(:sleep).at_most(3).times
expect(redis).to receive(:sismember).with('vmpooler__pool__undo_template_override', pool).and_return(false,false,true)
expect(redis).to receive(:sismember).with('vmpooler__pool__undo_size_override', pool).and_return(false,false)
end
subject.sleep_with_wakeup_events(loop_delay, wakeup_period, wakeup_option)
end
end
context 'when a undoing a size override is requested' do
before(:each) do
redis_connection_pool.with do |redis|
redis.sadd('vmpooler__pool__undo_size_override', pool)
allow(redis).to receive(:hget)
end
end
it 'should sleep until the undo override request is detected' do
redis_connection_pool.with do |redis|
expect(subject).to receive(:sleep).exactly(3).times
expect(redis).to receive(:sismember).with('vmpooler__pool__undo_template_override', pool).and_return(false,false,false)
expect(redis).to receive(:sismember).with('vmpooler__pool__undo_size_override', pool).and_return(false,false,true)
end
subject.sleep_with_wakeup_events(loop_delay, wakeup_period, wakeup_option)
end
end
end
describe 'with the pending_vm wakeup option' do
let(:wakeup_option) {{
:pending_vm => true,
@ -3477,6 +3525,54 @@ EOT
end
end
describe 'undo_override' do
let(:mutex) { Mutex.new }
let(:original_template) { 'templates/template1' }
let(:override_template) { 'templates/template2' }
let(:original_size) { 2 }
let(:override_size) { 10 }
let(:config) { YAML.load(<<-EOT
---
:config:
task_limit: 5
:providers:
:mock:
:pools:
- name: '#{pool}'
size: #{override_size}
template: '#{override_template}'
:pool_index:
'#{pool}': 0
:pools_at_startup:
- name: '#{pool}'
size: #{original_size}
template: '#{original_template}'
EOT
)
}
before(:each) do
redis_connection_pool.with do |redis|
redis.sadd('vmpooler__pool__undo_template_override', pool)
redis.sadd('vmpooler__pool__undo_size_override', pool)
# allow(redis).to receive(:hget)
end
end
it 'should revert to the original template and pool size' do
redis_connection_pool.with do |redis|
expect(redis).to receive(:sismember).with('vmpooler__pool__undo_template_override', pool).and_return(true)
expect(redis).to receive(:srem).with('vmpooler__pool__undo_template_override', pool).and_return(true)
expect(subject).to receive(:update_pool_template).with(config[:pools][0], provider, original_template, override_template, redis)
expect(redis).to receive(:sismember).with('vmpooler__pool__undo_size_override', pool).and_return(true)
expect(redis).to receive(:srem).with('vmpooler__pool__undo_size_override', pool).and_return(true)
end
subject.undo_override(config[:pools][0], provider)
end
end
describe '#create_inventory' do
it 'should log an error if one occurs' do

View file

@ -20,6 +20,21 @@ describe 'Vmpooler' do
expect(Vmpooler.config[:pools]).to eq(default_config[:pools])
end
end
it 'keeps a copy of the original pools at startup' do
Dir.chdir(fixtures_dir) do
configuration = Vmpooler.config
expect(configuration[:pools]).to eq(configuration[:pools_at_startup])
end
end
it 'the copy is a separate object and not a reference' do
Dir.chdir(fixtures_dir) do
configuration = Vmpooler.config
configuration[:pools][0]['template'] = 'sam'
expect(configuration[:pools]).not_to eq(configuration[:pools_at_startup])
end
end
end
context 'when config variable is set' do