Merge pull request #281 from mattkirby/pooler_109

(POOLER-109) Allow API to run independently
This commit is contained in:
mattkirby 2018-07-16 16:41:37 -07:00 committed by GitHub
commit 95d9c83479
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 229 additions and 149 deletions

View file

@ -1,5 +1,3 @@
require 'rubygems' unless defined?(Gem)
module Vmpooler
require 'date'
require 'json'
@ -14,11 +12,7 @@ module Vmpooler
require 'set'
%w[api graphite logger pool_manager statsd dummy_statsd generic_connection_pool providers].each do |lib|
begin
require "vmpooler/#{lib}"
rescue LoadError
require File.expand_path(File.join(File.dirname(__FILE__), 'vmpooler', lib))
end
require "vmpooler/#{lib}"
end
def self.config(filepath = 'vmpooler.yaml')
@ -31,36 +25,78 @@ module Vmpooler
else
# Take the name of the config file either from an ENV variable or from the filepath argument
config_file = ENV['VMPOOLER_CONFIG_FILE'] || filepath
parsed_config = YAML.load_file(config_file)
parsed_config = YAML.load_file(config_file) if File.exist? config_file
end
exit unless parsed_config
parsed_config ||= { config: {} }
# Bail out if someone attempts to start vmpooler with dummy authentication
# without enbaling debug mode.
if parsed_config[:auth]['provider'] == 'dummy'
unless ENV['VMPOOLER_DEBUG']
warning = [
'Dummy authentication should not be used outside of debug mode',
'please set environment variable VMPOOLER_DEBUG to \'true\' if you want to use dummy authentication'
]
if parsed_config.has_key? :auth
if parsed_config[:auth]['provider'] == 'dummy'
unless ENV['VMPOOLER_DEBUG']
warning = [
'Dummy authentication should not be used outside of debug mode',
'please set environment variable VMPOOLER_DEBUG to \'true\' if you want to use dummy authentication'
]
raise warning.join(";\s")
raise warning.join(";\s")
end
end
end
# Set some configuration defaults
parsed_config[:redis] ||= {}
parsed_config[:redis]['server'] ||= 'localhost'
parsed_config[:redis]['data_ttl'] ||= 168
parsed_config[:config]['task_limit'] = ENV['TASK_LIMIT'] || parsed_config[:config]['task_limit'] || 10
parsed_config[:config]['migration_limit'] = ENV['MIGRATION_LIMIT'] if ENV['MIGRATION_LIMIT']
parsed_config[:config]['vm_checktime'] = ENV['VM_CHECKTIME'] || parsed_config[:config]['vm_checktime'] || 15
parsed_config[:config]['vm_lifetime'] = ENV['VM_LIFETIME'] || parsed_config[:config]['vm_lifetime'] || 24
parsed_config[:config]['prefix'] = ENV['VM_PREFIX'] || parsed_config[:config]['prefix'] || ''
parsed_config[:config]['task_limit'] ||= 10
parsed_config[:config]['vm_checktime'] ||= 15
parsed_config[:config]['vm_lifetime'] ||= 24
parsed_config[:config]['prefix'] ||= ''
parsed_config[:config]['logfile'] = ENV['LOGFILE'] if ENV['LOGFILE']
parsed_config[:config]['site_name'] = ENV['SITE_NAME'] if ENV['SITE_NAME']
parsed_config[:config]['domain'] = ENV['DOMAIN_NAME'] if ENV['DOMAIN_NAME']
parsed_config[:config]['clone_target'] = ENV['CLONE_TARGET'] if ENV['CLONE_TARGET']
parsed_config[:config]['timeout'] = ENV['TIMEOUT'] if ENV['TIMEOUT']
parsed_config[:config]['vm_lifetime_auth'] = ENV['VM_LIFETIME_AUTH'] if ENV['VM_LIFETIME_AUTH']
parsed_config[:config]['ssh_key'] = ENV['SSH_KEY'] if ENV['SSH_KEY']
parsed_config[:config]['max_tries'] = ENV['MAX_TRIES'] if ENV['MAX_TRIES']
parsed_config[:config]['retry_factor'] = ENV['RETRY_FACTOR'] if ENV['RETRY_FACTOR']
parsed_config[:config]['create_folders'] = ENV['CREATE_FOLDERS'] if ENV['CREATE_FOLDERS']
parsed_config[:config]['create_template_delta_disks'] = ENV['CREATE_TEMPLATE_DELTA_DISKS'] if ENV['CREATE_TEMPLATE_DELTA_DISKS']
parsed_config[:config]['experimental_features'] = ENV['EXPERIMENTAL_FEATURES'] if ENV['EXPERIMENTAL_FEATURES']
parsed_config[:redis] = parsed_config[:redis] || {}
parsed_config[:redis]['server'] = ENV['REDIS_SERVER'] || parsed_config[:redis]['server'] || 'localhost'
parsed_config[:redis]['port'] = ENV['REDIS_PORT'] if ENV['REDIS_PORT']
parsed_config[:redis]['password'] = ENV['REDIS_PASSWORD'] if ENV['REDIS_PASSWORD']
parsed_config[:redis]['data_ttl'] = ENV['REDIS_DATA_TTL'] || parsed_config[:redis]['data_ttl'] || 168
parsed_config[:statsd] = parsed_config[:statsd] || {} if ENV['STATSD_SERVER']
parsed_config[:statsd]['server'] = ENV['STATSD_SERVER'] if ENV['STATSD_SERVER']
parsed_config[:statsd]['prefix'] = ENV['STATSD_PREFIX'] if ENV['STATSD_PREFIX']
parsed_config[:statsd]['port'] = ENV['STATSD_PORT'] if ENV['STATSD_PORT']
parsed_config[:graphite] = parsed_config[:graphite] || {} if ENV['GRAPHITE_SERVER']
parsed_config[:graphite]['server'] = ENV['GRAPHITE_SERVER'] if ENV['GRAPHITE_SERVER']
parsed_config[:auth] = parsed_config[:auth] || {} if ENV['AUTH_PROVIDER']
if parsed_config.has_key? :auth
parsed_config[:auth]['provider'] = ENV['AUTH_PROVIDER'] if ENV['AUTH_PROVIDER']
parsed_config[:auth][:ldap] = parsed_config[:auth][:ldap] || {} if parsed_config[:auth]['provider'] == 'ldap'
parsed_config[:auth][:ldap]['server'] = ENV['LDAP_SERVER'] if ENV['LDAP_SERVER']
parsed_config[:auth][:ldap]['port'] = ENV['LDAP_PORT'] if ENV['LDAP_PORT']
parsed_config[:auth][:ldap]['base'] = ENV['LDAP_BASE'] if ENV['LDAP_BASE']
parsed_config[:auth][:ldap]['user_object'] = ENV['LDAP_USER_OBJECT'] if ENV['LDAP_USER_OBJECT']
end
# Create an index of pool aliases
parsed_config[:pool_names] = Set.new
unless parsed_config[:pools]
redis = new_redis(parsed_config[:redis]['server'], parsed_config[:redis]['port'], parsed_config[:redis]['password'])
parsed_config[:pools] = load_pools_from_redis(redis)
end
parsed_config[:pools].each do |pool|
parsed_config[:pool_names] << pool['name']
if pool['alias']
@ -84,9 +120,23 @@ module Vmpooler
end
parsed_config[:uptime] = Time.now
parsed_config
end
def self.load_pools_from_redis(redis)
pools = []
redis.smembers('vmpooler__pools').each do |pool|
pool_hash = {}
redis.hgetall("vmpooler__pool__#{pool}").each do |k, v|
pool_hash[k] = v
end
pool_hash['alias'] = pool_hash['alias'].split(',')
pools << pool_hash
end
pools
end
def self.new_redis(host = 'localhost', port = nil, password = nil)
Redis.new(host: host, port: port, password: password)
end

