mirror of
https://github.com/puppetlabs/vmpooler.git
synced 2026-01-26 10:08:40 -05:00
Implement redis connection pooling, multi, and pipelines.
This commit is contained in:
parent
52bf6c4c89
commit
9973ed878f
6 changed files with 234 additions and 204 deletions
|
|
@ -36,6 +36,7 @@ if torun.include? 'manager'
|
||||||
Vmpooler::PoolManager.new(
|
Vmpooler::PoolManager.new(
|
||||||
config,
|
config,
|
||||||
Vmpooler.new_logger(logger_file),
|
Vmpooler.new_logger(logger_file),
|
||||||
|
Vmpooler.redis_connection_pool(redis_host, redis_port, redis_password),
|
||||||
metrics
|
metrics
|
||||||
).execute!
|
).execute!
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ services:
|
||||||
- VMPOOLER_DEBUG=true # for use of dummy auth
|
- VMPOOLER_DEBUG=true # for use of dummy auth
|
||||||
- VMPOOLER_CONFIG_FILE=/etc/vmpooler/vmpooler.yaml
|
- VMPOOLER_CONFIG_FILE=/etc/vmpooler/vmpooler.yaml
|
||||||
- REDIS_SERVER=redislocal
|
- REDIS_SERVER=redislocal
|
||||||
- LOGFILE=/dev/stdout
|
- LOGFILE=/dev/null
|
||||||
- EXTRA_CONFIG=/etc/vmpooler/providers.yaml
|
- EXTRA_CONFIG=/etc/vmpooler/providers.yaml
|
||||||
image: vmpooler-local
|
image: vmpooler-local
|
||||||
depends_on:
|
depends_on:
|
||||||
|
|
|
||||||
|
|
@ -156,6 +156,12 @@ module Vmpooler
|
||||||
pools
|
pools
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.redis_connection_pool(host, port, password, size = 10)
|
||||||
|
ConnectionPool.new(size: size) {
|
||||||
|
redis_connection(host, port, password)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
def self.redis_connection(host = 'localhost', port = nil, password = nil)
|
def self.redis_connection(host = 'localhost', port = nil, password = nil)
|
||||||
Redis.new(host: host, port: port, password: password)
|
Redis.new(host: host, port: port, password: password)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,8 @@ module Vmpooler
|
||||||
end
|
end
|
||||||
|
|
||||||
def evaluate_template_aliases(template, count)
|
def evaluate_template_aliases(template, count)
|
||||||
template_backends = [template]
|
template_backends = []
|
||||||
|
template_backends << template if backend.sismember('vmpooler__pools', template)
|
||||||
selection = []
|
selection = []
|
||||||
aliases = get_template_aliases(template)
|
aliases = get_template_aliases(template)
|
||||||
if aliases
|
if aliases
|
||||||
|
|
@ -346,7 +347,7 @@ module Vmpooler
|
||||||
payload.delete('request_id')
|
payload.delete('request_id')
|
||||||
payload.each do |poolname, count|
|
payload.each do |poolname, count|
|
||||||
selection = evaluate_template_aliases(poolname, count)
|
selection = evaluate_template_aliases(poolname, count)
|
||||||
selection.map { |alias_name, alias_count| platforms_with_aliases << "#{poolname}:#{alias_name}:#{alias_count}" }
|
selection.map { |selected_pool, selected_pool_count| platforms_with_aliases << "#{poolname}:#{selected_pool}:#{selected_pool_count}" }
|
||||||
end
|
end
|
||||||
|
|
||||||
platforms_string = platforms_with_aliases.join(',')
|
platforms_string = platforms_with_aliases.join(',')
|
||||||
|
|
@ -904,9 +905,21 @@ module Vmpooler
|
||||||
platform_parts = request_hash['requested'].split(',')
|
platform_parts = request_hash['requested'].split(',')
|
||||||
platform_parts.each do |platform|
|
platform_parts.each do |platform|
|
||||||
pool_alias, pool, _count = platform.split(':')
|
pool_alias, pool, _count = platform.split(':')
|
||||||
result[pool_alias] = { 'hostname': request_hash[pool].split(':') }
|
instances = backend.smembers("vmpooler__#{request_id}__#{pool_alias}__#{pool}")
|
||||||
|
result[pool_alias] = { 'hostname': instances }
|
||||||
|
#backend.del("vmpooler__#{request_id}__#{pool_alias}__#{pool}")
|
||||||
end
|
end
|
||||||
status 200
|
status 200
|
||||||
|
else
|
||||||
|
platform_parts = request_hash['requested'].split(',')
|
||||||
|
platform_parts.each do |platform|
|
||||||
|
pool_alias, pool, count = platform.split(':')
|
||||||
|
instance_count = backend.scard("vmpooler__#{request_id}__#{pool_alias}__#{pool}")
|
||||||
|
result[pool_alias] = {
|
||||||
|
'ready': instance_count.to_s,
|
||||||
|
'pending': (count.to_i - instance_count.to_i).to_s
|
||||||
|
}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
result
|
result
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
require 'vmpooler/providers'
|
require 'vmpooler/providers'
|
||||||
require 'spicy-proton'
|
require 'spicy-proton'
|
||||||
|
require 'redis'
|
||||||
|
|
||||||
module Vmpooler
|
module Vmpooler
|
||||||
class PoolManager
|
class PoolManager
|
||||||
|
|
@ -9,7 +10,7 @@ module Vmpooler
|
||||||
CHECK_LOOP_DELAY_MAX_DEFAULT = 60
|
CHECK_LOOP_DELAY_MAX_DEFAULT = 60
|
||||||
CHECK_LOOP_DELAY_DECAY_DEFAULT = 2.0
|
CHECK_LOOP_DELAY_DECAY_DEFAULT = 2.0
|
||||||
|
|
||||||
def initialize(config, logger, metrics)
|
def initialize(config, logger, redis_connection_pool, metrics)
|
||||||
$config = config
|
$config = config
|
||||||
|
|
||||||
# Load logger library
|
# Load logger library
|
||||||
|
|
@ -19,24 +20,18 @@ module Vmpooler
|
||||||
$metrics = metrics
|
$metrics = metrics
|
||||||
|
|
||||||
# Redis connection pool
|
# Redis connection pool
|
||||||
@redis = ConnectionPool.new(size: 10) {
|
@redis = redis_connection_pool
|
||||||
Vmpooler.redis_connection(
|
|
||||||
$config[:config][:redis]['server'],
|
|
||||||
$config[:config][:redis]['port'],
|
|
||||||
$config[:config][:redis]['password']
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
# VM Provider objects
|
# VM Provider objects
|
||||||
$providers = {}
|
$providers = Concurrent::Hash.new
|
||||||
|
|
||||||
# Our thread-tracker object
|
# Our thread-tracker object
|
||||||
$threads = {}
|
$threads = Concurrent::Hash.new
|
||||||
|
|
||||||
# Pool mutex
|
# Pool mutex
|
||||||
@reconfigure_pool = {}
|
@reconfigure_pool = Concurrent::Hash.new
|
||||||
|
|
||||||
@vm_mutex = {}
|
@vm_mutex = Concurrent::Hash.new
|
||||||
|
|
||||||
# Name generator for generating host names
|
# Name generator for generating host names
|
||||||
@name_generator = Spicy::Proton.new
|
@name_generator = Spicy::Proton.new
|
||||||
|
|
@ -85,7 +80,10 @@ module Vmpooler
|
||||||
_check_pending_vm(vm, pool, timeout, provider)
|
_check_pending_vm(vm, pool, timeout, provider)
|
||||||
rescue StandardError => e
|
rescue StandardError => e
|
||||||
$logger.log('s', "[!] [#{pool}] '#{vm}' #{timeout} #{provider} errored while checking a pending vm : #{e}")
|
$logger.log('s', "[!] [#{pool}] '#{vm}' #{timeout} #{provider} errored while checking a pending vm : #{e}")
|
||||||
fail_pending_vm(vm, pool, timeout)
|
@redis.with do |redis|
|
||||||
|
request_id = redis.hget("vmpooler__vm__#{vm}", 'request_id')
|
||||||
|
fail_pending_vm(vm, pool, timeout, redis, request_id=request_id)
|
||||||
|
end
|
||||||
raise
|
raise
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -96,11 +94,13 @@ module Vmpooler
|
||||||
return if mutex.locked?
|
return if mutex.locked?
|
||||||
|
|
||||||
mutex.synchronize do
|
mutex.synchronize do
|
||||||
request_id = redis.hget("vmpooler__vm__#{vm}", 'request_id')
|
@redis.with do |redis|
|
||||||
if provider.vm_ready?(pool, vm)
|
request_id = redis.hget("vmpooler__vm__#{vm}", 'request_id')
|
||||||
move_pending_vm_to_ready(vm, pool, request_id, redis)
|
if provider.vm_ready?(pool, vm)
|
||||||
else
|
move_pending_vm_to_ready(vm, pool, request_id, redis)
|
||||||
fail_pending_vm(vm, pool, timeout, redis, request_id = request_id)
|
else
|
||||||
|
fail_pending_vm(vm, pool, timeout, redis, request_id = request_id)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -114,10 +114,14 @@ module Vmpooler
|
||||||
clone_stamp = redis.hget("vmpooler__vm__#{vm}", 'clone')
|
clone_stamp = redis.hget("vmpooler__vm__#{vm}", 'clone')
|
||||||
return true unless clone_stamp
|
return true unless clone_stamp
|
||||||
|
|
||||||
|
# if clone_stamp == 'QUEUED'
|
||||||
|
# $logger.log('s', "Waiting for clone_stamp. Got 'QUEUED'.")
|
||||||
|
# return true
|
||||||
|
# end
|
||||||
time_since_clone = (Time.now - Time.parse(clone_stamp)) / 60
|
time_since_clone = (Time.now - Time.parse(clone_stamp)) / 60
|
||||||
if time_since_clone > timeout
|
if time_since_clone > timeout
|
||||||
if exists
|
if exists
|
||||||
pool_alias = get_alias_for_request(pool, request_id, redis) if $request_id
|
pool_alias = redis.hget("vmpooler__vm__#{vm}", 'pool_alias') if $request_id
|
||||||
redis.multi
|
redis.multi
|
||||||
redis.smove('vmpooler__pending__' + pool, 'vmpooler__completed__' + pool, vm)
|
redis.smove('vmpooler__pending__' + pool, 'vmpooler__completed__' + pool, vm)
|
||||||
redis.zadd('vmpooler__odcreate__task', 1, "#{pool_alias}:#{pool_name}:1:#{request_id}") if request_id
|
redis.zadd('vmpooler__odcreate__task', 1, "#{pool_alias}:#{pool_name}:1:#{request_id}") if request_id
|
||||||
|
|
@ -136,32 +140,36 @@ module Vmpooler
|
||||||
|
|
||||||
def move_pending_vm_to_ready(vm, pool, request_id, redis)
|
def move_pending_vm_to_ready(vm, pool, request_id, redis)
|
||||||
clone_time = redis.hget('vmpooler__vm__' + vm, 'clone')
|
clone_time = redis.hget('vmpooler__vm__' + vm, 'clone')
|
||||||
finish = format('%<time>.2f', time: Time.now - Time.parse(clone_time)) if clone_time
|
# return false unless clone_time
|
||||||
|
# if clone_time == 'QUEUED'
|
||||||
|
# $logger.log('s', "Waiting for clone_time. Got 'QUEUED'.")
|
||||||
|
# return false
|
||||||
|
# end
|
||||||
|
finish = format('%<time>.2f', time: Time.now - Time.parse(clone_time))
|
||||||
|
|
||||||
if request_id
|
if request_id
|
||||||
fulfilled = redis.hget("vmpooler__odrequest__#{request_id}", pool)
|
pool_alias = redis.hget("vmpooler__vm__#{vm}", 'pool_alias')
|
||||||
fulfilled = "#{fulfilled}:#{vm}" if fulfilled
|
redis.pipelined do
|
||||||
fulfilled ||= vm
|
redis.hset("vmpooler__active__#{pool}", vm, Time.now)
|
||||||
|
redis.hset("vmpooler__vm__#{vm}", 'checkout', Time.now)
|
||||||
redis.multi
|
redis.sadd("vmpooler__#{request_id}__#{pool_alias}__#{pool}", vm)
|
||||||
redis.hset("vmpooler__active__#{pool}", vm, Time.now)
|
end
|
||||||
redis.hset("vmpooler__vm__#{vm}", 'checkout', Time.now)
|
|
||||||
redis.hset("vmpooler__odrequest__#{request_id}", pool, fulfilled)
|
|
||||||
move_vm_queue(pool, vm, 'pending', 'running', redis)
|
move_vm_queue(pool, vm, 'pending', 'running', redis)
|
||||||
else
|
else
|
||||||
redis.multi
|
|
||||||
redis.smove('vmpooler__pending__' + pool, 'vmpooler__ready__' + pool, vm)
|
redis.smove('vmpooler__pending__' + pool, 'vmpooler__ready__' + pool, vm)
|
||||||
end
|
end
|
||||||
|
|
||||||
redis.hset('vmpooler__boot__' + Date.today.to_s, pool + ':' + vm, finish) # maybe remove as this is never used by vmpooler itself?
|
redis.pipelined do
|
||||||
redis.hset("vmpooler__vm__#{vm}", 'ready', Time.now)
|
redis.hset('vmpooler__boot__' + Date.today.to_s, pool + ':' + vm, finish) # maybe remove as this is never used by vmpooler itself?
|
||||||
|
redis.hset("vmpooler__vm__#{vm}", 'ready', Time.now)
|
||||||
|
|
||||||
# last boot time is displayed in API, and used by alarming script
|
# last boot time is displayed in API, and used by alarming script
|
||||||
redis.hset('vmpooler__lastboot', pool, Time.now)
|
redis.hset('vmpooler__lastboot', pool, Time.now)
|
||||||
redis.exec
|
end
|
||||||
|
|
||||||
$metrics.timing("time_to_ready_state.#{pool}", finish)
|
$metrics.timing("time_to_ready_state.#{pool}", finish)
|
||||||
$logger.log('s', "[>] [#{pool}] '#{vm}' moved from 'pending' to 'ready' queue")
|
$logger.log('s', "[>] [#{pool}] '#{vm}' moved from 'pending' to 'ready' queue") unless request_id
|
||||||
|
$logger.log('s', "[>] [#{pool}] '#{vm}' is 'ready' for request '#{request_id}'") if request_id
|
||||||
end
|
end
|
||||||
|
|
||||||
def vm_still_ready?(pool_name, vm_name, provider, redis)
|
def vm_still_ready?(pool_name, vm_name, provider, redis)
|
||||||
|
|
@ -173,10 +181,10 @@ module Vmpooler
|
||||||
move_vm_queue(pool_name, vm_name, 'ready', 'completed', redis, "is unreachable, removed from 'ready' queue")
|
move_vm_queue(pool_name, vm_name, 'ready', 'completed', redis, "is unreachable, removed from 'ready' queue")
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_ready_vm(vm, pool_name, ttl, provider, redis)
|
def check_ready_vm(vm, pool_name, ttl, provider)
|
||||||
Thread.new do
|
Thread.new do
|
||||||
begin
|
begin
|
||||||
_check_ready_vm(vm, pool_name, ttl, provider, redis)
|
_check_ready_vm(vm, pool_name, ttl, provider)
|
||||||
rescue StandardError => e
|
rescue StandardError => e
|
||||||
$logger.log('s', "[!] [#{pool_name}] '#{vm}' failed while checking a ready vm : #{e}")
|
$logger.log('s', "[!] [#{pool_name}] '#{vm}' failed while checking a ready vm : #{e}")
|
||||||
raise
|
raise
|
||||||
|
|
@ -184,36 +192,38 @@ module Vmpooler
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def _check_ready_vm(vm, pool_name, ttl, provider, redis)
|
def _check_ready_vm(vm, pool_name, ttl, provider)
|
||||||
# Periodically check that the VM is available
|
# Periodically check that the VM is available
|
||||||
mutex = vm_mutex(vm)
|
mutex = vm_mutex(vm)
|
||||||
return if mutex.locked?
|
return if mutex.locked?
|
||||||
|
|
||||||
mutex.synchronize do
|
mutex.synchronize do
|
||||||
check_stamp = redis.hget('vmpooler__vm__' + vm, 'check')
|
@redis.with do |redis|
|
||||||
return if check_stamp && (((Time.now - Time.parse(check_stamp)) / 60) <= $config[:config]['vm_checktime'])
|
check_stamp = redis.hget('vmpooler__vm__' + vm, 'check')
|
||||||
|
return if check_stamp && (((Time.now - Time.parse(check_stamp)) / 60) <= $config[:config]['vm_checktime'])
|
||||||
|
|
||||||
redis.hset('vmpooler__vm__' + vm, 'check', Time.now)
|
redis.hset('vmpooler__vm__' + vm, 'check', Time.now)
|
||||||
# Check if the hosts TTL has expired
|
# Check if the hosts TTL has expired
|
||||||
if ttl > 0
|
if ttl > 0
|
||||||
# if 'boottime' is nil, set bootime to beginning of unix epoch, forces TTL to be assumed expired
|
# if 'boottime' is nil, set bootime to beginning of unix epoch, forces TTL to be assumed expired
|
||||||
boottime = redis.hget("vmpooler__vm__#{vm}", 'ready')
|
boottime = redis.hget("vmpooler__vm__#{vm}", 'ready')
|
||||||
if boottime
|
if boottime
|
||||||
boottime = Time.parse(boottime)
|
boottime = Time.parse(boottime)
|
||||||
else
|
else
|
||||||
boottime = Time.at(0)
|
boottime = Time.at(0)
|
||||||
end
|
end
|
||||||
if ((Time.now - boottime) / 60).to_s[/^\d+\.\d{1}/].to_f > ttl
|
if ((Time.now - boottime) / 60).to_s[/^\d+\.\d{1}/].to_f > ttl
|
||||||
redis.smove('vmpooler__ready__' + pool_name, 'vmpooler__completed__' + pool_name, vm)
|
redis.smove('vmpooler__ready__' + pool_name, 'vmpooler__completed__' + pool_name, vm)
|
||||||
|
|
||||||
$logger.log('d', "[!] [#{pool_name}] '#{vm}' reached end of TTL after #{ttl} minutes, removed from 'ready' queue")
|
$logger.log('d', "[!] [#{pool_name}] '#{vm}' reached end of TTL after #{ttl} minutes, removed from 'ready' queue")
|
||||||
return
|
return
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
return if mismatched_hostname?(vm, pool_name, provider)
|
||||||
|
|
||||||
|
vm_still_ready?(pool_name, vm, provider, redis)
|
||||||
end
|
end
|
||||||
|
|
||||||
return if mismatched_hostname?(vm, pool_name, provider)
|
|
||||||
|
|
||||||
vm_still_ready?(pool_name, vm, provider, redis)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -248,10 +258,10 @@ module Vmpooler
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_running_vm(vm, pool, ttl, provider, redis)
|
def check_running_vm(vm, pool, ttl, provider)
|
||||||
Thread.new do
|
Thread.new do
|
||||||
begin
|
begin
|
||||||
_check_running_vm(vm, pool, ttl, provider, redis)
|
_check_running_vm(vm, pool, ttl, provider)
|
||||||
rescue StandardError => e
|
rescue StandardError => e
|
||||||
$logger.log('s', "[!] [#{pool}] '#{vm}' failed while checking VM with an error: #{e}")
|
$logger.log('s', "[!] [#{pool}] '#{vm}' failed while checking VM with an error: #{e}")
|
||||||
raise
|
raise
|
||||||
|
|
@ -259,31 +269,39 @@ module Vmpooler
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def _check_running_vm(vm, pool, ttl, provider, redis)
|
def _check_running_vm(vm, pool, ttl, provider)
|
||||||
mutex = vm_mutex(vm)
|
mutex = vm_mutex(vm)
|
||||||
return if mutex.locked?
|
return if mutex.locked?
|
||||||
|
|
||||||
mutex.synchronize do
|
mutex.synchronize do
|
||||||
# Check that VM is within defined lifetime
|
@redis.with do |redis|
|
||||||
checkouttime = redis.hget('vmpooler__active__' + pool, vm)
|
# Check that VM is within defined lifetime
|
||||||
if checkouttime
|
checkouttime = redis.hget('vmpooler__active__' + pool, vm)
|
||||||
running = (Time.now - Time.parse(checkouttime)) / 60 / 60
|
# return if checkouttime == 'QUEUED'
|
||||||
|
if checkouttime
|
||||||
|
# if checkouttime == 'QUEUED'
|
||||||
|
# $logger.log('s', "checkouttime is #{checkouttime}")
|
||||||
|
# return
|
||||||
|
# end
|
||||||
|
time_since_checkout = Time.now - Time.parse(checkouttime)
|
||||||
|
running = time_since_checkout / 60 / 60
|
||||||
|
|
||||||
if (ttl.to_i > 0) && (running.to_i >= ttl.to_i)
|
if (ttl.to_i > 0) && (running.to_i >= ttl.to_i)
|
||||||
move_vm_queue(pool, vm, 'running', 'completed', redis, "reached end of TTL after #{ttl} hours")
|
move_vm_queue(pool, vm, 'running', 'completed', redis, "reached end of TTL after #{ttl} hours")
|
||||||
return
|
return
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
if provider.vm_ready?(pool, vm)
|
if provider.vm_ready?(pool, vm)
|
||||||
return
|
|
||||||
else
|
|
||||||
host = provider.get_vm(pool, vm)
|
|
||||||
|
|
||||||
if host
|
|
||||||
return
|
return
|
||||||
else
|
else
|
||||||
move_vm_queue(pool, vm, 'running', 'completed', redis, 'is no longer in inventory, removing from running')
|
host = provider.get_vm(pool, vm)
|
||||||
|
|
||||||
|
if host
|
||||||
|
return
|
||||||
|
else
|
||||||
|
move_vm_queue(pool, vm, 'running', 'completed', redis, 'is no longer in inventory, removing from running')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -295,15 +313,13 @@ module Vmpooler
|
||||||
end
|
end
|
||||||
|
|
||||||
# Clone a VM
|
# Clone a VM
|
||||||
def clone_vm(pool_name, provider, request_id = nil)
|
def clone_vm(pool_name, provider, request_id = nil, pool_alias = nil)
|
||||||
Thread.new do
|
Thread.new do
|
||||||
begin
|
begin
|
||||||
_clone_vm(pool_name, provider, request_id)
|
_clone_vm(pool_name, provider, request_id, pool_alias)
|
||||||
rescue StandardError => e
|
rescue StandardError => e
|
||||||
if request_id
|
if request_id
|
||||||
$logger.log('s', "[!] [#{pool_name}] failed while cloning VM for request #{request_id} with an error: #{e}")
|
$logger.log('s', "[!] [#{pool_name}] failed while cloning VM for request #{request_id} with an error: #{e}")
|
||||||
pool_alias = get_alias_for_request(pool, request_id)
|
|
||||||
$logger.log('s', "Pool_alias is #{pool_alias}")
|
|
||||||
@redis.with do |redis|
|
@redis.with do |redis|
|
||||||
redis.zadd('vmpooler__odcreate__task', 1, "#{pool_alias}:#{pool_name}:1:#{request_id}")
|
redis.zadd('vmpooler__odcreate__task', 1, "#{pool_alias}:#{pool_name}:1:#{request_id}")
|
||||||
end
|
end
|
||||||
|
|
@ -350,59 +366,58 @@ module Vmpooler
|
||||||
hostname
|
hostname
|
||||||
end
|
end
|
||||||
|
|
||||||
def _clone_vm(pool_name, provider, request_id = nil)
|
def _clone_vm(pool_name, provider, request_id = nil, pool_alias = nil)
|
||||||
@redis.with do |redis|
|
@redis.with do |redis|
|
||||||
new_vmname = find_unique_hostname(pool_name, redis)
|
new_vmname = find_unique_hostname(pool_name, redis)
|
||||||
|
mutex = vm_mutex(new_vmname)
|
||||||
|
mutex.synchronize do
|
||||||
|
|
||||||
# Add VM to Redis inventory ('pending' pool)
|
# Add VM to Redis inventory ('pending' pool)
|
||||||
redis.multi
|
|
||||||
redis.sadd('vmpooler__pending__' + pool_name, new_vmname)
|
|
||||||
redis.hset('vmpooler__vm__' + new_vmname, 'clone', Time.now)
|
|
||||||
redis.hset('vmpooler__vm__' + new_vmname, 'template', pool_name)
|
|
||||||
redis.hset('vmpooler__vm__' + new_vmname, 'request_id', request_id)
|
|
||||||
redis.exec
|
|
||||||
end
|
|
||||||
|
|
||||||
begin
|
|
||||||
$logger.log('d', "[ ] [#{pool_name}] Starting to clone '#{new_vmname}'")
|
|
||||||
start = Time.now
|
|
||||||
provider.create_vm(pool_name, new_vmname)
|
|
||||||
finish = format('%<time>.2f', time: Time.now - start)
|
|
||||||
|
|
||||||
@redis.with do |redis|
|
|
||||||
redis.multi
|
redis.multi
|
||||||
redis.hset('vmpooler__clone__' + Date.today.to_s, pool_name + ':' + new_vmname, finish)
|
redis.sadd('vmpooler__pending__' + pool_name, new_vmname)
|
||||||
redis.hset('vmpooler__vm__' + new_vmname, 'clone_time', finish)
|
redis.hset('vmpooler__vm__' + new_vmname, 'clone', Time.now)
|
||||||
|
redis.hset('vmpooler__vm__' + new_vmname, 'template', pool_name) # This value is used to represent the pool.
|
||||||
|
redis.hset('vmpooler__vm__' + new_vmname, 'pool', pool_name)
|
||||||
|
redis.hset('vmpooler__vm__' + new_vmname, 'request_id', request_id) if request_id
|
||||||
|
redis.hset('vmpooler__vm__' + new_vmname, 'pool_alias', pool_alias) if pool_alias
|
||||||
redis.exec
|
redis.exec
|
||||||
end
|
|
||||||
$logger.log('s', "[+] [#{pool_name}] '#{new_vmname}' cloned in #{finish} seconds")
|
|
||||||
|
|
||||||
$metrics.timing("clone.#{pool_name}", finish)
|
begin
|
||||||
rescue StandardError
|
$logger.log('d', "[ ] [#{pool_name}] Starting to clone '#{new_vmname}'")
|
||||||
@redis.with do |redis|
|
start = Time.now
|
||||||
redis.multi
|
provider.create_vm(pool_name, new_vmname)
|
||||||
redis.srem("vmpooler__pending__#{pool_name}", new_vmname)
|
finish = format('%<time>.2f', time: Time.now - start)
|
||||||
expiration_ttl = $config[:redis]['data_ttl'].to_i * 60 * 60
|
|
||||||
redis.expire("vmpooler__vm__#{new_vmname}", expiration_ttl)
|
redis.pipelined do
|
||||||
redis.exec
|
redis.hset('vmpooler__clone__' + Date.today.to_s, pool_name + ':' + new_vmname, finish)
|
||||||
end
|
redis.hset('vmpooler__vm__' + new_vmname, 'clone_time', finish)
|
||||||
raise
|
end
|
||||||
ensure
|
$logger.log('s', "[+] [#{pool_name}] '#{new_vmname}' cloned in #{finish} seconds")
|
||||||
if request_id
|
|
||||||
@tasks['ondemand_clone_count'] -= 1 if request_id
|
$metrics.timing("clone.#{pool_name}", finish)
|
||||||
else
|
rescue StandardError
|
||||||
@redis.with do |redis|
|
redis.pipelined do
|
||||||
redis.decr('vmpooler__tasks__clone') unless request_id
|
redis.srem("vmpooler__pending__#{pool_name}", new_vmname)
|
||||||
|
expiration_ttl = $config[:redis]['data_ttl'].to_i * 60 * 60
|
||||||
|
redis.expire("vmpooler__vm__#{new_vmname}", expiration_ttl)
|
||||||
|
end
|
||||||
|
raise
|
||||||
|
ensure
|
||||||
|
if request_id
|
||||||
|
@tasks['ondemand_clone_count'] -= 1
|
||||||
|
else
|
||||||
|
redis.decr('vmpooler__tasks__clone')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Destroy a VM
|
# Destroy a VM
|
||||||
def destroy_vm(vm, pool, provider, redis)
|
def destroy_vm(vm, pool, provider)
|
||||||
Thread.new do
|
Thread.new do
|
||||||
begin
|
begin
|
||||||
_destroy_vm(vm, pool, provider, redis)
|
_destroy_vm(vm, pool, provider)
|
||||||
rescue StandardError => e
|
rescue StandardError => e
|
||||||
$logger.log('d', "[!] [#{pool}] '#{vm}' failed while destroying the VM with an error: #{e}")
|
$logger.log('d', "[!] [#{pool}] '#{vm}' failed while destroying the VM with an error: #{e}")
|
||||||
raise
|
raise
|
||||||
|
|
@ -410,27 +425,29 @@ module Vmpooler
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def _destroy_vm(vm, pool, provider, redis)
|
def _destroy_vm(vm, pool, provider)
|
||||||
mutex = vm_mutex(vm)
|
mutex = vm_mutex(vm)
|
||||||
return if mutex.locked?
|
return if mutex.locked?
|
||||||
|
|
||||||
mutex.synchronize do
|
mutex.synchronize do
|
||||||
redis.hdel('vmpooler__active__' + pool, vm)
|
@redis.with do |redis|
|
||||||
redis.hset('vmpooler__vm__' + vm, 'destroy', Time.now)
|
redis.hdel('vmpooler__active__' + pool, vm)
|
||||||
|
redis.hset('vmpooler__vm__' + vm, 'destroy', Time.now)
|
||||||
|
|
||||||
# Auto-expire metadata key
|
# Auto-expire metadata key
|
||||||
redis.expire('vmpooler__vm__' + vm, ($config[:redis]['data_ttl'].to_i * 60 * 60))
|
redis.expire('vmpooler__vm__' + vm, ($config[:redis]['data_ttl'].to_i * 60 * 60))
|
||||||
|
|
||||||
start = Time.now
|
start = Time.now
|
||||||
|
|
||||||
provider.destroy_vm(pool, vm)
|
provider.destroy_vm(pool, vm)
|
||||||
|
|
||||||
redis.srem('vmpooler__completed__' + pool, vm)
|
redis.srem('vmpooler__completed__' + pool, vm)
|
||||||
|
|
||||||
finish = format('%<time>.2f', time: Time.now - start)
|
finish = format('%<time>.2f', time: Time.now - start)
|
||||||
$logger.log('s', "[-] [#{pool}] '#{vm}' destroyed in #{finish} seconds")
|
$logger.log('s', "[-] [#{pool}] '#{vm}' destroyed in #{finish} seconds")
|
||||||
$metrics.timing("destroy.#{pool}", finish)
|
$metrics.timing("destroy.#{pool}", finish)
|
||||||
get_vm_usage_labels(vm, redis)
|
get_vm_usage_labels(vm, redis)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
dereference_mutex(vm)
|
dereference_mutex(vm)
|
||||||
end
|
end
|
||||||
|
|
@ -439,14 +456,13 @@ module Vmpooler
|
||||||
return unless $config[:config]['usage_stats']
|
return unless $config[:config]['usage_stats']
|
||||||
|
|
||||||
redis.multi
|
redis.multi
|
||||||
checkout = redis.hget("vmpooler__vm__#{vm}", 'checkout')
|
redis.hget("vmpooler__vm__#{vm}", 'checkout')
|
||||||
|
redis.hget("vmpooler__vm__#{vm}", 'tag:jenkins_build_url')
|
||||||
|
redis.hget("vmpooler__vm__#{vm}", 'token:user') || 'unauthenticated'
|
||||||
|
redis.hget("vmpooler__vm__#{vm}", 'template')
|
||||||
|
checkout, jenkins_build_url, user, poolname = redis.exec
|
||||||
return if checkout.nil?
|
return if checkout.nil?
|
||||||
|
|
||||||
jenkins_build_url = redis.hget("vmpooler__vm__#{vm}", 'tag:jenkins_build_url')
|
|
||||||
user = redis.hget("vmpooler__vm__#{vm}", 'token:user') || 'unauthenticated'
|
|
||||||
poolname = redis.hget("vmpooler__vm__#{vm}", 'template')
|
|
||||||
redis.exec
|
|
||||||
|
|
||||||
unless jenkins_build_url
|
unless jenkins_build_url
|
||||||
user = user.gsub('.', '_')
|
user = user.gsub('.', '_')
|
||||||
$metrics.increment("usage.#{user}.#{poolname}")
|
$metrics.increment("usage.#{user}.#{poolname}")
|
||||||
|
|
@ -928,9 +944,9 @@ module Vmpooler
|
||||||
def sync_pool_template(pool)
|
def sync_pool_template(pool)
|
||||||
@redis.with do |redis|
|
@redis.with do |redis|
|
||||||
pool_template = redis.hget('vmpooler__config__template', pool['name'])
|
pool_template = redis.hget('vmpooler__config__template', pool['name'])
|
||||||
end
|
if pool_template
|
||||||
if pool_template
|
pool['template'] = pool_template unless pool['template'] == pool_template
|
||||||
pool['template'] = pool_template unless pool['template'] == pool_template
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -1025,17 +1041,20 @@ module Vmpooler
|
||||||
|
|
||||||
def remove_excess_vms(pool)
|
def remove_excess_vms(pool)
|
||||||
@redis.with do |redis|
|
@redis.with do |redis|
|
||||||
ready = redis.scard("vmpooler__ready__#{pool['name']}")
|
redis.multi
|
||||||
total = redis.scard("vmpooler__pending__#{pool['name']}") + ready
|
redis.scard("vmpooler__ready__#{pool['name']}")
|
||||||
|
redis.scard("vmpooler__pending__#{pool['name']}")
|
||||||
|
ready, pending = redis.exec
|
||||||
|
total = pending.to_i + total.to_i
|
||||||
return if total.nil?
|
return if total.nil?
|
||||||
return if total == 0
|
return if total == 0
|
||||||
|
|
||||||
mutex = pool_mutex(pool['name'])
|
mutex = pool_mutex(pool['name'])
|
||||||
return if mutex.locked?
|
return if mutex.locked?
|
||||||
return unless ready > pool['size']
|
return unless ready.to_i > pool['size']
|
||||||
|
|
||||||
mutex.synchronize do
|
mutex.synchronize do
|
||||||
difference = ready - pool['size']
|
difference = ready.to_i - pool['size']
|
||||||
difference.times do
|
difference.times do
|
||||||
next_vm = redis.spop("vmpooler__ready__#{pool['name']}")
|
next_vm = redis.spop("vmpooler__ready__#{pool['name']}")
|
||||||
move_vm_queue(pool['name'], next_vm, 'ready', 'completed', redis)
|
move_vm_queue(pool['name'], next_vm, 'ready', 'completed', redis)
|
||||||
|
|
@ -1118,7 +1137,7 @@ module Vmpooler
|
||||||
begin
|
begin
|
||||||
vm_lifetime = redis.hget('vmpooler__vm__' + vm, 'lifetime') || $config[:config]['vm_lifetime'] || 12
|
vm_lifetime = redis.hget('vmpooler__vm__' + vm, 'lifetime') || $config[:config]['vm_lifetime'] || 12
|
||||||
pool_check_response[:checked_running_vms] += 1
|
pool_check_response[:checked_running_vms] += 1
|
||||||
check_running_vm(vm, pool_name, vm_lifetime, provider, redis)
|
check_running_vm(vm, pool_name, vm_lifetime, provider)
|
||||||
rescue StandardError => e
|
rescue StandardError => e
|
||||||
$logger.log('d', "[!] [#{pool_name}] _check_pool with an error while evaluating running VMs: #{e}")
|
$logger.log('d', "[!] [#{pool_name}] _check_pool with an error while evaluating running VMs: #{e}")
|
||||||
end
|
end
|
||||||
|
|
@ -1153,7 +1172,7 @@ module Vmpooler
|
||||||
if inventory[vm]
|
if inventory[vm]
|
||||||
begin
|
begin
|
||||||
pool_check_response[:checked_pending_vms] += 1
|
pool_check_response[:checked_pending_vms] += 1
|
||||||
check_pending_vm(vm, pool_name, pool_timeout, provider, redis)
|
check_pending_vm(vm, pool_name, pool_timeout, provider)
|
||||||
rescue StandardError => e
|
rescue StandardError => e
|
||||||
$logger.log('d', "[!] [#{pool_name}] _check_pool failed with an error while evaluating pending VMs: #{e}")
|
$logger.log('d', "[!] [#{pool_name}] _check_pool failed with an error while evaluating pending VMs: #{e}")
|
||||||
end
|
end
|
||||||
|
|
@ -1170,22 +1189,22 @@ module Vmpooler
|
||||||
if inventory[vm]
|
if inventory[vm]
|
||||||
begin
|
begin
|
||||||
pool_check_response[:destroyed_vms] += 1
|
pool_check_response[:destroyed_vms] += 1
|
||||||
destroy_vm(vm, pool_name, provider, redis)
|
destroy_vm(vm, pool_name, provider)
|
||||||
rescue StandardError => e
|
rescue StandardError => e
|
||||||
redis.multi
|
redis.pipelined do
|
||||||
redis.srem("vmpooler__completed__#{pool_name}", vm)
|
redis.srem("vmpooler__completed__#{pool_name}", vm)
|
||||||
redis.hdel("vmpooler__active__#{pool_name}", vm)
|
redis.hdel("vmpooler__active__#{pool_name}", vm)
|
||||||
redis.del("vmpooler__vm__#{vm}")
|
redis.del("vmpooler__vm__#{vm}")
|
||||||
redis.exec
|
end
|
||||||
$logger.log('d', "[!] [#{pool_name}] _check_pool failed with an error while evaluating completed VMs: #{e}")
|
$logger.log('d', "[!] [#{pool_name}] _check_pool failed with an error while evaluating completed VMs: #{e}")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
$logger.log('s', "[!] [#{pool_name}] '#{vm}' not found in inventory, removed from 'completed' queue")
|
$logger.log('s', "[!] [#{pool_name}] '#{vm}' not found in inventory, removed from 'completed' queue")
|
||||||
redis.multi
|
redis.pipelined do
|
||||||
redis.srem("vmpooler__completed__#{pool_name}", vm)
|
redis.srem("vmpooler__completed__#{pool_name}", vm)
|
||||||
redis.hdel("vmpooler__active__#{pool_name}", vm)
|
redis.hdel("vmpooler__active__#{pool_name}", vm)
|
||||||
redis.del("vmpooler__vm__#{vm}")
|
redis.del("vmpooler__vm__#{vm}")
|
||||||
redis.exec
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -1228,10 +1247,11 @@ module Vmpooler
|
||||||
|
|
||||||
@redis.with do |redis|
|
@redis.with do |redis|
|
||||||
redis.multi
|
redis.multi
|
||||||
ready = redis.scard("vmpooler__ready__#{pool_name}")
|
redis.scard("vmpooler__ready__#{pool_name}")
|
||||||
total = redis.scard("vmpooler__pending__#{pool_name}") + ready
|
redis.scard("vmpooler__pending__#{pool_name}")
|
||||||
running = redis.scard("vmpooler__running__#{pool_name}")
|
redis.scard("vmpooler__running__#{pool_name}")
|
||||||
redis.exec
|
ready, pending, running = redis.exec
|
||||||
|
total = pending.to_i + ready.to_i
|
||||||
|
|
||||||
$metrics.gauge("ready.#{pool_name}", ready)
|
$metrics.gauge("ready.#{pool_name}", ready)
|
||||||
$metrics.gauge("running.#{pool_name}", running)
|
$metrics.gauge("running.#{pool_name}", running)
|
||||||
|
|
@ -1243,7 +1263,7 @@ module Vmpooler
|
||||||
$logger.log('s', "[!] [#{pool_name}] is empty")
|
$logger.log('s', "[!] [#{pool_name}] is empty")
|
||||||
end
|
end
|
||||||
|
|
||||||
(pool_size - total).times do
|
(pool_size - total.to_i).times do
|
||||||
if redis.get('vmpooler__tasks__clone').to_i < $config[:config]['task_limit'].to_i
|
if redis.get('vmpooler__tasks__clone').to_i < $config[:config]['task_limit'].to_i
|
||||||
begin
|
begin
|
||||||
redis.incr('vmpooler__tasks__clone')
|
redis.incr('vmpooler__tasks__clone')
|
||||||
|
|
@ -1369,8 +1389,8 @@ module Vmpooler
|
||||||
requests&.map { |request_id| create_ondemand_vms(request_id, redis) }
|
requests&.map { |request_id| create_ondemand_vms(request_id, redis) }
|
||||||
provisioning_tasks = process_ondemand_vms(redis)
|
provisioning_tasks = process_ondemand_vms(redis)
|
||||||
requests_ready = check_ondemand_requests_ready(redis)
|
requests_ready = check_ondemand_requests_ready(redis)
|
||||||
|
requests.length + provisioning_tasks + requests_ready
|
||||||
end
|
end
|
||||||
requests.length + provisioning_tasks + requests_ready
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_ondemand_vms(request_id, redis)
|
def create_ondemand_vms(request_id, redis)
|
||||||
|
|
@ -1383,43 +1403,43 @@ module Vmpooler
|
||||||
score = redis.zscore('vmpooler__provisioning__request', request_id)
|
score = redis.zscore('vmpooler__provisioning__request', request_id)
|
||||||
requested = requested.split(',')
|
requested = requested.split(',')
|
||||||
|
|
||||||
redis.multi
|
redis.pipelined do
|
||||||
requested.each do |request|
|
requested.each do |request|
|
||||||
redis.zadd('vmpooler__odcreate__task', Time.now.to_i, "#{request}:#{request_id}")
|
redis.zadd('vmpooler__odcreate__task', Time.now.to_i, "#{request}:#{request_id}")
|
||||||
|
end
|
||||||
|
redis.zrem('vmpooler__provisioning__request', request_id)
|
||||||
|
redis.zadd('vmpooler__provisioning__processing', score, request_id)
|
||||||
end
|
end
|
||||||
redis.zrem('vmpooler__provisioning__request', request_id)
|
|
||||||
redis.zadd('vmpooler__provisioning__processing', score, request_id)
|
|
||||||
redis.exec
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def process_ondemand_vms(redis)
|
def process_ondemand_vms(redis)
|
||||||
queue_key = 'vmpooler__odcreate__task'
|
queue_key = 'vmpooler__odcreate__task'
|
||||||
queue = redis.zrange(queue_key, 0, -1)
|
queue = redis.zrange(queue_key, 0, -1, :with_scores => true)
|
||||||
ondemand_clone_limit = $config[:config]['ondemand_clone_limit']
|
ondemand_clone_limit = $config[:config]['ondemand_clone_limit']
|
||||||
@tasks['ondemand_clone_count'] = 0 unless @tasks['ondemand_clone_count']
|
@tasks['ondemand_clone_count'] = 0 unless @tasks['ondemand_clone_count']
|
||||||
queue.each do |request|
|
queue.each do |request, score|
|
||||||
if @tasks['ondemand_clone_count'] < ondemand_clone_limit
|
if @tasks['ondemand_clone_count'] < ondemand_clone_limit
|
||||||
requested_platform, fulfilled_platform, count, request_id = request.split(':')
|
pool_alias, pool, count, request_id = request.split(':')
|
||||||
count = count.to_i
|
count = count.to_i
|
||||||
provider = get_provider_for_pool(fulfilled_platform)
|
provider = get_provider_for_pool(pool)
|
||||||
delta = ondemand_clone_limit - @tasks['ondemand_clone_count']
|
slots = ondemand_clone_limit - @tasks['ondemand_clone_count']
|
||||||
if delta >= count
|
return if slots == 0
|
||||||
|
if slots >= count
|
||||||
count.times do
|
count.times do
|
||||||
@tasks['ondemand_clone_count'] += 1
|
@tasks['ondemand_clone_count'] += 1
|
||||||
clone_vm(fulfilled_platform, provider, request_id)
|
clone_vm(pool, provider, request_id, pool_alias)
|
||||||
end
|
end
|
||||||
redis.zrem(queue_key, request)
|
redis.zrem(queue_key, request)
|
||||||
else
|
else
|
||||||
available_slots = delta - count
|
remaining_count = count - slots
|
||||||
available_slots.times do
|
slots.times do
|
||||||
@tasks['ondemand_clone_count'] += 1
|
@tasks['ondemand_clone_count'] += 1
|
||||||
clone_vm(fulfilled_platform, provider, request_id)
|
clone_vm(pool, provider, request_id, pool_alias)
|
||||||
|
end
|
||||||
|
redis.pipelined do
|
||||||
|
redis.zrem(queue_key, request)
|
||||||
|
redis.zadd(queue_key, score, "#{pool_alias}:#{pool}:#{remaining_count}:#{request_id}")
|
||||||
end
|
end
|
||||||
score = redis.zscore(queue_key, request_id)
|
|
||||||
redis.multi
|
|
||||||
redis.zrem(queue_key, request)
|
|
||||||
redis.zadd(queue_key, score, "#{requested_platform}:#{fulfilled_platform}:#{count - delta}:#{request_id}")
|
|
||||||
redis.exec
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
break
|
break
|
||||||
|
|
@ -1428,25 +1448,14 @@ module Vmpooler
|
||||||
queue.length
|
queue.length
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_alias_for_request(pool, request_id, redis)
|
|
||||||
# Identify the alias associated with a request_id for retries to get tagged properly
|
|
||||||
requested = redis.hget("vmpooler__odrequest__#{request_id}", 'requested')
|
|
||||||
requested.split(',').each do |request|
|
|
||||||
pool_alias, pool_name, count = request.split(':')
|
|
||||||
return pool_alias if pool_name == pool
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def vms_ready?(request_id, redis)
|
def vms_ready?(request_id, redis)
|
||||||
catch :request_not_ready do
|
catch :request_not_ready do
|
||||||
request_hash = redis.hgetall("vmpooler__odrequest__#{request_id}")
|
request_hash = redis.hgetall("vmpooler__odrequest__#{request_id}")
|
||||||
requested_platforms = request_hash['requested'].split(',')
|
requested_platforms = request_hash['requested'].split(',')
|
||||||
requested_platforms.each do |platform|
|
requested_platforms.each do |platform|
|
||||||
_platform_alias, pool, count = platform.split(':')
|
platform_alias, pool, count = platform.split(':')
|
||||||
pools_filled = request_hash[pool]
|
pools_filled = redis.scard("vmpooler__#{request_id}__#{platform_alias}__#{pool}")
|
||||||
throw :request_not_ready unless pools_filled
|
throw :request_not_ready unless pools_filled.to_i == count.to_i
|
||||||
fulfilled_count = request_hash[pool].split(':').size
|
|
||||||
throw :request_not_ready unless fulfilled_count == count.to_i
|
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
@ -1457,6 +1466,7 @@ module Vmpooler
|
||||||
in_progress_requests = redis.zrange('vmpooler__provisioning__processing', 0, -1)
|
in_progress_requests = redis.zrange('vmpooler__provisioning__processing', 0, -1)
|
||||||
in_progress_requests&.each do |request_id|
|
in_progress_requests&.each do |request_id|
|
||||||
next unless vms_ready?(request_id, redis)
|
next unless vms_ready?(request_id, redis)
|
||||||
|
$logger.log('s', 'vms are ready')
|
||||||
|
|
||||||
redis.multi
|
redis.multi
|
||||||
redis.hset("vmpooler__odrequest__#{request_id}", 'status', 'ready')
|
redis.hset("vmpooler__odrequest__#{request_id}", 'status', 'ready')
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ module Vmpooler
|
||||||
# The connection_pool method is normally used only for testing
|
# The connection_pool method is normally used only for testing
|
||||||
attr_reader :connection_pool
|
attr_reader :connection_pool
|
||||||
|
|
||||||
def initialize(config, logger, metrics, name, options)
|
def initialize(config, logger, metrics, redis_connection_pool, name, options)
|
||||||
super(config, logger, metrics, redis_connection_pool, name, options)
|
super(config, logger, metrics, redis_connection_pool, name, options)
|
||||||
|
|
||||||
task_limit = global_config[:config].nil? || global_config[:config]['task_limit'].nil? ? 10 : global_config[:config]['task_limit'].to_i
|
task_limit = global_config[:config].nil? || global_config[:config]['task_limit'].nil? ? 10 : global_config[:config]['task_limit'].to_i
|
||||||
|
|
@ -39,7 +39,7 @@ module Vmpooler
|
||||||
end
|
end
|
||||||
@provider_hosts = {}
|
@provider_hosts = {}
|
||||||
@provider_hosts_lock = Mutex.new
|
@provider_hosts_lock = Mutex.new
|
||||||
@redis = redis
|
@redis = redis_connection_pool
|
||||||
end
|
end
|
||||||
|
|
||||||
# name of the provider class
|
# name of the provider class
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue