mirror of
https://github.com/puppetlabs/vmpooler.git
synced 2026-01-26 10:08:40 -05:00
Merge pull request #298 from mattkirby/pooler_129
(POOLER-129) Allow setting weights for backends
This commit is contained in:
commit
98a84ab239
10 changed files with 57 additions and 22 deletions
|
|
@ -17,6 +17,7 @@ git logs & PR history.
|
||||||
### Added
|
### Added
|
||||||
- Re-write check\_pool in pool\_manager to improve readability
|
- Re-write check\_pool in pool\_manager to improve readability
|
||||||
- Add a docker-compose file for testing vmpooler
|
- Add a docker-compose file for testing vmpooler
|
||||||
|
- Add capability to weight backends when an alias spans multiple backends (POOLER-129)
|
||||||
|
|
||||||
# [0.2.0](https://github.com/puppetlabs/vmpooler/compare/0.1.0...0.2.0)
|
# [0.2.0](https://github.com/puppetlabs/vmpooler/compare/0.1.0...0.2.0)
|
||||||
|
|
||||||
|
|
|
||||||
1
Gemfile
1
Gemfile
|
|
@ -1,6 +1,7 @@
|
||||||
source ENV['GEM_SOURCE'] || 'https://rubygems.org'
|
source ENV['GEM_SOURCE'] || 'https://rubygems.org'
|
||||||
|
|
||||||
gem 'json', '>= 1.8'
|
gem 'json', '>= 1.8'
|
||||||
|
gem 'pickup', '~> 0.0.11'
|
||||||
gem 'puma', '~> 3.11'
|
gem 'puma', '~> 3.11'
|
||||||
gem 'rack', '~> 2.0'
|
gem 'rack', '~> 2.0'
|
||||||
gem 'rake', '~> 12.3'
|
gem 'rake', '~> 12.3'
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,16 @@
|
||||||
module Vmpooler
|
module Vmpooler
|
||||||
require 'date'
|
require 'date'
|
||||||
require 'json'
|
require 'json'
|
||||||
require 'open-uri'
|
|
||||||
require 'net/ldap'
|
require 'net/ldap'
|
||||||
|
require 'open-uri'
|
||||||
|
require 'pickup'
|
||||||
require 'rbvmomi'
|
require 'rbvmomi'
|
||||||
require 'redis'
|
require 'redis'
|
||||||
|
require 'set'
|
||||||
require 'sinatra/base'
|
require 'sinatra/base'
|
||||||
require 'time'
|
require 'time'
|
||||||
require 'timeout'
|
require 'timeout'
|
||||||
require 'yaml'
|
require 'yaml'
|
||||||
require 'set'
|
|
||||||
|
|
||||||
%w[api graphite logger pool_manager statsd dummy_statsd generic_connection_pool].each do |lib|
|
%w[api graphite logger pool_manager statsd dummy_statsd generic_connection_pool].each do |lib|
|
||||||
require "vmpooler/#{lib}"
|
require "vmpooler/#{lib}"
|
||||||
|
|
|
||||||
|
|
@ -37,15 +37,38 @@ module Vmpooler
|
||||||
end
|
end
|
||||||
|
|
||||||
def fetch_single_vm(template)
|
def fetch_single_vm(template)
|
||||||
vm = backend.spop('vmpooler__ready__' + template)
|
template_backends = [template]
|
||||||
return [vm, template] if vm
|
|
||||||
|
|
||||||
aliases = Vmpooler::API.settings.config[:alias]
|
aliases = Vmpooler::API.settings.config[:alias]
|
||||||
if aliases && aliased_template = aliases[template]
|
if aliases
|
||||||
vm = backend.spop('vmpooler__ready__' + aliased_template)
|
template_backends << aliases[template] if aliases[template]
|
||||||
return [vm, aliased_template] if vm
|
|
||||||
|
pool_index = pool_index(pools)
|
||||||
|
weighted_pools = {}
|
||||||
|
template_backends.each do |t|
|
||||||
|
next unless pool_index.key? t
|
||||||
|
index = pool_index[t]
|
||||||
|
clone_target = pools[index]['clone_target'] || config['clone_target']
|
||||||
|
next unless config.key?('backend_weight')
|
||||||
|
weight = config['backend_weight'][clone_target]
|
||||||
|
if weight
|
||||||
|
weighted_pools[t] = weight
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if weighted_pools.count == template_backends.count
|
||||||
|
pickup = Pickup.new(weighted_pools)
|
||||||
|
selection = pickup.pick
|
||||||
|
template_backends.delete(selection)
|
||||||
|
template_backends.unshift(selection)
|
||||||
|
else
|
||||||
|
template_backends = template_backends.sample(template_backends.count)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
template_backends.each do |t|
|
||||||
|
vm = backend.spop('vmpooler__ready__' + t)
|
||||||
|
return [vm, t] if vm
|
||||||
|
end
|
||||||
[nil, nil]
|
[nil, nil]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -188,8 +188,10 @@ module Vmpooler
|
||||||
|
|
||||||
# Check if the hostname has magically changed from underneath Pooler
|
# Check if the hostname has magically changed from underneath Pooler
|
||||||
vm_hash = provider.get_vm(pool['name'], vm)
|
vm_hash = provider.get_vm(pool['name'], vm)
|
||||||
|
return unless vm_hash.is_a? Hash
|
||||||
hostname = vm_hash['hostname']
|
hostname = vm_hash['hostname']
|
||||||
|
|
||||||
|
return if hostname.nil?
|
||||||
return if hostname.empty?
|
return if hostname.empty?
|
||||||
return if hostname == vm
|
return if hostname == vm
|
||||||
$redis.smove('vmpooler__ready__' + pool['name'], 'vmpooler__completed__' + pool['name'], vm)
|
$redis.smove('vmpooler__ready__' + pool['name'], 'vmpooler__completed__' + pool['name'], vm)
|
||||||
|
|
@ -870,7 +872,7 @@ module Vmpooler
|
||||||
if inventory[vm]
|
if inventory[vm]
|
||||||
begin
|
begin
|
||||||
pool_check_response[:checked_ready_vms] += 1
|
pool_check_response[:checked_ready_vms] += 1
|
||||||
check_ready_vm(vm, pool_name, pool_ttl, provider)
|
check_ready_vm(vm, pool_name, pool_ttl || 0, provider)
|
||||||
rescue => err
|
rescue => err
|
||||||
$logger.log('d', "[!] [#{pool_name}] _check_pool failed with an error while evaluating ready VMs: #{err}")
|
$logger.log('d', "[!] [#{pool_name}] _check_pool failed with an error while evaluating ready VMs: #{err}")
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -428,7 +428,7 @@ module Vmpooler
|
||||||
|
|
||||||
def vm_ready?(_pool_name, vm_name)
|
def vm_ready?(_pool_name, vm_name)
|
||||||
begin
|
begin
|
||||||
open_socket(vm_name)
|
open_socket(vm_name, global_config[:config]['domain'])
|
||||||
rescue => _err
|
rescue => _err
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -2974,9 +2974,7 @@ EOT
|
||||||
# mock response from create_inventory
|
# mock response from create_inventory
|
||||||
{vm => 1}
|
{vm => 1}
|
||||||
}
|
}
|
||||||
let(:big_lifetime) {
|
let(:big_lifetime) { 2000 }
|
||||||
2000
|
|
||||||
}
|
|
||||||
before(:each) do
|
before(:each) do
|
||||||
allow(subject).to receive(:check_ready_vm)
|
allow(subject).to receive(:check_ready_vm)
|
||||||
create_ready_vm(pool,vm,token)
|
create_ready_vm(pool,vm,token)
|
||||||
|
|
@ -2992,7 +2990,7 @@ EOT
|
||||||
expect(subject).to receive(:check_ready_vm).and_raise(RuntimeError,'MockError')
|
expect(subject).to receive(:check_ready_vm).and_raise(RuntimeError,'MockError')
|
||||||
expect(logger).to receive(:log).with('d', "[!] [#{pool}] _check_pool failed with an error while evaluating ready VMs: MockError")
|
expect(logger).to receive(:log).with('d', "[!] [#{pool}] _check_pool failed with an error while evaluating ready VMs: MockError")
|
||||||
|
|
||||||
subject.check_ready_pool_vms(pool, provider, pool_check_response, inventory)
|
subject.check_ready_pool_vms(pool, provider, pool_check_response, inventory, big_lifetime)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should use the pool TTL if set' do
|
it 'should use the pool TTL if set' do
|
||||||
|
|
@ -3511,12 +3509,8 @@ EOT
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'captures #create_inventory errors correctly' do
|
it 'captures #create_inventory errors correctly' do
|
||||||
allow(subject).to receive(:create_inventory).and_raise(
|
allow(subject).to receive(:create_inventory).and_raise(RuntimeError,'Mock Error')
|
||||||
RuntimeError,'Mock Error'
|
|
||||||
)
|
|
||||||
expect {
|
|
||||||
subject._check_pool(pool_object, provider)
|
subject._check_pool(pool_object, provider)
|
||||||
}.to_not raise_error(RuntimeError, /Mock Error/)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should return early if an error occurs' do
|
it 'should return early if an error occurs' do
|
||||||
|
|
|
||||||
|
|
@ -925,9 +925,10 @@ EOT
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#vm_ready?' do
|
describe '#vm_ready?' do
|
||||||
|
let(:domain) { nil }
|
||||||
context 'When a VM is ready' do
|
context 'When a VM is ready' do
|
||||||
before(:each) do
|
before(:each) do
|
||||||
expect(subject).to receive(:open_socket).with(vmname)
|
expect(subject).to receive(:open_socket).with(vmname, domain)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should return true' do
|
it 'should return true' do
|
||||||
|
|
@ -939,7 +940,7 @@ EOT
|
||||||
# TODO not sure how to handle a VM that is passed in but
|
# TODO not sure how to handle a VM that is passed in but
|
||||||
# not located in the pool. Is that ready or not?
|
# not located in the pool. Is that ready or not?
|
||||||
before(:each) do
|
before(:each) do
|
||||||
expect(subject).to receive(:open_socket).with(vmname)
|
expect(subject).to receive(:open_socket).with(vmname, domain)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should return true' do
|
it 'should return true' do
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ Gem::Specification.new do |s|
|
||||||
s.bindir = 'bin'
|
s.bindir = 'bin'
|
||||||
s.executables = 'vmpooler'
|
s.executables = 'vmpooler'
|
||||||
s.require_paths = ["lib"]
|
s.require_paths = ["lib"]
|
||||||
|
s.add_dependency 'pickup', '~> 0.0.11'
|
||||||
s.add_dependency 'puma', '~> 3.11'
|
s.add_dependency 'puma', '~> 3.11'
|
||||||
s.add_dependency 'rack', '~> 2.0'
|
s.add_dependency 'rack', '~> 2.0'
|
||||||
s.add_dependency 'rake', '~> 12.3'
|
s.add_dependency 'rake', '~> 12.3'
|
||||||
|
|
|
||||||
|
|
@ -477,6 +477,14 @@
|
||||||
# Expects a boolean value
|
# Expects a boolean value
|
||||||
# (optional; default: false)
|
# (optional; default: false)
|
||||||
#
|
#
|
||||||
|
# - backend_weight
|
||||||
|
# A hash of clone_target values with weights assigned to allow selecting VMs by alias with selection probability
|
||||||
|
# This setting is only used when there is a pool title and matching alias that both have values set in backend weight.
|
||||||
|
# When both conditions are met then the next VM is selected by probability using backend weight. When weight is not set
|
||||||
|
# in this configuration then distribution of load is random.
|
||||||
|
# Expects a hash value
|
||||||
|
# (optional)
|
||||||
|
#
|
||||||
# Example:
|
# Example:
|
||||||
|
|
||||||
:config:
|
:config:
|
||||||
|
|
@ -493,6 +501,9 @@
|
||||||
domain: 'example.com'
|
domain: 'example.com'
|
||||||
prefix: 'poolvm-'
|
prefix: 'poolvm-'
|
||||||
experimental_features: true
|
experimental_features: true
|
||||||
|
backend_weight:
|
||||||
|
'backend1': 60
|
||||||
|
'backend2': 40
|
||||||
|
|
||||||
# :pools:
|
# :pools:
|
||||||
#
|
#
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue