Add a configurable maximum per pool request upper limit

This commit is contained in:
kirby@puppetlabs.com 2020-05-11 13:13:03 -07:00
parent 9ea80f2a10
commit 0e798c391d
5 changed files with 108 additions and 66 deletions

View file

@ -60,10 +60,11 @@ module Vmpooler
# Set some configuration defaults
parsed_config[:config]['task_limit'] = string_to_int(ENV['TASK_LIMIT']) || parsed_config[:config]['task_limit'] || 10
parsed_config[:config]['ondemand_clone_limit'] = string_to_int(ENV['ONDEMAND_CLONE_LIMIT']) || parsed_config[:config]['ondemand_clone_limit'] || 10
parsed_config[:config]['max_ondemand_instances_per_request'] = string_to_int(ENV['MAX_ONDEMAND_INSTANCES_PER_REQUEST']) || parsed_config[:config]['max_ondemand_instances_per_request'] || 10
parsed_config[:config]['migration_limit'] = string_to_int(ENV['MIGRATION_LIMIT']) if ENV['MIGRATION_LIMIT']
parsed_config[:config]['vm_checktime'] = string_to_int(ENV['VM_CHECKTIME']) || parsed_config[:config]['vm_checktime'] || 1
parsed_config[:config]['vm_lifetime'] = string_to_int(ENV['VM_LIFETIME']) || parsed_config[:config]['vm_lifetime'] || 24
parsed_config[:config]['max_lifetime_upper_limit'] = string_to_int(ENV['MAX_LIFETIME_UPPER_LIMIT']) || string_to_int(parsed_config[:config]['max_lifetime_upper_limit'])
parsed_config[:config]['max_lifetime_upper_limit'] = string_to_int(ENV['MAX_LIFETIME_UPPER_LIMIT']) || parsed_config[:config]['max_lifetime_upper_limit']
parsed_config[:config]['ready_ttl'] = string_to_int(ENV['READY_TTL']) || parsed_config[:config]['ready_ttl'] || 5
parsed_config[:config]['ondemand_request_ttl'] = string_to_int(ENV['ONDEMAND_REQUEST_TTL']) || parsed_config[:config]['ondemand_request_ttl'] || 5
parsed_config[:config]['prefix'] = ENV['PREFIX'] || parsed_config[:config]['prefix'] || ''

View file

@ -307,11 +307,9 @@ module Vmpooler
pool_index = pool_index(pools)
template_configs = backend.hgetall('vmpooler__config__template')
template_configs&.each do |poolname, template|
if pool_index.include? poolname
unless pools[pool_index[poolname]]['template'] == template
pools[pool_index[poolname]]['template'] = template
end
end
next unless pool_index.include? poolname
pools[pool_index[poolname]]['template'] = template unless pools[pool_index[poolname]]['template'] == template
end
end
@ -319,11 +317,9 @@ module Vmpooler
pool_index = pool_index(pools)
poolsize_configs = backend.hgetall('vmpooler__config__poolsize')
poolsize_configs&.each do |poolname, size|
if pool_index.include? poolname
unless pools[pool_index[poolname]]['size'] == size.to_i
pools[pool_index[poolname]]['size'] == size.to_i
end
end
next unless pool_index.include? poolname
pools[pool_index[poolname]]['size'] == size.to_i unless pools[pool_index[poolname]]['size'] == size.to_i
end
end
@ -331,21 +327,33 @@ module Vmpooler
pool_index = pool_index(pools)
clone_target_configs = backend.hgetall('vmpooler__config__clone_target')
clone_target_configs&.each do |poolname, clone_target|
if pool_index.include? poolname
unless pools[pool_index[poolname]]['clone_target'] == clone_target
pools[pool_index[poolname]]['clone_target'] == clone_target
end
end
next unless pool_index.include? poolname
pools[pool_index[poolname]]['clone_target'] == clone_target unless pools[pool_index[poolname]]['clone_target'] == clone_target
end
end
def too_many_requested?(payload)
payload&.each do |_poolname, count|
next unless count.to_i > config['max_ondemand_instances_per_request']
return true
end
false
end
def generate_ondemand_request(payload)
result = { 'ok': false }
if too_many_requested?(payload.reject { |k, _v| k == 'request_id' })
result['message'] = "requested amount of instances exceeds the maximum #{config['max_ondemand_instances_per_request']}"
status 403
return result
end
score = Time.now.to_i
request_id = payload['request_id']
request_id ||= generate_request_id
score = Time.now.to_i
result['request_id'] = request_id
if backend.exists("vmpooler__odrequest__#{request_id}")

View file

@ -1487,6 +1487,8 @@ module Vmpooler
end
def check_ondemand_requests_ready(redis)
# default expiration is one month to ensure the data does not stay in redis forever
default_expiration = 259_200_0
in_progress_requests = redis.zrange('vmpooler__provisioning__processing', 0, -1, with_scores: true)
in_progress_requests&.each do |request_id, score|
next if request_expired?(request_id, score, redis)
@ -1494,6 +1496,7 @@ module Vmpooler
redis.multi
redis.hset("vmpooler__odrequest__#{request_id}", 'status', 'ready')
redis.expire("vmpooler__odrequest__#{request_id}", default_expiration)
redis.zrem('vmpooler__provisioning__processing', request_id)
redis.exec
end