(POOLER-158) Getting started with provisioning on demand

This commit is contained in:
kirby@puppetlabs.com 2020-04-06 10:52:05 -07:00
parent e9a79cb6db
commit 63712741a0
3 changed files with 145 additions and 2 deletions

View file

@ -8,9 +8,9 @@
# RUN:
# docker run -e VMPOOLER_CONFIG -p 80:4567 -it vmpooler
FROM jruby:9.2.9-jdk
FROM jruby:9.2-jdk
ARG vmpooler_version=0.5.0
ARG vmpooler_version=0.11.1
COPY docker/docker-entrypoint.sh /usr/local/bin/

View file

@ -277,6 +277,35 @@ module Vmpooler
end
end
def generate_ondemand_request(payload)
result = { 'ok': false }
request_id = payload[:request_id]
request_id = generate_request_id if request_id.nil?
score = Time.now.to_i
result['request_id'] = request_id
if backend.exists("vmpooler__odrequest__#{request_id}")
result['message'] = "request_id '#{request_id}' has already been created"
return result
end
return result unless backend.zadd('vmpooler__provisioning__request', score, request_id)
status 201
requested = payload[:requested].map { |poolname, count| "#{poolname}:#{count}" }.join(',')
backend.hset("vmpooler__odrequest__#{request_id}", 'requested', requested)
result['ok'] = true
result
end
def generate_request_id
SecureRandom.uuid
end
get '/' do
sync_pool_sizes
redirect to('/dashboard/')
@ -689,6 +718,41 @@ module Vmpooler
JSON.pretty_generate(result)
end
post "#{api_prefix}/ondemandrequest/?" do
content_type :json
result = { 'ok' => false }
payload = JSON.parse(request.body.read)
if payload
invalid = invalid_templates(payload)
if invalid.empty?
result = generate_ondemand_request(payload)
else
invalid.each do |bad_template|
metrics.increment('ondemandrequest.invalid.' + bad_template)
end
status 404
end
else
metrics.increment('ondemandrequest.invalid.unknown')
status 404
end
JSON.pretty_generate(result)
end
get "#{api_prefix}/ondemandrequest/:requestid/?" do
content_type :json
result = {'ok': false}
status 404
result = check_ondemand_request(payload)
JSON.pretty_generate(result)
end
post "#{api_prefix}/vm/?" do
content_type :json
result = { 'ok' => false }
@ -764,6 +828,29 @@ module Vmpooler
invalid
end
def check_ondemand_request(payload)
result = {'ok': false}
request_id = payload[:request_id]
request_hash = backend.hgetall("vmpooler__odrequest__#{request_id}")
if request_hash.empty?
result['message'] = "no request found for request_id '#{request_id}'"
return result
end
if request_hash['status'] == 'ready'
result['status'] = 'ready'
instances = {}
platforms = request_hash['requested'].split(',').map( { |r| r.split(':')[0] } )
platforms.each do |platform|
instances[platform] = request_hash[platform].split(':')
end
result['instances'] = instances
status 200
end
result
end
post "#{api_prefix}/vm/:template/?" do
content_type :json
result = { 'ok' => false }

View file

@ -1213,6 +1213,55 @@ module Vmpooler
raise("Provider '#{provider_class}' is unknown for pool with provider name '#{provider_name}'") if provider.nil?
end
def check_ondemand_requests(maxloop = 0,
loop_delay_min = CHECK_LOOP_DELAY_MIN_DEFAULT,
loop_delay_max = CHECK_LOOP_DELAY_MAX_DEFAULT,
loop_delay_decay = CHECK_LOOP_DELAY_DECAY_DEFAULT)
# Use the pool setings if they exist
loop_delay_min = pool['check_loop_delay_min'] unless pool['check_loop_delay_min'].nil?
loop_delay_max = pool['check_loop_delay_max'] unless pool['check_loop_delay_max'].nil?
loop_delay_decay = pool['check_loop_delay_decay'] unless pool['check_loop_delay_decay'].nil?
loop_delay_decay = 2.0 if loop_delay_decay <= 1.0
loop_delay_max = loop_delay_min if loop_delay_max.nil? || loop_delay_max < loop_delay_min
loop_count = 1
loop_delay = loop_delay_min
loop do
result = process_ondemand_requests
loop_delay = (loop_delay * loop_delay_decay).to_i
loop_delay = loop_delay_min if result > 0
loop_delay = loop_delay_max if loop_delay > loop_delay_max
sleep_with_wakeup_events(loop_delay, loop_delay_min, ondemand_request: true)
unless maxloop == 0
break if loop_count >= maxloop
loop_count += 1
end
end
end
def process_ondemand_requests
requests = $redis.zrange('vmpooler__provisioning__requests', 0, -1)
return 0 if requests.empty?
requests.each do |request_id|
create_ondemand_vms(request_id)
$redis.zrem('vmpooler__provisioning__requests', request_id)
end
return requests.length
end
def create_ondemand_vms(request_id)
requested = $redis.hget("vmpooler__odrequest__#{request_id}", 'requested')
requested = requested.split(',')
end
def execute!(maxloop = 0, loop_delay = 1)
$logger.log('d', 'starting vmpooler')
@ -1303,6 +1352,13 @@ module Vmpooler
end
end
if !$threads['ondemand_provisioner']
check_ondemand_requests
elsif !$threads['ondemand_provisioner'].alive?
$logger.log('d', '[!] [ondemand_provisioner] worker thread died, restarting')
check_ondemand_requests
end
sleep(loop_delay)
unless maxloop == 0