View file

@ -4,8 +4,6 @@ module Vmpooler
super
end
set :environment, :production
not_found do
content_type :json
@ -42,11 +40,10 @@ module Vmpooler
use Vmpooler::API::Reroute
use Vmpooler::API::V1
def configure(config, redis, metrics, environment = :production)
def configure(config, redis, metrics)
self.settings.set :config, config
self.settings.set :redis, redis
self.settings.set :metrics, metrics
self.settings.set :environment, environment
end
def execute!

View file

@ -1,8 +1,13 @@
module Vmpooler
class Dashboard < Sinatra::Base
def config
Vmpooler.config
end
get '/dashboard/?' do
erb :dashboard, locals: {
site_name: $config[:config]['site_name'] || '<b>vmpooler</b>'
site_name: ENV['SITE_NAME'] || config[:config]['site_name'] || '<b>vmpooler</b>'
}
end
end

View file

@ -32,6 +32,31 @@ module Vmpooler
$config
end
# Place pool configuration in redis so an API instance can discover running pool configuration
def load_pools_to_redis
previously_configured_pools = $redis.smembers('vmpooler__pools')
currently_configured_pools = []
config[:pools].each do |pool|
currently_configured_pools << pool['name']
$redis.sadd('vmpooler__pools', pool['name'])
pool_keys = pool.keys
pool_keys.delete('alias')
to_set = {}
pool_keys.each do |k|
to_set[k] = pool[k]
end
to_set['alias'] = pool['alias'].join(',') if to_set.has_key?('alias')
$redis.hmset("vmpooler__pool__#{pool['name']}", to_set.to_a.flatten) unless to_set.empty?
end
previously_configured_pools.each do |pool|
unless currently_configured_pools.include? pool
$redis.srem('vmpooler__pools', pool)
$redis.del("vmpooler__pool__#{pool}")
end
end
return
end
# Check the state of a VM
def check_pending_vm(vm, pool, timeout, provider)
Thread.new do
@ -927,6 +952,9 @@ module Vmpooler
end
end
# Load running pool configuration into redis so API server can retrieve it
load_pools_to_redis
# Get pool loop settings
$config[:config] = {} if $config[:config].nil?
check_loop_delay_min = $config[:config]['check_loop_delay_min'] || CHECK_LOOP_DELAY_MIN_DEFAULT