First attempt at adding connection pool to pool manager

This commit is contained in:
kirby@puppetlabs.com 2020-04-22 21:25:01 -07:00
parent 70f0482d33
commit 52bf6c4c89
5 changed files with 498 additions and 413 deletions

View file

@ -24,7 +24,7 @@ end
if torun.include? 'api' if torun.include? 'api'
api = Thread.new do api = Thread.new do
thr = Vmpooler::API.new thr = Vmpooler::API.new
redis = Vmpooler.new_redis(redis_host, redis_port, redis_password) redis = Vmpooler.redis_connection(redis_host, redis_port, redis_password)
thr.helpers.configure(config, redis, metrics) thr.helpers.configure(config, redis, metrics)
thr.helpers.execute! thr.helpers.execute!
end end
@ -36,7 +36,6 @@ if torun.include? 'manager'
Vmpooler::PoolManager.new( Vmpooler::PoolManager.new(
config, config,
Vmpooler.new_logger(logger_file), Vmpooler.new_logger(logger_file),
Vmpooler.new_redis(redis_host, redis_port, redis_password),
metrics metrics
).execute! ).execute!
end end

View file

@ -110,7 +110,7 @@ module Vmpooler
# Create an index of pool aliases # Create an index of pool aliases
parsed_config[:pool_names] = Set.new parsed_config[:pool_names] = Set.new
unless parsed_config[:pools] unless parsed_config[:pools]
redis = new_redis(parsed_config[:redis]['server'], parsed_config[:redis]['port'], parsed_config[:redis]['password']) redis = redis_connection(parsed_config[:redis]['server'], parsed_config[:redis]['port'], parsed_config[:redis]['password'])
parsed_config[:pools] = load_pools_from_redis(redis) parsed_config[:pools] = load_pools_from_redis(redis)
end end
@ -156,7 +156,7 @@ module Vmpooler
pools pools
end end
def self.new_redis(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

File diff suppressed because it is too large Load diff

View file

@ -14,10 +14,11 @@ module Vmpooler
# Provider options passed in during initialization # Provider options passed in during initialization
attr_reader :provider_options attr_reader :provider_options
def initialize(config, logger, metrics, name, options) def initialize(config, logger, metrics, redis_connection_pool, name, options)
@config = config @config = config
@logger = logger @logger = logger
@metrics = metrics @metrics = metrics
@redis = redis_connection_pool
@provider_name = name @provider_name = name
# Ensure that there is not a nil provider configuration # Ensure that there is not a nil provider configuration

View file

@ -10,7 +10,7 @@ module Vmpooler
attr_reader :connection_pool attr_reader :connection_pool
def initialize(config, logger, metrics, name, options) def initialize(config, logger, metrics, name, options)
super(config, logger, metrics, 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
# The default connection pool size is: # The default connection pool size is:
@ -39,6 +39,7 @@ module Vmpooler
end end
@provider_hosts = {} @provider_hosts = {}
@provider_hosts_lock = Mutex.new @provider_hosts_lock = Mutex.new
@redis = redis
end end
# name of the provider class # name of the provider class
@ -59,12 +60,16 @@ module Vmpooler
def destroy_vm_and_log(vm_name, vm_object, pool, data_ttl) def destroy_vm_and_log(vm_name, vm_object, pool, data_ttl)
try = 0 if try.nil? try = 0 if try.nil?
max_tries = 3 max_tries = 3
$redis.srem("vmpooler__completed__#{pool}", vm_name) @redis.with do |redis|
$redis.hdel("vmpooler__active__#{pool}", vm_name) redis.multi
$redis.hset("vmpooler__vm__#{vm_name}", 'destroy', Time.now) redis.srem("vmpooler__completed__#{pool}", vm_name)
redis.hdel("vmpooler__active__#{pool}", vm_name)
redis.hset("vmpooler__vm__#{vm_name}", 'destroy', Time.now)
# Auto-expire metadata key # Auto-expire metadata key
$redis.expire('vmpooler__vm__' + vm_name, (data_ttl * 60 * 60)) redis.expire('vmpooler__vm__' + vm_name, (data_ttl * 60 * 60))
redis.exec
end
start = Time.now start = Time.now
@ -968,9 +973,13 @@ module Vmpooler
begin begin
connection = ensured_vsphere_connection(pool_object) connection = ensured_vsphere_connection(pool_object)
vm_hash = get_vm_details(pool_name, vm_name, connection) vm_hash = get_vm_details(pool_name, vm_name, connection)
$redis.hset("vmpooler__vm__#{vm_name}", 'host', vm_hash['host_name']) @redis.with do |redis|
redis.multi
redis.hset("vmpooler__vm__#{vm_name}", 'host', vm_hash['host_name'])
migration_count = redis.scard('vmpooler__migration')
redis.exec
end
migration_limit = @config[:config]['migration_limit'] if @config[:config].key?('migration_limit') migration_limit = @config[:config]['migration_limit'] if @config[:config].key?('migration_limit')
migration_count = $redis.scard('vmpooler__migration')
if migration_enabled? @config if migration_enabled? @config
if migration_count >= migration_limit if migration_count >= migration_limit
logger.log('s', "[ ] [#{pool_name}] '#{vm_name}' is running on #{vm_hash['host_name']}. No migration will be evaluated since the migration_limit has been reached") logger.log('s', "[ ] [#{pool_name}] '#{vm_name}' is running on #{vm_hash['host_name']}. No migration will be evaluated since the migration_limit has been reached")
@ -993,15 +1002,23 @@ module Vmpooler
end end
def migrate_vm_to_new_host(pool_name, vm_name, vm_hash, connection) def migrate_vm_to_new_host(pool_name, vm_name, vm_hash, connection)
$redis.sadd('vmpooler__migration', vm_name) @redis.with do |redis|
redis.sadd('vmpooler__migration', vm_name)
end
target_host_name = select_next_host(pool_name, @provider_hosts, vm_hash['architecture']) target_host_name = select_next_host(pool_name, @provider_hosts, vm_hash['architecture'])
target_host_object = find_host_by_dnsname(connection, target_host_name) target_host_object = find_host_by_dnsname(connection, target_host_name)
finish = migrate_vm_and_record_timing(pool_name, vm_name, vm_hash, target_host_object, target_host_name) finish = migrate_vm_and_record_timing(pool_name, vm_name, vm_hash, target_host_object, target_host_name)
$redis.hset("vmpooler__vm__#{vm_name}", 'host', target_host_name) @redis.with do |redis|
$redis.hset("vmpooler__vm__#{vm_name}", 'migrated', true) redis.multi
redis.hset("vmpooler__vm__#{vm_name}", 'host', target_host_name)
redis.hset("vmpooler__vm__#{vm_name}", 'migrated', true)
redis.exec
end
logger.log('s', "[>] [#{pool_name}] '#{vm_name}' migrated from #{vm_hash['host_name']} to #{target_host_name} in #{finish} seconds") logger.log('s', "[>] [#{pool_name}] '#{vm_name}' migrated from #{vm_hash['host_name']} to #{target_host_name} in #{finish} seconds")
ensure ensure
$redis.srem('vmpooler__migration', vm_name) @redis.with do |redis|
redis.srem('vmpooler__migration', vm_name)
end
end end
def migrate_vm_and_record_timing(pool_name, vm_name, vm_hash, target_host_object, dest_host_name) def migrate_vm_and_record_timing(pool_name, vm_name, vm_hash, target_host_object, dest_host_name)
@ -1011,9 +1028,13 @@ module Vmpooler
metrics.timing("migrate.#{pool_name}", finish) metrics.timing("migrate.#{pool_name}", finish)
metrics.increment("migrate_from.#{vm_hash['host_name']}") metrics.increment("migrate_from.#{vm_hash['host_name']}")
metrics.increment("migrate_to.#{dest_host_name}") metrics.increment("migrate_to.#{dest_host_name}")
checkout_to_migration = format('%<time>.2f', time: Time.now - Time.parse($redis.hget("vmpooler__vm__#{vm_name}", 'checkout'))) @redis.with do |redis|
$redis.hset("vmpooler__vm__#{vm_name}", 'migration_time', finish) checkout_to_migration = format('%<time>.2f', time: Time.now - Time.parse(redis.hget("vmpooler__vm__#{vm_name}", 'checkout')))
$redis.hset("vmpooler__vm__#{vm_name}", 'checkout_to_migration', checkout_to_migration) redis.multi
redis.hset("vmpooler__vm__#{vm_name}", 'migration_time', finish)
redis.hset("vmpooler__vm__#{vm_name}", 'checkout_to_migration', checkout_to_migration)
redis.exec
end
finish finish
end end